diff options
Diffstat (limited to 'calendar/gui/print.c')
-rw-r--r-- | calendar/gui/print.c | 2646 |
1 files changed, 0 insertions, 2646 deletions
diff --git a/calendar/gui/print.c b/calendar/gui/print.c deleted file mode 100644 index b353fc24fb..0000000000 --- a/calendar/gui/print.c +++ /dev/null @@ -1,2646 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Print support - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <math.h> -#include <time.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-paper.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomeui/gnome-paper-selector.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnomeprint/gnome-print.h> -#include <libgnomeprint/gnome-print-copies.h> -#include <libgnomeprint/gnome-print-master.h> -#include <libgnomeprint/gnome-print-master-preview.h> -#include <libgnomeprint/gnome-print-preview.h> -#include <libgnomeprint/gnome-printer-dialog.h> -#include <e-util/e-dialog-widgets.h> -#include <e-util/e-time-utils.h> -#include <gal/util/e-unicode-i18n.h> -#include <gal/widgets/e-unicode.h> -#include <cal-util/timeutil.h> -#include "calendar-commands.h" -#include "calendar-config.h" -#include "e-day-view.h" -#include "e-day-view-layout.h" -#include "e-week-view.h" -#include "e-week-view-layout.h" -#include "gnome-cal.h" -#include "print.h" - - - -/* - * Note that most dimensions are in points (1/72 of an inch) since that is - * what gnome-print uses. - */ - -/* The font to use */ -#define DEFAULT_FONT "Times" - -/* The font size to use for normal text. */ -#define DAY_NORMAL_FONT_SIZE 12 -#define WEEK_NORMAL_FONT_SIZE 12 -#define MONTH_NORMAL_FONT_SIZE 8 - -/* The height of the header bar across the top of the Day, Week & Month views, - which contains the dates shown and the 2 small calendar months. */ -#define HEADER_HEIGHT 80 - -/* The width of the small calendar months, the space from the right edge of - the header rectangle, and the space between the months. */ -#define SMALL_MONTH_WIDTH 80 -#define SMALL_MONTH_PAD 4 -#define SMALL_MONTH_SPACING 12 - -/* The minimum number of rows we leave space for for the long events in the - day view. */ -#define DAY_VIEW_MIN_ROWS_IN_TOP_DISPLAY 2 - -/* The row height for long events in the day view. */ -#define DAY_VIEW_ROW_HEIGHT 20 - -/* The minutes per row in the day view printout. */ -#define DAY_VIEW_MINS_PER_ROW 30 - -#define DAY_VIEW_ROWS ((60 / DAY_VIEW_MINS_PER_ROW) * 24) - -/* The width of the column with all the times in it. */ -#define DAY_VIEW_TIME_COLUMN_WIDTH 36 - -/* The space on the right of each event. */ -#define DAY_VIEW_EVENT_X_PAD 8 - -/* Allowance for small errors in floating point comparisons. */ -#define EPSILON 0.01 - -/* The weird month of September 1752, where 3 Sep through 13 Sep were - eliminated due to the Gregorian reformation. */ -static const int sept_1752[42] = { - 0, 0, 1, 2, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 -}; -#define SEPT_1752_START 2 /* Start day within month */ -#define SEPT_1752_END 20 /* End day within month */ - - -struct pdinfo -{ - gint days_shown; - time_t day_starts[E_DAY_VIEW_MAX_DAYS + 1]; - - GArray *long_events; - GArray *events[E_DAY_VIEW_MAX_DAYS]; - - gint start_hour; - gint end_hour; - gint start_minute_offset; - gint end_minute_offset; - gint rows; - gint mins_per_row; - gint8 cols_per_row[DAY_VIEW_ROWS]; - gboolean use_24_hour_format; -}; - -struct psinfo -{ - gint days_shown; - time_t day_starts[E_WEEK_VIEW_MAX_WEEKS * 7 + 1]; - - GArray *events; - - int rows_per_cell; - int rows_per_compressed_cell; - int display_start_weekday; - gboolean multi_week_view; - int weeks_shown; - int month; - gboolean compress_weekend; - gboolean use_24_hour_format; - double row_height; - double header_row_height; -}; - -struct ptinfo -{ - GList *todos; -}; - -struct einfo -{ - char *text; - time_t start; - time_t end; - int count; -}; - -static const GnomePaper *paper_info = NULL; - - -/* Convenience function to help the transition to timezone functions. - It returns the current timezone. */ -static icaltimezone* -get_timezone (void) -{ - char *location = calendar_config_get_timezone (); - return icaltimezone_get_builtin_timezone (location); -} - - -/* Convenience function to help the transition to timezone functions. - It converts a time_t to a struct tm. */ -static struct tm* -convert_timet_to_struct_tm (time_t time, icaltimezone *zone) -{ - static struct tm my_tm; - struct icaltimetype tt; - - /* Convert it to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Fill in the struct tm. */ - my_tm.tm_year = tt.year - 1900; - my_tm.tm_mon = tt.month - 1; - my_tm.tm_mday = tt.day; - my_tm.tm_hour = tt.hour; - my_tm.tm_min = tt.minute; - my_tm.tm_sec = tt.second; - my_tm.tm_isdst = tt.is_daylight; - - my_tm.tm_wday = time_day_of_week (tt.day, tt.month - 1, tt.year); - - return &my_tm; -} - - -/* Fills the 42-element days array with the day numbers for the specified month. Slots outside the - * bounds of the month are filled with zeros. The starting and ending indexes of the days are - * returned in the start and end arguments. - */ -static void -build_month (int month, int year, int *days, int *start, int *end) -{ - int i; - int d_month, d_week, week_start_day; - - /* Note that months are zero-based, so September is month 8 */ - - if ((year == 1752) && (month == 8)) { - memcpy (days, sept_1752, 42 * sizeof (int)); - - if (start) - *start = SEPT_1752_START; - - if (end) - *end = SEPT_1752_END; - - return; - } - - for (i = 0; i < 42; i++) - days[i] = 0; - - d_month = time_days_in_month (year, month); - /* Get the start weekday in the month, 0=Sun to 6=Sat. */ - d_week = time_day_of_week (1, month, year); - - /* Get the configuration setting specifying which weekday we put on - the left column, 0=Sun to 6=Sat. */ - week_start_day = calendar_config_get_week_start_day (); - - /* Figure out which square we want to put the 1 in. */ - d_week = (d_week + 7 - week_start_day) % 7; - - for (i = 0; i < d_month; i++) - days[d_week + i] = i + 1; - - if (start) - *start = d_week; - - if (end) - *end = d_week + d_month - 1; -} - -static GnomeFont * -get_font_for_size (double h, GnomeFontWeight weight, gboolean italic) -{ - GnomeFontFace *face; - GnomeFont *font; - double asc, desc, size; - - face = gnome_font_unsized_closest (DEFAULT_FONT, weight, italic); - asc = gnome_font_face_get_ascender (face); - desc = gnome_font_face_get_descender (face); - size = h * 1000 / (asc + desc); - g_print ("Print Info: %f, %f, %f\n", asc, desc, size); - - font = gnome_font_new_closest (DEFAULT_FONT, weight, italic, size); - - gtk_object_unref (GTK_OBJECT (face)); - - return font; -} - -enum align_box { - ALIGN_LEFT=1, - ALIGN_RIGHT, - ALIGN_CENTER, - ALIGN_BORDER= 1<<8 -}; - - -/* Prints a rectangle, with or without a border, filled or outline, and - possibly with triangular arrows at one or both horizontal edges. - width = width of border, -ve means no border. - fillcolor = shade of fill, -ve means no fill. - left_triangle_width, right_triangle_width = width from edge of rectangle to - point of triangle, or -ve for no triangle. */ -static void -print_border_with_triangles (GnomePrintContext *pc, - double l, double r, double t, double b, - double width, double fillcolor, - double left_triangle_width, - double right_triangle_width) -{ - gnome_print_gsave (pc); - - /* Fill in the interior of the rectangle, if desired. */ - if (fillcolor >= -EPSILON) { - gnome_print_moveto (pc, l, t); - if (left_triangle_width > 0.0) - gnome_print_lineto (pc, l - left_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, l, b); - gnome_print_lineto (pc, r, b); - if (right_triangle_width > 0.0) - gnome_print_lineto (pc, r + right_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, r, t); - gnome_print_closepath (pc); - gnome_print_setrgbcolor (pc, fillcolor, fillcolor, - fillcolor); - gnome_print_fill (pc); - } - - /* Draw the outline, if desired. */ - if (width >= -EPSILON) { - gnome_print_moveto (pc, l, t); - if (left_triangle_width > 0.0) - gnome_print_lineto (pc, l - left_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, l, b); - gnome_print_lineto (pc, r, b); - if (right_triangle_width > 0.0) - gnome_print_lineto (pc, r + right_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, r, t); - gnome_print_closepath (pc); - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, width); - gnome_print_stroke (pc); - } - - gnome_print_grestore (pc); -} - - -/* Prints a rectangle, with or without a border, and filled or outline. - width = width of border, -ve means no border. - fillcolor = shade of fill, -ve means no fill. */ -static void -print_border (GnomePrintContext *pc, - double l, double r, double t, double b, - double width, double fillcolor) -{ - print_border_with_triangles (pc, l, r, t, b, width, fillcolor, - -1.0, -1.0); -} - - -/* Prints 1 line of aligned text in a box. It is centered vertically, and - the horizontal alignment can be either ALIGN_LEFT, ALIGN_RIGHT, or - ALIGN_CENTER. */ -static void -print_text(GnomePrintContext *pc, GnomeFont *font, const char *text, - enum align_box align, double l, double r, double t, double b) -{ - double w, x, y; - - gnome_print_gsave (pc); - - w = gnome_font_get_width_utf8 (font, text); - - switch (align & 3) { - case ALIGN_LEFT: - default: - x = l; - break; - case ALIGN_RIGHT: - x = r - w; - break; - case ALIGN_CENTER: - x = l + ((r - l) - w) / 2; - break; - } - - /* Make sure we don't go off the left edge. */ - x = MAX (l, x); - - /* Now calculate the baseline. */ - y = t - gnome_font_get_ascender (font); - - /* Set a clipping rectangle. */ - gnome_print_moveto (pc, l, t); - gnome_print_lineto (pc, r, t); - gnome_print_lineto (pc, r, b); - gnome_print_lineto (pc, l, b); - gnome_print_closepath (pc); - gnome_print_clip (pc); - - gnome_print_newpath (pc); - gnome_print_moveto (pc, x, y); - gnome_print_setfont (pc, font); - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_show (pc, text); - - gnome_print_grestore (pc); -} - -/* gets/frees the font for you, as a book font */ -static void -print_text_size(GnomePrintContext *pc, const char *text, - enum align_box align, double l, double r, double t, double b) -{ - GnomeFont *font; - - font = get_font_for_size (t - b, GNOME_FONT_BOOK, FALSE); - print_text(pc, font, text, align, l, r, t, b); - gtk_object_unref (GTK_OBJECT (font)); -} - -/* gets/frees the font for you, as a bold font */ -static void -print_text_size_bold(GnomePrintContext *pc, const char *text, - enum align_box align, double l, double r, double t, double b) -{ - GnomeFont *font; - - font = get_font_for_size (t - b, GNOME_FONT_BOLD, FALSE); - print_text(pc, font, text, align, l, r, t, b); - gtk_object_unref (GTK_OBJECT (font)); -} - -static void -titled_box (GnomePrintContext *pc, const char *text, GnomeFont *font, - enum align_box align, double *l, double *r, double *t, double *b, - double linewidth) -{ - double size; - - size = gnome_font_get_size (font); - - if (align & ALIGN_BORDER) { - print_border (pc, *l, *r, *t, *t - size * 1.4, - linewidth, 0.9); - print_border (pc, *l, *r, *t - size * 1.4, *b, - linewidth, -1.0); - - *l += 2; - *r -= 2; - *b += 2; - } - - print_text (pc, font, text, align, *l, *r, *t, *t - size * 1.4); - *t -= size * 1.4; -} - -enum datefmt { - DATE_MONTH = 1 << 0, - DATE_DAY = 1 << 1, - DATE_DAYNAME = 1 << 2, - DATE_YEAR = 1 << 3 -}; - -static char *days[] = { - N_("1st"), N_("2nd"), N_("3rd"), N_("4th"), N_("5th"), - N_("6th"), N_("7th"), N_("8th"), N_("9th"), N_("10th"), - N_("11th"), N_("12th"), N_("13th"), N_("14th"), N_("15th"), - N_("16th"), N_("17th"), N_("18th"), N_("19th"), N_("20th"), - N_("21st"), N_("22nd"), N_("23rd"), N_("24th"), N_("25th"), - N_("26th"), N_("27th"), N_("28th"), N_("29th"), N_("30th"), - N_("31st") -}; - -/* - format the date 'nicely' and consistently for various headers -*/ -static char * -format_date(time_t time, int flags, char *buffer, int bufflen) -{ - icaltimezone *zone = get_timezone (); - char fmt[64]; - struct tm tm; - char *utf_str; - - tm = *convert_timet_to_struct_tm (time, zone); - - fmt[0] = 0; - if (flags & DATE_DAYNAME) { - strcat(fmt, "%A"); - } - if (flags & DATE_DAY) { - if (flags & DATE_DAYNAME) - strcat(fmt, " "); - strcat(fmt, gettext(days[tm.tm_mday-1])); - } - if (flags & DATE_MONTH) { - if (flags & (DATE_DAY|DATE_DAYNAME)) - strcat(fmt, " "); - strcat(fmt, "%B"); - if ((flags & (DATE_DAY|DATE_YEAR)) == (DATE_DAY|DATE_YEAR)) - strcat(fmt, ","); - } - if (flags & DATE_YEAR) { - if (flags & (DATE_DAY|DATE_DAYNAME|DATE_MONTH)) - strcat(fmt, " "); - strcat(fmt, "%Y"); - } - strftime(buffer, bufflen, fmt, &tm); - utf_str = e_utf8_from_locale_string (buffer); - strncpy (buffer, utf_str, bufflen - 1); - buffer[bufflen - 1] = '\0'; - g_free (utf_str); - return buffer; -} - - -/* - print out the month small, embolden any days with events. -*/ -static void -print_month_small (GnomePrintContext *pc, GnomeCalendar *gcal, time_t month, - double left, double right, double top, double bottom, - int titleflags, time_t greystart, time_t greyend, - int bordertitle) -{ - icaltimezone *zone = get_timezone (); - CalClient *client; - GnomeFont *font, *font_bold, *font_normal; - time_t now, next; - int x, y; - int days[42]; - int day, weekday, week_start_day; - char buf[100]; - struct tm tm; - double font_size, max_font_size; - double header_size, col_width, row_height, text_xpad, w; - double cell_top, cell_bottom, cell_left, cell_right, text_right; - char *daynames[] = { N_("Su"), N_("Mo"), N_("Tu"), N_("We"), - N_("Th"), N_("Fr"), N_("Sa") }; - - /* Print the title, e.g. 'June 2001', in the top 16% of the area. */ - format_date (month, titleflags, buf, 100); - header_size = (top - bottom) * 0.16; - font = get_font_for_size (header_size, GNOME_FONT_BOLD, FALSE); - if (bordertitle) { - print_border (pc, left, right, top, top - header_size, - 1.0, 0.9); - } - print_text (pc, font, buf, ALIGN_CENTER, left, right, - top, top - header_size); - gtk_object_unref (GTK_OBJECT (font)); - - top -= header_size; - - client = gnome_calendar_get_cal_client (gcal); - - col_width = (right - left) / 7; - - /* The top row with the day abbreviations gets an extra bit of - vertical space around it. */ - row_height = (top - bottom) / 7.4; - - /* First we need to calculate a reasonable font size. We start with a - rough guess of just under the height of each row. */ - font_size = row_height; - - /* Check that it isn't going to be too wide. The characters are about - twice as high as they are wide, but we need to fit two characters - into each cell, so we don't want to go over col_width. */ - max_font_size = col_width * 0.65; - - font_size = row_height; - - /* get month days */ - tm = *convert_timet_to_struct_tm (month, zone); - build_month (tm.tm_mon, tm.tm_year + 1900, days, 0, 0); - - font_normal = get_font_for_size (font_size, GNOME_FONT_BOOK, FALSE); - font_bold = get_font_for_size (font_size, GNOME_FONT_BOLD, FALSE); - - /* Get a reasonable estimate of the largest number we will need, - and use it to calculate the offset from the right edge of the - cell that we should put the numbers. */ - w = gnome_font_get_width_utf8 (font_bold, "23"); - text_xpad = (col_width - w) / 2; - - gnome_print_setrgbcolor (pc, 0, 0, 0); - - /* Print the abbreviated day names across the top in bold. */ - week_start_day = calendar_config_get_week_start_day (); - weekday = week_start_day; - for (x = 0; x < 7; x++) { - print_text (pc, font_bold, U_(daynames[weekday]), ALIGN_CENTER, - left + x * col_width, left + (x + 1) * col_width, - top, top - row_height * 1.4); - weekday = (weekday + 1) % 7; - } - - top -= row_height * 1.4; - - now = time_month_begin_with_zone (month, zone); - for (y = 0; y < 6; y++) { - - cell_top = top - y * row_height; - cell_bottom = cell_top - row_height; - - for (x = 0; x < 7; x++) { - - cell_left = left + x * col_width; - /* We add a 0.05 to make sure the cells meet up with - each other. Otherwise you sometimes get lines - between them which looks bad. Maybe I'm not using - coords in the way gnome-print expects. */ - cell_right = cell_left + col_width + 0.05; - text_right = cell_right - text_xpad; - - day = days[y * 7 + x]; - if (day != 0) { - GList *uids; - - sprintf (buf, "%d", day); - - /* this is a slow messy way to do this ... but easy ... */ - uids = cal_client_get_objects_in_range (client, - CALOBJ_TYPE_EVENT, - now, time_day_end_with_zone (now, zone)); - font = uids ? font_bold : font_normal; - cal_obj_uid_list_free (uids); - - next = time_add_day_with_zone (now, 1, zone); - if ((now >= greystart && now < greyend) - || (greystart >= now && greystart < next)) { - print_border (pc, - cell_left, cell_right, - cell_top, cell_bottom, - -1.0, 0.75); - } - print_text (pc, font, buf, ALIGN_RIGHT, - cell_left, text_right, - cell_top, cell_bottom); - - now = next; - } - } - } - gtk_object_unref (GTK_OBJECT (font_normal)); - gtk_object_unref (GTK_OBJECT (font_bold)); -} - - - -/* wraps text into the print context, not taking up more than its allowed space */ -static double -bound_text(GnomePrintContext *pc, GnomeFont *font, const char *text, - double left, double right, double top, double bottom, double indent) -{ - double maxwidth = right-left; - double width; - const char *p; - char *wordstart; - int c; - char *outbuffer, *o, *outbuffendmarker; - int outbufflen; - int dump=0; - int first=1; - - g_return_val_if_fail(text!=NULL, top); - - if (top<bottom) { - /* too much to fit in appointment printout */ - return top; - } - - outbufflen = 1024; - outbuffer = g_malloc(outbufflen); - outbuffendmarker = outbuffer+outbufflen-2; - - top -= gnome_font_get_size (font); - gnome_print_setfont (pc, font); - - width=0; - p = text; - wordstart = outbuffer; - o = outbuffer; - while ((c=*p)) { - if (c=='\n') { - wordstart=o; - dump=1; - } else { - /* grow output buffer if required */ - if (o>=outbuffendmarker) { - char *newbuf; - outbufflen*=2; - newbuf = g_realloc(outbuffer, outbufflen); - o = newbuf+(o-outbuffer); - wordstart = newbuf+(o-outbuffer); - outbuffer = newbuf; - outbuffendmarker = outbuffer+outbufflen-2; - } - *o++=c; - if (c==' ') - wordstart = o; - width+=gnome_font_get_glyph_width(font, gnome_font_lookup_default (font, c)); - if (width>maxwidth) - dump=1; - else - dump=0; - } - if (dump) { - if (wordstart==outbuffer) - wordstart=o; - c=*wordstart; - *wordstart=0; - gnome_print_moveto(pc, left, top); - gnome_print_show(pc, outbuffer); - *wordstart=c; - memcpy(outbuffer, wordstart, o-wordstart); - width = gnome_font_get_width_utf8_sized(font, outbuffer, o-wordstart); - o=outbuffer+(o-wordstart); - wordstart = outbuffer; - top -= gnome_font_get_size (font); - if (top<bottom) { - /* too much to fit, drop the rest */ - g_free(outbuffer); - return top; - } - if (first) { - left += indent; - maxwidth -= indent; - first=0; - } - } - p++; - } - if (dump==0) { - *o=0; - gnome_print_moveto(pc, left, top); - gnome_print_show(pc, outbuffer); - top -= gnome_font_get_size (font); - } - g_free(outbuffer); - return top; -} - - -/* Draw the borders, lines, and times down the left of the day view. */ -static void -print_day_background (GnomePrintContext *pc, GnomeCalendar *gcal, - time_t whence, struct pdinfo *pdi, - double left, double right, double top, double bottom) -{ - GnomeFont *font_hour, *font_minute; - double yinc, y; - double width = DAY_VIEW_TIME_COLUMN_WIDTH; - double font_size, max_font_size, hour_font_size, minute_font_size; - char buf[20]; - const char *minute; - gboolean use_24_hour; - int i, hour, row; - - /* Fill the time column in light-gray. */ - print_border (pc, left, left + width, top, bottom, -1.0, 0.9); - - /* Draw the border around the entire view. */ - gnome_print_setrgbcolor (pc, 0, 0, 0); - print_border (pc, left, right, top, bottom, 1.0, -1.0); - - /* Draw the vertical line on the right of the time column. */ - gnome_print_setlinewidth (pc, 0.0); - gnome_print_moveto (pc, left + width, bottom); - gnome_print_lineto (pc, left + width, top); - gnome_print_stroke (pc); - - /* Calculate the row height. */ - yinc = (top - bottom) / (pdi->end_hour - pdi->start_hour); - - /* Get the 2 fonts we need. */ - font_size = yinc * 0.6; - max_font_size = width * 0.5; - hour_font_size = MIN (font_size, max_font_size); - font_hour = get_font_for_size (hour_font_size, GNOME_FONT_BOLD, FALSE); - - font_size = yinc * 0.33; - max_font_size = width * 0.25; - minute_font_size = MIN (font_size, max_font_size); - font_minute = get_font_for_size (minute_font_size, GNOME_FONT_BOLD, FALSE); - - use_24_hour = calendar_config_get_24_hour_format (); - - row = 0; - for (i = pdi->start_hour; i < pdi->end_hour; i++) { - y = top - yinc * (row + 1); - gnome_print_setrgbcolor (pc, 0, 0, 0); - - if (use_24_hour) { - hour = i; - minute = "00"; - } else { - if (i < 12) - minute = U_("am"); - else - minute = U_("pm"); - - hour = i % 12; - if (hour == 0) - hour = 12; - } - - /* the hour label/minute */ - sprintf (buf, "%d", hour); - print_text (pc, font_hour, buf, ALIGN_RIGHT, - left, left + width * 0.58, - y + yinc - 4, y + yinc - 4 - hour_font_size); - print_text (pc, font_minute, minute, ALIGN_RIGHT, - left, left + width - 3, - y + yinc - 3, y + yinc - 3 - minute_font_size); - - /* Draw the horizontal line between hours, across the entire - width of the day view. */ - gnome_print_moveto (pc, left, y); - gnome_print_lineto (pc, right, y); - gnome_print_stroke (pc); - - /* Draw the horizontal line for the 1/2-hours, across the - entire width except for part of the time column. */ - gnome_print_moveto (pc, left + width * 0.6, y + yinc / 2); - gnome_print_lineto (pc, right, y + yinc / 2); - gnome_print_stroke (pc); - - row++; - } - - gtk_object_unref (GTK_OBJECT (font_hour)); - gtk_object_unref (GTK_OBJECT (font_minute)); -} - - -/* This adds one event to the view, adding it to the appropriate array. */ -static gint -print_day_add_event (CalComponent *comp, - time_t start, - time_t end, - gint days_shown, - time_t *day_starts, - GArray *long_events, - GArray **events) - -{ - icaltimezone *zone = get_timezone (); - EDayViewEvent event; - gint day, offset; - struct icaltimetype start_tt, end_tt; - -#if 0 - g_print ("Day view lower: %s", ctime (&day_starts[0])); - g_print ("Day view upper: %s", ctime (&day_starts[days_shown])); - g_print ("Event start: %s", ctime (&start)); - g_print ("Event end : %s\n", ctime (&end)); -#endif - - /* Check that the event times are valid. */ - g_return_val_if_fail (start <= end, -1); - g_return_val_if_fail (start < day_starts[days_shown], -1); - g_return_val_if_fail (end > day_starts[0], -1); - - start_tt = icaltime_from_timet_with_zone (start, FALSE, zone); - end_tt = icaltime_from_timet_with_zone (end, FALSE, zone); - - event.comp = comp; - gtk_object_ref (GTK_OBJECT (comp)); - event.start = start; - event.end = end; - event.canvas_item = NULL; - - /* Calculate the start & end minute, relative to the top of the - display. */ - /*offset = day_view->first_hour_shown * 60 - + day_view->first_minute_shown;*/ - offset = 0; - event.start_minute = start_tt.hour * 60 + start_tt.minute - offset; - event.end_minute = end_tt.hour * 60 + end_tt.minute - offset; - - event.start_row_or_col = 0; - event.num_columns = 0; - - /* Find out which array to add the event to. */ - for (day = 0; day < days_shown; day++) { - if (start >= day_starts[day] && end <= day_starts[day + 1]) { - - /* Special case for when the appointment ends at - midnight, i.e. the start of the next day. */ - if (end == day_starts[day + 1]) { - - /* If the event last the entire day, then we - skip it here so it gets added to the top - canvas. */ - if (start == day_starts[day]) - break; - - event.end_minute = 24 * 60; - } - - g_array_append_val (events[day], event); - return day; - } - } - - /* The event wasn't within one day so it must be a long event, - i.e. shown in the top canvas. */ - g_array_append_val (long_events, event); - return E_DAY_VIEW_LONG_EVENT; -} - - -static gboolean -print_day_details_cb (CalComponent *comp, time_t istart, time_t iend, - gpointer data) -{ - struct pdinfo *pdi = (struct pdinfo *)data; - - print_day_add_event (comp, istart, iend, - pdi->days_shown, pdi->day_starts, - pdi->long_events, pdi->events); - - return TRUE; -} - - -static void -free_event_array (GArray *array) -{ - EDayViewEvent *event; - gint event_num; - - for (event_num = 0; event_num < array->len; event_num++) { - event = &g_array_index (array, EDayViewEvent, event_num); - if (event->canvas_item) - gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - gtk_object_unref (GTK_OBJECT (event->comp)); - } - - g_array_set_size (array, 0); -} - - -static void -print_day_long_event (GnomePrintContext *pc, GnomeFont *font, - double left, double right, double top, double bottom, - double row_height, EDayViewEvent *event, - struct pdinfo *pdi) -{ - CalComponentText summary; - double x1, x2, y1, y2; - double left_triangle_width = -1.0, right_triangle_width = -1.0; - char *text; - char buffer[32]; - struct tm date_tm; - - /* If the event starts before the first day being printed, draw a - triangle. (Note that I am assuming we are just showing 1 day at - the moment.) */ - if (event->start < pdi->day_starts[0]) - left_triangle_width = 4; - - /* If the event ends after the last day being printed, draw a - triangle. */ - if (event->end > pdi->day_starts[1]) - right_triangle_width = 4; - - x1 = left + 10; - x2 = right - 10; - y1 = top - event->start_row_or_col * row_height - 4; - y2 = y1 - row_height + 4; - print_border_with_triangles (pc, x1, x2, y1, y2, 0.5, 0.95, - left_triangle_width, - right_triangle_width); - - /* If the event starts after the first day being printed, we need to - print the start time. */ - if (event->start > pdi->day_starts[0]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x1 += 4; - print_text (pc, font, buffer, ALIGN_LEFT, x1, x2, y1, y2); - x1 += gnome_font_get_width_utf8 (font, buffer); - } - - /* If the event ends before the end of the last day being printed, - we need to print the end time. */ - if (event->end < pdi->day_starts[1]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->end_minute / 60; - date_tm.tm_min = event->end_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x2 -= 4; - print_text (pc, font, buffer, ALIGN_RIGHT, x1, x2, y1, y2); - x2 -= gnome_font_get_width_utf8 (font, buffer); - } - - /* Print the text. */ - cal_component_get_summary (event->comp, &summary); - text = summary.value ? (char*) summary.value : ""; - - x1 += 4; - x2 -= 4; - print_text (pc, font, text, ALIGN_CENTER, x1, x2, y1, y2); -} - - -static void -print_day_event (GnomePrintContext *pc, GnomeFont *font, - double left, double right, double top, double bottom, - EDayViewEvent *event, struct pdinfo *pdi) -{ - CalComponentText summary; - double x1, x2, y1, y2, col_width, row_height; - int start_offset, end_offset, start_row, end_row; - char *text, start_buffer[32], end_buffer[32]; - gboolean display_times = FALSE, free_text = FALSE; - struct tm date_tm; - - if ((event->start_minute >= pdi->end_minute_offset) - || (event->end_minute <= pdi->start_minute_offset)) - return; - - start_offset = event->start_minute - pdi->start_minute_offset; - end_offset = event->end_minute - pdi->start_minute_offset; - - start_row = start_offset / pdi->mins_per_row; - start_row = MAX (0, start_row); - end_row = (end_offset - 1) / pdi->mins_per_row; - end_row = MIN (pdi->rows - 1, end_row); - col_width = (right - left) / pdi->cols_per_row[event->start_minute / pdi->mins_per_row]; - - if (start_offset != start_row * pdi->mins_per_row - || end_offset != (end_row + 1) * pdi->mins_per_row) - display_times = TRUE; - - x1 = left + event->start_row_or_col * col_width; - x2 = x1 + event->num_columns * col_width - DAY_VIEW_EVENT_X_PAD; - - row_height = (top - bottom) / pdi->rows; - y1 = top - start_row * row_height; - y2 = top - (end_row + 1) * row_height; - -#if 0 - g_print ("Event: %g,%g %g,%g\n row_height: %g start_row: %i top: %g rows: %i\n", - x1, y1, x2, y2, row_height, start_row, top, pdi->rows); -#endif - - print_border (pc, x1, x2, y1, y2, 1.0, 0.95); - - cal_component_get_summary (event->comp, &summary); - text = summary.value ? (char*) summary.value : ""; - - - if (display_times) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - start_buffer, sizeof (start_buffer)); - - date_tm.tm_hour = event->end_minute / 60; - date_tm.tm_min = event->end_minute % 60; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - end_buffer, sizeof (end_buffer)); - - text = g_strdup_printf ("%s - %s %s ", start_buffer, - end_buffer, text); - - free_text = TRUE; - } - - bound_text (pc, font, text, x1 + 2, x2 - 2, y1, y2, 0); - - if (free_text) - g_free (text); -} - - -static void -print_day_details (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - CalClient *client; - EDayViewEvent *event; - GnomeFont *font; - time_t start, end; - struct pdinfo pdi; - gint rows_in_top_display, i; - double font_size, max_font_size; - - start = time_day_begin_with_zone (whence, zone); - end = time_day_end_with_zone (start, zone); - - pdi.days_shown = 1; - pdi.day_starts[0] = start; - pdi.day_starts[1] = end; - pdi.long_events = g_array_new (FALSE, FALSE, sizeof (EDayViewEvent)); - pdi.events[0] = g_array_new (FALSE, FALSE, sizeof (EDayViewEvent)); - pdi.start_hour = calendar_config_get_day_start_hour (); - pdi.end_hour = calendar_config_get_day_end_hour (); - if (calendar_config_get_day_end_minute () != 0) - pdi.end_hour++; - pdi.rows = (pdi.end_hour - pdi.start_hour) * 2; - pdi.mins_per_row = 30; - pdi.start_minute_offset = pdi.start_hour * 60; - pdi.end_minute_offset = pdi.end_hour * 60; - pdi.use_24_hour_format = calendar_config_get_24_hour_format (); - - /* Get the events from the server. */ - client = gnome_calendar_get_cal_client (gcal); - cal_client_generate_instances (client, CALOBJ_TYPE_EVENT, start, end, - print_day_details_cb, &pdi); - qsort (pdi.long_events->data, pdi.long_events->len, - sizeof (EDayViewEvent), e_day_view_event_sort_func); - qsort (pdi.events[0]->data, pdi.events[0]->len, - sizeof (EDayViewEvent), e_day_view_event_sort_func); - - /* Also print events outside of work hours */ - if (pdi.events[0]->len > 0) { - icaltimezone *zone = get_timezone (); - struct icaltimetype tt; - - event = &g_array_index (pdi.events[0], EDayViewEvent, 0); - tt = icaltime_from_timet_with_zone (event->start, FALSE, zone); - if (tt.hour < pdi.start_hour) - pdi.start_hour = tt.hour; - pdi.start_minute_offset = pdi.start_hour * 60; - - event = &g_array_index (pdi.events[0], EDayViewEvent, pdi.events[0]->len - 1); - tt = icaltime_from_timet_with_zone (event->end, FALSE, zone); - if (tt.hour > pdi.end_hour || tt.hour == 0) { - pdi.end_hour = tt.hour ? tt.hour : 24; - if (tt.minute > 0) - pdi.end_hour++; - } - pdi.end_minute_offset = pdi.end_hour * 60; - - pdi.rows = (pdi.end_hour - pdi.start_hour) * 2; - } - - /* Lay them out the long events, across the top of the page. */ - e_day_view_layout_long_events (pdi.long_events, pdi.days_shown, - pdi.day_starts, &rows_in_top_display); - - /* Print the long events. */ - font = get_font_for_size (12, GNOME_FONT_BOOK, FALSE); - for (i = 0; i < pdi.long_events->len; i++) { - event = &g_array_index (pdi.long_events, EDayViewEvent, i); - print_day_long_event (pc, font, left, right, top, bottom, - DAY_VIEW_ROW_HEIGHT, event, &pdi); - } - gtk_object_unref (GTK_OBJECT (font)); - - /* We always leave space for DAY_VIEW_MIN_ROWS_IN_TOP_DISPLAY in the - top display, but we may have more rows than that, in which case - the main display area will be compressed. */ - rows_in_top_display = MAX (rows_in_top_display, - DAY_VIEW_MIN_ROWS_IN_TOP_DISPLAY); - - /* Draw the border around the long events. */ - gnome_print_setrgbcolor (pc, 0, 0, 0); - print_border (pc, left, right, - top, top - rows_in_top_display * DAY_VIEW_ROW_HEIGHT - 4, - 1.0, -1.0); - - /* Adjust the area containing the main display. */ - top -= rows_in_top_display * DAY_VIEW_ROW_HEIGHT + 4; - - /* Draw the borders, lines, and times down the left. */ - print_day_background (pc, gcal, whence, &pdi, - left, right, top, bottom); - - /* Now adjust to get rid of the time column. */ - left += DAY_VIEW_TIME_COLUMN_WIDTH; - - /* Lay out the short events, within the day. */ - e_day_view_layout_day_events (pdi.events[0], DAY_VIEW_ROWS, - DAY_VIEW_MINS_PER_ROW, pdi.cols_per_row); - - /* Print the short events. */ - max_font_size = ((top - bottom) / pdi.rows) - 4; - font_size = MIN (DAY_NORMAL_FONT_SIZE, max_font_size); - font = get_font_for_size (font_size, GNOME_FONT_BOOK, FALSE); - for (i = 0; i < pdi.events[0]->len; i++) { - event = &g_array_index (pdi.events[0], EDayViewEvent, i); - print_day_event (pc, font, left, right, top, bottom, - event, &pdi); - } - gtk_object_unref (GTK_OBJECT (font)); - - /* Free everything. */ - free_event_array (pdi.long_events); - g_array_free (pdi.long_events, TRUE); - free_event_array (pdi.events[0]); - g_array_free (pdi.events[0], TRUE); -} - - -/* This adds one event to the view, adding it to the appropriate array. */ -static gboolean -print_week_summary_cb (CalComponent *comp, - time_t start, - time_t end, - gpointer data) - -{ - icaltimezone *zone = get_timezone (); - EWeekViewEvent event; - struct icaltimetype start_tt, end_tt; - - struct psinfo *psi = (struct psinfo *)data; - - /* Check that the event times are valid. */ - -#if 0 - g_print ("View start:%li end:%li Event start:%li end:%li\n", - psi->day_starts[0], psi->day_starts[psi->days_shown], - start, end); -#endif - - g_return_val_if_fail (start <= end, TRUE); - g_return_val_if_fail (start < psi->day_starts[psi->days_shown], TRUE); - g_return_val_if_fail (end > psi->day_starts[0], TRUE); - - start_tt = icaltime_from_timet_with_zone (start, FALSE, zone); - end_tt = icaltime_from_timet_with_zone (end, FALSE, zone); - - event.comp = comp; - gtk_object_ref (GTK_OBJECT (event.comp)); - event.start = start; - event.end = end; - event.spans_index = 0; - event.num_spans = 0; - - event.start_minute = start_tt.hour * 60 + start_tt.minute; - event.end_minute = end_tt.hour * 60 + end_tt.minute; - if (event.end_minute == 0 && start != end) - event.end_minute = 24 * 60; - - g_array_append_val (psi->events, event); - - return TRUE; -} - - -/* Returns TRUE if the event is a one-day event (i.e. not a long event). */ -static gboolean -print_is_one_day_week_event (EWeekViewEvent *event, - EWeekViewEventSpan *span, - time_t *day_starts) -{ - if (event->start == day_starts[span->start_day] - && event->end == day_starts[span->start_day + 1]) - return FALSE; - - if (span->num_days == 1 - && event->start >= day_starts[span->start_day] - && event->end <= day_starts[span->start_day + 1]) - return TRUE; - - return FALSE; -} - - -static void -print_week_long_event (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double x1, double x2, double y1, double y2, - EWeekViewEvent *event, EWeekViewEventSpan *span, - char *text) -{ - double left_triangle_width = -1.0, right_triangle_width = -1.0; - struct tm date_tm; - char buffer[32]; - - /* If the event starts before the first day of the span, draw a - triangle to indicate it continues. */ - if (event->start < psi->day_starts[span->start_day]) - left_triangle_width = 4; - - /* If the event ends after the last day of the span, draw a - triangle. */ - if (event->end > psi->day_starts[span->start_day + span->num_days]) - right_triangle_width = 4; - - print_border_with_triangles (pc, x1, x2, y1, y2, 0.5, 0.9, - left_triangle_width, - right_triangle_width); - - /* If the event starts after the first day being printed, we need to - print the start time. */ - if (event->start > psi->day_starts[span->start_day]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, psi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x1 += 4; - print_text_size (pc, buffer, ALIGN_LEFT, x1, x2, y1, y2); - x1 += gnome_font_get_width_utf8 (font, buffer); - } - - /* If the event ends before the end of the last day being printed, - we need to print the end time. */ - if (event->end < psi->day_starts[span->start_day + span->num_days]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->end_minute / 60; - date_tm.tm_min = event->end_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, psi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x2 -= 4; - print_text_size (pc, buffer, ALIGN_RIGHT, x1, x2, y1, y2); - x2 -= gnome_font_get_width_utf8 (font, buffer); - } - - x1 += 4; - x2 -= 4; - print_text_size (pc, text, ALIGN_CENTER, x1, x2, y1, y2); -} - - -static void -print_week_day_event (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double x1, double x2, double y1, double y2, - EWeekViewEvent *event, EWeekViewEventSpan *span, - char *text) -{ - struct tm date_tm; - char buffer[32]; - - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, psi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - print_text_size (pc, buffer, ALIGN_LEFT, x1, x2, y1, y2); - x1 += gnome_font_get_width_utf8 (font, buffer); - - x1 += 4; - print_text_size (pc, text, ALIGN_LEFT, x1, x2, y1, y2); -} - - -static void -print_week_event (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double left, double top, - double cell_width, double cell_height, - EWeekViewEvent *event, GArray *spans) -{ - EWeekViewEventSpan *span; - gint span_num; - CalComponentText summary; - char *text; - int num_days, start_x, start_y, start_h, end_x, end_y, end_h; - double x1, x2, y1, y2; - - cal_component_get_summary (event->comp, &summary); - text = summary.value ? (char*) summary.value : ""; - - for (span_num = 0; span_num < event->num_spans; span_num++) { - span = &g_array_index (spans, EWeekViewEventSpan, - event->spans_index + span_num); - - if (e_week_view_layout_get_span_position - (event, span, - psi->rows_per_cell, - psi->rows_per_compressed_cell, - psi->display_start_weekday, - psi->multi_week_view, - psi->compress_weekend, - &num_days)) { - - e_week_view_layout_get_day_position - (span->start_day, - psi->multi_week_view, - psi->weeks_shown, - psi->display_start_weekday, - psi->compress_weekend, - &start_x, &start_y, &start_h); - - if (num_days == 1) { - end_x = start_x; - end_y = start_y; - end_h = start_h; - } else { - e_week_view_layout_get_day_position - (span->start_day + num_days - 1, - psi->multi_week_view, - psi->weeks_shown, - psi->display_start_weekday, - psi->compress_weekend, - &end_x, &end_y, &end_h); - } - - x1 = left + start_x * cell_width + 6; - x2 = left + (end_x + 1) * cell_width - 6; - y1 = top - start_y * cell_height - - psi->header_row_height - - span->row * psi->row_height; - y2 = y1 - psi->row_height * 0.9; - - if (print_is_one_day_week_event (event, span, - psi->day_starts)) { - print_week_day_event (pc, font, psi, - x1, x2, y1, y2, - event, span, text); - } else { - print_week_long_event (pc, font, psi, - x1, x2, y1, y2, - event, span, text); - } - } - } -} - - -static void -print_week_view_background (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double left, double top, - double cell_width, double cell_height) -{ - icaltimezone *zone = get_timezone (); - int day, day_x, day_y, day_h; - double x1, x2, y1, y2, font_size, fillcolor; - struct tm tm; - char *format_string, buffer[128], *utf_str; - - font_size = gnome_font_get_size (font); - - for (day = 0; day < psi->days_shown; day++) { - e_week_view_layout_get_day_position - (day, psi->multi_week_view, psi->weeks_shown, - psi->display_start_weekday, psi->compress_weekend, - &day_x, &day_y, &day_h); - - x1 = left + day_x * cell_width; - x2 = left + (day_x + 1) * cell_width; - y1 = top - day_y * cell_height; - y2 = y1 - day_h * cell_height; - - tm = *convert_timet_to_struct_tm (psi->day_starts[day], zone); - - /* In the month view we draw a grey background for the end - of the previous month and the start of the following. */ - fillcolor = -1.0; - if (psi->multi_week_view && (tm.tm_mon != psi->month)) - fillcolor = 0.9; - - print_border (pc, x1, x2, y1, y2, 1.0, fillcolor); - - if (psi->multi_week_view) { - if (tm.tm_mday == 1) - format_string = _("%d %B"); - else - format_string = "%d"; - } else { - gnome_print_moveto (pc, x1 + 0.1 * cell_width, - y1 - psi->header_row_height + 3); - gnome_print_lineto (pc, x2, - y1 - psi->header_row_height + 3); - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, 0.5); - gnome_print_stroke (pc); - - /* strftime format %A = full weekday name, %d = day of - month, %B = full month name. You can change the - order but don't change the specifiers or add - anything. */ - format_string = _("%A %d %B"); - - } - - strftime (buffer, sizeof (buffer), format_string, &tm); - utf_str = e_utf8_from_locale_string (buffer); - print_text_size (pc, utf_str, ALIGN_RIGHT, - x1, x2 - 4, y1 - 2, y1 - 2 - font_size); - g_free (utf_str); - } -} - - - -static void -print_week_summary (GnomePrintContext *pc, GnomeCalendar *gcal, - time_t whence, gboolean multi_week_view, int weeks_shown, - int month, double font_size, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - CalClient *client; - EWeekViewEvent *event; - struct psinfo psi; - time_t day_start; - gint rows_per_day[E_WEEK_VIEW_MAX_WEEKS * 7], day, event_num; - GArray *spans; - GnomeFont *font; - double cell_width, cell_height; - - psi.days_shown = weeks_shown * 7; - psi.events = g_array_new (FALSE, FALSE, sizeof (EWeekViewEvent)); - psi.multi_week_view = multi_week_view; - psi.weeks_shown = weeks_shown; - psi.month = month; - - /* Get a few config settings. */ - if (multi_week_view) - psi.compress_weekend = calendar_config_get_compress_weekend (); - else - psi.compress_weekend = TRUE; - psi.use_24_hour_format = calendar_config_get_24_hour_format (); - - /* We convert this from (0 = Sun, 6 = Sat) to (0 = Mon, 6 = Sun). */ - psi.display_start_weekday = calendar_config_get_week_start_day (); - psi.display_start_weekday = (psi.display_start_weekday + 6) % 7; - - /* If weekends are compressed then we can't start on a Sunday. */ - if (psi.compress_weekend && psi.display_start_weekday == 6) - psi.display_start_weekday = 5; - - day_start = time_day_begin_with_zone (whence, zone); - for (day = 0; day <= psi.days_shown; day++) { - psi.day_starts[day] = day_start; - day_start = time_add_day_with_zone (day_start, 1, zone); - } - - /* Get the events from the server. */ - client = gnome_calendar_get_cal_client (gcal); - cal_client_generate_instances (client, CALOBJ_TYPE_EVENT, - psi.day_starts[0], - psi.day_starts[psi.days_shown], - print_week_summary_cb, &psi); - qsort (psi.events->data, psi.events->len, - sizeof (EWeekViewEvent), e_week_view_event_sort_func); - - /* Layout the events. */ - spans = e_week_view_layout_events (psi.events, NULL, - psi.multi_week_view, - psi.weeks_shown, - psi.compress_weekend, - psi.display_start_weekday, - psi.day_starts, rows_per_day); - - /* Calculate the size of the cells. */ - if (multi_week_view) { - cell_width = (right - left) / (psi.compress_weekend ? 6 : 7); - cell_height = (top - bottom) / (weeks_shown * 2); - } else { - cell_width = (right - left) / 2; - cell_height = (top - bottom) / 6; - } - - /* Calculate the row height, using the normal font and with room for - space or a rectangle around it. */ - psi.row_height = font_size * 1.2; - psi.header_row_height = font_size * 1.5; - - /* Calculate how many rows we can fit into each type of cell. */ - psi.rows_per_cell = ((cell_height * 2) - psi.header_row_height) - / psi.row_height; - psi.rows_per_compressed_cell = (cell_height - psi.header_row_height) - / psi.row_height; - - font = get_font_for_size (font_size, GNOME_FONT_BOOK, FALSE); - - /* Draw the grid and the day names/numbers. */ - print_week_view_background (pc, font, &psi, left, top, - cell_width, cell_height); - - /* Print the events. */ - for (event_num = 0; event_num < psi.events->len; event_num++) { - event = &g_array_index (psi.events, EWeekViewEvent, event_num); - print_week_event (pc, font, &psi, left, top, - cell_width, cell_height, event, spans); - } - - gtk_object_unref (GTK_OBJECT (font)); - - /* Free everything. */ - for (event_num = 0; event_num < psi.events->len; event_num++) { - event = &g_array_index (psi.events, EWeekViewEvent, event_num); - gtk_object_unref (GTK_OBJECT (event->comp)); - } - g_array_free (psi.events, TRUE); - g_array_free (spans, TRUE); -} - - -static void -print_year_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom, - int morerows) -{ - icaltimezone *zone = get_timezone (); - double row_height, col_width, l, r, t, b; - time_t now; - int col, row, rows, cols; - - l = left; - t = top; - - /* If morerows is set we do 4 rows and 3 columns instead of 3 rows and - 4 columns. This is useful if we switch paper orientation. */ - if (morerows) { - rows = 4; - cols = 3; - } else { - rows = 3; - cols = 4; - } - - row_height = (top - bottom) / rows; - col_width = (right - left) / cols; - r = l + col_width; - b = top - row_height; - now = time_year_begin_with_zone (whence, zone); - - for (row = 0; row < rows; row++) { - t = top - row_height * row; - b = t - row_height; - for (col = 0; col < cols; col++) { - l = left + col_width * col; - r = l + col_width; - print_month_small (pc, gcal, now, - l + 8, r - 8, t - 8, b + 8, - DATE_MONTH, 0, 0, TRUE); - now = time_add_month_with_zone (now, 1, zone); - } - } -} - -static void -print_month_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - time_t date; - struct tm tm; - struct icaltimetype tt; - char buffer[100]; - GnomeFont *font; - gboolean compress_weekend; - int columns, col, weekday, len, month; - double font_size, cell_width, x1, x2, y1, y2; - - weekday = calendar_config_get_week_start_day (); - compress_weekend = calendar_config_get_compress_weekend (); - - /* Remember which month we want. */ - tt = icaltime_from_timet_with_zone (whence, FALSE, zone); - month = tt.month - 1; - - /* Find the start of the month, and then the start of the week on - or before that day. */ - date = time_month_begin_with_zone (whence, zone); - date = time_week_begin_with_zone (date, weekday, zone); - - /* If weekends are compressed then we can't start on a Sunday. */ - if (compress_weekend && weekday == 0) - date = time_add_day_with_zone (date, -1, zone); - - /* do day names ... */ - - /* We are only interested in outputting the weekday here, but we want - to be able to step through the week without worrying about - overflows making strftime choke, so we move near to the start of - the month. */ - tm = *convert_timet_to_struct_tm (date, zone); - tm.tm_mday = (tm.tm_mday % 7) + 7; - - font = get_font_for_size (MONTH_NORMAL_FONT_SIZE, GNOME_FONT_BOLD, FALSE); - font_size = gnome_font_get_size (font); - gnome_print_setfont (pc, font); - - columns = compress_weekend ? 6 : 7; - cell_width = (right - left) / columns; - y1 = top; - y2 = top - font_size * 1.5; - - for (col = 0; col < columns; col++) { - char *utf_str; - - if (tm.tm_wday == 6 && compress_weekend) { - strftime (buffer, sizeof (buffer), "%a/", &tm); - len = strlen (buffer); - tm.tm_mday++; - tm.tm_wday = (tm.tm_wday + 1) % 7; - strftime (buffer + len, sizeof (buffer) - len, - "%a", &tm); - } else { - strftime (buffer, sizeof (buffer), "%A", &tm); - } - - x1 = left + cell_width * col; - x2 = x1 + cell_width; - - print_border (pc, x1, x2, y1, y2, 1.0, -1.0); - utf_str = e_utf8_from_locale_string (buffer); - print_text_size (pc, utf_str, ALIGN_CENTER, x1, x2, y1, y2); - g_free (utf_str); - - tm.tm_mday++; - tm.tm_wday = (tm.tm_wday + 1) % 7; - } - gtk_object_unref (GTK_OBJECT (font)); - - top = y2; - print_week_summary (pc, gcal, date, TRUE, 6, month, - MONTH_NORMAL_FONT_SIZE, - left, right, top, bottom); -} - - -static void -print_todo_details (GnomePrintContext *pc, GnomeCalendar *gcal, - time_t start, time_t end, - double left, double right, double top, double bottom) -{ - CalClient *client; - GnomeFont *font_summary; - double y, yend, x, xend; - struct icaltimetype *tt; - ECalendarTable *task_pad; - ETable *table; - CalendarModel *model; - gint rows, row; - - /* We get the tasks directly from the TaskPad ETable. This means we - get them filtered & sorted for free. */ - task_pad = gnome_calendar_get_task_pad (gcal); - table = e_calendar_table_get_table (task_pad); - model = e_calendar_table_get_model (task_pad); - client = gnome_calendar_get_task_pad_cal_client (gcal); - - font_summary = get_font_for_size (10, GNOME_FONT_BOOK, FALSE); - - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, 0.0); - - titled_box (pc, U_("Tasks"), font_summary, ALIGN_CENTER | ALIGN_BORDER, - &left, &right, &top, &bottom, 1.0); - - y = top - 3; - yend = bottom - 2; - - rows = e_table_model_row_count (E_TABLE_MODEL (model)); - for (row = 0; row < rows; row++) { - CalComponent *comp; - CalComponentText summary; - int model_row; - - model_row = e_table_view_to_model_row (table, row); - comp = calendar_model_get_component (model, model_row); - - cal_component_get_summary (comp, &summary); - - if (!summary.value) - continue; - - x = left; - xend = right - 2; - - if (y < bottom) - break; - - /* Print the box to put the tick in. */ - print_border (pc, x + 2, x + 8, y - 3, y - 11, 0.1, -1.0); - - /* If the task is complete, print a tick in the box. */ - cal_component_get_completed (comp, &tt); - if (tt) { - cal_component_free_icaltimetype (tt); - - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, 1.0); - gnome_print_moveto (pc, x + 3, y - 8); - gnome_print_lineto (pc, x + 5, y - 10); - gnome_print_lineto (pc, x + 7, y - 3.5); - gnome_print_stroke (pc); - } - - y = bound_text (pc, font_summary, summary.value, - x + 10, xend, y, yend, 0); - y += gnome_font_get_size (font_summary) - 6; - gnome_print_moveto (pc, x, y); - gnome_print_lineto (pc, xend, y); - gnome_print_stroke (pc); - y -= 3; - } - - gtk_object_unref (GTK_OBJECT (font_summary)); -} - - -/* Value for the PrintView enum */ -static const int print_view_map[] = { - PRINT_VIEW_DAY, - PRINT_VIEW_WEEK, - PRINT_VIEW_MONTH, - PRINT_VIEW_YEAR, - -1 -}; - -/* Creates the range selector widget for printing a calendar */ -static GtkWidget * -range_selector_new (GtkWidget *dialog, time_t at, int *view) -{ - icaltimezone *zone = get_timezone (); - GtkWidget *box; - GtkWidget *radio; - GSList *group; - char text[1024]; - char str1[512]; - char str2[512]; - struct tm tm; - time_t week_begin, week_end; - struct tm week_begin_tm, week_end_tm; - gint week_start_day; - - box = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); - - tm = *convert_timet_to_struct_tm (at, zone); - - /* Day */ - - strftime (text, sizeof (text), _("Selected day (%a %b %d %Y)"), &tm); - radio = gtk_radio_button_new_with_label (NULL, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Week */ - - week_start_day = calendar_config_get_week_start_day (); - week_begin = time_week_begin_with_zone (at, week_start_day, zone); - /* If the week starts on a Sunday, we have to show the Saturday first, - since the weekend is compressed. If the original date passed in was - a Saturday, we need to move on to the next Saturday, else we move - back to the last one. */ - if (week_start_day == 0) { - if (tm.tm_wday == 6) - week_begin = time_add_day_with_zone (week_begin, 6, zone); - else - week_begin = time_add_day_with_zone (week_begin, -1, zone); - } - week_end = time_add_day_with_zone (week_begin, 6, zone); - - week_begin_tm = *convert_timet_to_struct_tm (week_begin, zone); - week_end_tm = *convert_timet_to_struct_tm (week_end, zone); - - if (week_begin_tm.tm_mon == week_end_tm.tm_mon) { - strftime (str1, sizeof (str1), _("%a %b %d"), &week_begin_tm); - strftime (str2, sizeof (str2), _("%a %d %Y"), &week_end_tm); - } else { - if (week_begin_tm.tm_year == week_end_tm.tm_year) { - strftime (str1, sizeof (str1), _("%a %b %d"), &week_begin_tm); - strftime (str2, sizeof (str2), _("%a %b %d %Y"), &week_end_tm); - } else { - strftime (str1, sizeof (str1), _("%a %b %d %Y"), &week_begin_tm); - strftime (str2, sizeof (str2), _("%a %b %d %Y"), &week_end_tm); - } - } - - g_snprintf (text, sizeof (text), _("Selected week (%s - %s)"), str1, str2); - - radio = gtk_radio_button_new_with_label (group, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Month */ - - strftime (text, sizeof (text), _("Selected month (%b %Y)"), &tm); - radio = gtk_radio_button_new_with_label (group, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Year */ - - strftime (text, sizeof (text), _("Selected year (%Y)"), &tm); - radio = gtk_radio_button_new_with_label (group, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Select default */ - - e_dialog_widget_hook_value (dialog, radio, view, (gpointer) print_view_map); - - gtk_widget_show_all (box); - return box; -} - - -static void -print_day_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - int i, days = 1; - double todo, header, l; - char buf[100]; - - for (i = 0; i < days; i++) { - todo = (right - left) * 0.75 + left; - header = top - HEADER_HEIGHT; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Day View"); - - /* Print the main view with all the events in. */ - print_day_details (pc, gcal, date, - left, todo - 2.0, header, bottom); - - /* Print the TaskPad down the right. */ - print_todo_details (pc, gcal, 0, INT_MAX, - todo, right, header, bottom); - - /* Print the filled border around the header. */ - print_border (pc, left, right, top, header + 2.0, 1.0, 0.9); - - /* Print the 2 mini calendar-months. */ - l = right - SMALL_MONTH_PAD - SMALL_MONTH_WIDTH * 2 - - SMALL_MONTH_SPACING; - print_month_small (pc, gcal, date, - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, date, date, FALSE); - - l += SMALL_MONTH_SPACING + SMALL_MONTH_WIDTH; - print_month_small (pc, gcal, - time_add_month_with_zone (date, 1, zone), - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - - /* Print the date, e.g. '8th May, 2001'. */ - format_date (date, DATE_DAY | DATE_MONTH | DATE_YEAR, - buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 4, todo, top - 4, top - 4 - 24); - - /* Print the day, e.g. 'Tuesday'. */ - format_date (date, DATE_DAYNAME, buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 4, todo, top - 32, top - 32 - 18); - - gnome_print_showpage (pc); - date = time_add_day_with_zone (date, 1, zone); - } -} - - -static void -print_week_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - double header, l; - char buf[100]; - time_t when; - gint week_start_day; - struct tm tm; - - header = top - HEADER_HEIGHT; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Week View"); - - tm = *convert_timet_to_struct_tm (date, zone); - week_start_day = calendar_config_get_week_start_day (); - when = time_week_begin_with_zone (date, week_start_day, zone); - /* If the week starts on a Sunday, we have to show the Saturday first, - since the weekend is compressed. */ - if (week_start_day == 0) { - if (tm.tm_wday == 6) - when = time_add_day_with_zone (when, 6, zone); - else - when = time_add_day_with_zone (when, -1, zone); - } - - /* Print the main week view. */ - print_week_summary (pc, gcal, when, FALSE, 1, 0, - WEEK_NORMAL_FONT_SIZE, - left, right, header, bottom); - - /* Print the border around the main view. */ - print_border (pc, left, right, header, bottom, 1.0, -1.0); - - /* Print the border around the header area. */ - print_border (pc, left, right, top, header + 2.0, 1.0, 0.9); - - /* Print the 2 mini calendar-months. */ - l = right - SMALL_MONTH_PAD - SMALL_MONTH_WIDTH * 2 - - SMALL_MONTH_SPACING; - print_month_small (pc, gcal, when, - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, when, - time_add_week_with_zone (when, 1, zone), FALSE); - - l += SMALL_MONTH_SPACING + SMALL_MONTH_WIDTH; - print_month_small (pc, gcal, - time_add_month_with_zone (when, 1, zone), - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, when, - time_add_week_with_zone (when, 1, zone), FALSE); - - /* Print the start day of the week, e.g. '7th May 2001'. */ - format_date (when, DATE_DAY | DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 3, right, top - 4, top - 4 - 24); - - /* Print the end day of the week, e.g. '13th May 2001'. */ - when = time_add_day_with_zone (when, 6, zone); - format_date (when, DATE_DAY | DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 3, right, top - 24 - 3, top - 24 - 3 - 24); - - gnome_print_showpage (pc); -} - - -static void -print_month_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - double header; - char buf[100]; - - header = top - HEADER_HEIGHT; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Month View"); - - /* Print the main month view. */ - print_month_summary (pc, gcal, date, left, right, header, bottom); - - /* Print the border around the header. */ - print_border (pc, left, right, top, header, 1.0, 0.9); - - /* Print the 2 mini calendar-months. */ - print_month_small (pc, gcal, - time_add_month_with_zone (date, 1, zone), - right - (right - left) / 7 + 2, right - 8, - top - 4, header, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - print_month_small (pc, gcal, - time_add_month_with_zone (date, -1, zone), - left + 8, left + (right - left) / 7 - 2, - top - 4, header, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - - /* Print the month, e.g. 'May 2001'. */ - format_date (date, DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_CENTER, - left + 3, right - 3, top - 3, top - 3 - 24); - - gnome_print_showpage (pc); -} - - -static void -print_year_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - char buf[100]; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Year View"); - - print_year_summary (pc, gcal, date, left, right, top - 50, bottom, - TRUE); - - /* centered title */ - format_date (date, DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_CENTER, - left+3, right, top-3, top - 27); - - gnome_print_showpage (pc); -} - -static void -write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext) -{ - icaltimezone *zone = get_timezone (); - struct tm *tmp_tm; - int len; - - tmp_tm = convert_timet_to_struct_tm (t, zone); - - if (stext != NULL) - strcat (buffer, stext); - - len = strlen (buffer); - e_time_format_date_and_time (tmp_tm, - calendar_config_get_24_hour_format (), - FALSE, FALSE, - &buffer[len], size - len); - if (etext != NULL) - strcat (buffer, etext); -} - -static icaltimezone* -get_zone_from_tzid (CalClient *client, const char *tzid) -{ - icaltimezone *zone; - - /* Note that the timezones may not be on the server, so we try to get - the builtin timezone with the TZID first. */ - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (!zone) { - CalClientGetStatus status; - - status = cal_client_get_timezone (client, tzid, &zone); - /* FIXME: Handle error better. */ - if (status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - tzid ? tzid : ""); - } - - return zone; -} - -static void -print_date_label (GnomePrintContext *pc, CalComponent *comp, CalClient *client, - double left, double right, double top, double bottom) -{ - icaltimezone *start_zone, *end_zone, *due_zone, *completed_zone; - CalComponentDateTime datetime; - time_t start = 0, end = 0, complete = 0, due = 0; - static char buffer[1024], *utf_text; - - cal_component_get_dtstart (comp, &datetime); - if (datetime.value) { - start_zone = get_zone_from_tzid (client, datetime.tzid); - start = icaltime_as_timet_with_zone (*datetime.value, - start_zone); - } - cal_component_free_datetime (&datetime); - - cal_component_get_dtend (comp, &datetime); - if (datetime.value) { - end_zone = get_zone_from_tzid (client, datetime.tzid); - end = icaltime_as_timet_with_zone (*datetime.value, - end_zone); - } - cal_component_free_datetime (&datetime); - - cal_component_get_due (comp, &datetime); - if (datetime.value) { - due_zone = get_zone_from_tzid (client, datetime.tzid); - due = icaltime_as_timet_with_zone (*datetime.value, - due_zone); - } - cal_component_free_datetime (&datetime); - - cal_component_get_completed (comp, &datetime.value); - if (datetime.value) { - completed_zone = icaltimezone_get_utc_timezone (); - complete = icaltime_as_timet_with_zone (*datetime.value, - completed_zone); - cal_component_free_icaltimetype (datetime.value); - } - - buffer[0] = '\0'; - - if (start > 0) - write_label_piece (start, buffer, 1024, NULL, NULL); - - if (end > 0 && start > 0) - write_label_piece (end, buffer, 1024, _(" to "), NULL); - - if (complete > 0) { - if (start > 0) - write_label_piece (complete, buffer, 1024, _(" (Completed "), ")"); - else - write_label_piece (complete, buffer, 1024, _("Completed "), NULL); - } - - if (due > 0 && complete == 0) { - if (start > 0) - write_label_piece (due, buffer, 1024, _(" (Due "), ")"); - else - write_label_piece (due, buffer, 1024, _("Due "), NULL); - } - - utf_text = e_utf8_from_locale_string (buffer); - print_text_size_bold (pc, utf_text, ALIGN_LEFT, - left, right, top, top - 15); - g_free (utf_text); -} - -static void -print_comp_item (GnomePrintContext *pc, CalComponent *comp, CalClient *client, - double left, double right, double top, double bottom) -{ - GnomeFont *font; - CalComponentVType vtype; - CalComponentText text; - GSList *desc, *l; - const char *title, *categories; - char *categories_string; - GSList *contact_list, *elem; - gint header_size; - - vtype = cal_component_get_vtype (comp); - - /* We should only be asked to print VEVENTs or VTODOs. */ - if (vtype == CAL_COMPONENT_EVENT) - title = U_("Appointment"); - else if (vtype == CAL_COMPONENT_TODO) - title = U_("Task"); - else - return; - - /* Print the title in a box at the top of the page. */ - font = get_font_for_size (18, GNOME_FONT_BOLD, FALSE); - header_size = 50; - print_border (pc, left, right, top, top - header_size, - 1.0, 0.9); - print_text (pc, font, title, ALIGN_CENTER, left, right, - top - header_size * 0.1, top - header_size); - gtk_object_unref (GTK_OBJECT (font)); - - top -= header_size + 10; - - /* Summary */ - font = get_font_for_size (18, GNOME_FONT_BOLD, FALSE); - cal_component_get_summary (comp, &text); - top = bound_text (pc, font, text.value, left, right, - top - 3, bottom, 0); - gtk_object_unref (GTK_OBJECT (font)); - - /* Date information */ - print_date_label (pc, comp, client, left, right, top-3, top - 15); - top -= 20; - - font = get_font_for_size (12, GNOME_FONT_BOOK, FALSE); - - /* For a VTODO we print the Status, Priority, % Complete and URL. */ - if (vtype == CAL_COMPONENT_TODO) { - icalproperty_status status; - const char *status_string = NULL; - int *percent; - int *priority; - const char *url; - - /* Status */ - cal_component_get_status (comp, &status); - if (status != ICAL_STATUS_NONE) { - switch (status) { - case ICAL_STATUS_NEEDSACTION: - status_string = U_("Not Started"); - break; - case ICAL_STATUS_INPROCESS: - status_string = U_("In Progress"); - break; - case ICAL_STATUS_COMPLETED: - status_string = U_("Completed"); - break; - case ICAL_STATUS_CANCELLED: - status_string = U_("Cancelled"); - break; - default: - break; - } - - if (status_string) { - char *text = g_strdup_printf (U_("Status: %s"), - status_string); - top = bound_text (pc, font, text, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - g_free (text); - } - } - - /* Priority */ - cal_component_get_priority (comp, &priority); - if (priority && *priority >= 0) { - char *priority_string, *priority_utf8, *text; - - priority_string = cal_util_priority_to_string (*priority); - cal_component_free_priority (priority); - - priority_utf8 = e_utf8_from_locale_string (priority_string); - text = g_strdup_printf (U_("Priority: %s"), - priority_utf8); - top = bound_text (pc, font, text, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - g_free (text); - g_free (priority_utf8); - } - - /* Percent Complete */ - cal_component_get_percent (comp, &percent); - if (percent) { - char *percent_string; - - percent_string = g_strdup_printf (U_("Percent Complete: %i"), *percent); - cal_component_free_percent (percent); - - top = bound_text (pc, font, percent_string, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - } - - - /* URL */ - cal_component_get_url (comp, &url); - if (url && url[0]) { - char *url_string = g_strdup_printf (U_("URL: %s"), - url); - - top = bound_text (pc, font, url_string, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - - g_free (url_string); - } - } - - /* Categories */ - cal_component_get_categories (comp, &categories); - if (categories && categories[0]) { - categories_string = g_strdup_printf (U_("Categories: %s"), - categories); - top = bound_text (pc, font, categories_string, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - g_free (categories_string); - } - - /* Contacts */ - cal_component_get_contact_list (comp, &contact_list); - if (contact_list) { - GString *contacts = g_string_new (U_("Contacts: ")); - for (elem = contact_list; elem; elem = elem->next) { - CalComponentText *t = elem->data; - /* Put a comma between contacts. */ - if (elem != contact_list) - g_string_append (contacts, ", "); - g_string_append (contacts, t->value); - } - cal_component_free_text_list (contact_list); - - top = bound_text (pc, font, contacts->str, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - - g_string_free (contacts, TRUE); - } - - top -= 16; - - /* Description */ - cal_component_get_description_list (comp, &desc); - for (l = desc; l != NULL; l = l->next) { - CalComponentText *text = l->data; - - if (text->value != NULL) - top = bound_text (pc, font, text->value, left, right, top-3, bottom, 0); - } - cal_component_free_text_list (desc); - gtk_object_unref (GTK_OBJECT (font)); - - gnome_print_showpage (pc); -} - -void -print_calendar (GnomeCalendar *gcal, gboolean preview, time_t date, - PrintView default_view) -{ - GnomePrinter *printer; - GnomePrintMaster *gpm; - GnomePrintContext *pc; - int copies, collate; - double l, r, t, b; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - printer = NULL; - copies = 1; - collate = FALSE; - - if (!preview) { - GtkWidget *gpd; - GtkWidget *range; - int view; - - gpd = gnome_print_dialog_new (_("Print Calendar"), - GNOME_PRINT_DIALOG_RANGE - | GNOME_PRINT_DIALOG_COPIES); - - view = (int) default_view; - range = range_selector_new (gpd, date, &view); - gnome_print_dialog_construct_range_custom (GNOME_PRINT_DIALOG (gpd), range); - - gnome_dialog_set_default (GNOME_DIALOG (gpd), - GNOME_PRINT_PRINT); - - /* Run dialog */ - - switch (gnome_dialog_run (GNOME_DIALOG (gpd))) { - case GNOME_PRINT_PRINT: - break; - - case GNOME_PRINT_PREVIEW: - preview = TRUE; - break; - - case -1: - return; - - default: - gnome_dialog_close (GNOME_DIALOG (gpd)); - return; - } - - e_dialog_get_values (gpd); - default_view = (PrintView) view; - - gnome_print_dialog_get_copies (GNOME_PRINT_DIALOG (gpd), - &copies, &collate); - printer = gnome_print_dialog_get_printer (GNOME_PRINT_DIALOG (gpd)); - - gnome_dialog_close (GNOME_DIALOG (gpd)); - } - - /* FIXME: allow configuration of paper size */ - - gpm = gnome_print_master_new (); - - if (paper_info == NULL) - paper_info = gnome_paper_with_name (gnome_paper_name_default ()); - gnome_print_master_set_paper (gpm, paper_info); - - if (printer) - gnome_print_master_set_printer (gpm, printer); - - gnome_print_master_set_copies (gpm, copies, collate); - - pc = gnome_print_master_get_context (gpm); - - l = gnome_paper_lmargin (paper_info); - r = gnome_paper_pswidth (paper_info) - - gnome_paper_rmargin (paper_info); - t = gnome_paper_psheight (paper_info) - - gnome_paper_tmargin (paper_info); - b = gnome_paper_bmargin (paper_info); - - /* depending on the view, do a different output */ - switch (default_view) { - case PRINT_VIEW_DAY: - print_day_view (pc, gcal, date, l, r, t, b); - break; - case PRINT_VIEW_WEEK: - print_week_view (pc, gcal, date, l, r, t, b); - break; - case PRINT_VIEW_MONTH: - gnome_print_rotate (pc, 90); - gnome_print_translate (pc, 0, - -gnome_paper_pswidth (paper_info)); - print_month_view (pc, gcal, date, b, t, r, l); - break; - case PRINT_VIEW_YEAR: - print_year_view (pc, gcal, date, l, r, t, b); - break; - default: - g_assert_not_reached (); - } - - gnome_print_master_close (gpm); - - if (preview) { - GnomePrintMasterPreview *gpmp; - gboolean landscape = FALSE; - - if (default_view == PRINT_VIEW_MONTH) - landscape = TRUE; - - gpmp = gnome_print_master_preview_new_with_orientation (gpm, _("Print Preview"), landscape); - gtk_widget_show (GTK_WIDGET (gpmp)); - } else { - gnome_print_master_print (gpm); - } - - gtk_object_unref (GTK_OBJECT (gpm)); -} - - -void -print_comp (CalComponent *comp, CalClient *client, gboolean preview) -{ - GnomePrinter *printer; - GnomePrintMaster *gpm; - GnomePrintContext *pc; - int copies, collate; - double l, r, t, b; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - printer = NULL; - copies = 1; - collate = FALSE; - - if (!preview) { - GtkWidget *gpd; - - gpd = gnome_print_dialog_new (_("Print Item"), - GNOME_PRINT_DIALOG_COPIES); - - gnome_dialog_set_default (GNOME_DIALOG (gpd), - GNOME_PRINT_PRINT); - - /* Run dialog */ - - switch (gnome_dialog_run (GNOME_DIALOG (gpd))) { - case GNOME_PRINT_PRINT: - break; - - case GNOME_PRINT_PREVIEW: - preview = TRUE; - break; - - case -1: - return; - - default: - gnome_dialog_close (GNOME_DIALOG (gpd)); - return; - } - - e_dialog_get_values (gpd); - - gnome_print_dialog_get_copies (GNOME_PRINT_DIALOG (gpd), - &copies, &collate); - printer = gnome_print_dialog_get_printer (GNOME_PRINT_DIALOG (gpd)); - - gnome_dialog_close (GNOME_DIALOG (gpd)); - } - - /* FIXME: allow configuration of paper size */ - - gpm = gnome_print_master_new (); - - if (paper_info == NULL) - paper_info = gnome_paper_with_name (gnome_paper_name_default ()); - gnome_print_master_set_paper (gpm, paper_info); - - if (printer) - gnome_print_master_set_printer (gpm, printer); - - gnome_print_master_set_copies (gpm, copies, collate); - - pc = gnome_print_master_get_context (gpm); - - l = gnome_paper_lmargin (paper_info); - r = gnome_paper_pswidth (paper_info) - - gnome_paper_rmargin (paper_info); - t = gnome_paper_psheight (paper_info) - - gnome_paper_tmargin (paper_info); - b = gnome_paper_bmargin (paper_info); - - print_comp_item (pc, comp, client, l, r, t, b); - - gnome_print_master_close (gpm); - - if (preview) { - GnomePrintMasterPreview *gpmp; - - gpmp = gnome_print_master_preview_new (gpm, - _("Print Preview")); - gtk_widget_show (GTK_WIDGET (gpmp)); - } else { - gnome_print_master_print (gpm); - } - - gtk_object_unref (GTK_OBJECT (gpm)); -} - -void -print_setup (void) -{ - GtkWidget *dlg, *ps; - gint btn; - - ps = gnome_paper_selector_new (); - gtk_widget_show (ps); - - dlg = gnome_dialog_new (_("Print Setup"), - GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, - NULL); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dlg)->vbox), ps, TRUE, TRUE, 2); - - btn = gnome_dialog_run (GNOME_DIALOG (dlg)); - if (btn == 0) { - gchar *name; - - name = gnome_paper_selector_get_name (GNOME_PAPER_SELECTOR (ps)); - paper_info = gnome_paper_with_name (name); - } - - gnome_dialog_close (GNOME_DIALOG (dlg)); -} |