diff options
author | Federico Mena Quintero <federico@nuclecu.unam.mx> | 1998-08-28 08:29:59 +0800 |
---|---|---|
committer | Arturo Espinosa <unammx@src.gnome.org> | 1998-08-28 08:29:59 +0800 |
commit | 21e41f438e4761587b0ea42db80b23dde1eb59e3 (patch) | |
tree | bf8fed6dc79bd0df6121f757e5f91afd699f645f /calendar/gui/year-view.c | |
parent | e4a4179f9d2226b1420e73ae894221502bfd7209 (diff) | |
download | gsoc2013-evolution-21e41f438e4761587b0ea42db80b23dde1eb59e3.tar.gz gsoc2013-evolution-21e41f438e4761587b0ea42db80b23dde1eb59e3.tar.zst gsoc2013-evolution-21e41f438e4761587b0ea42db80b23dde1eb59e3.zip |
Today: fixed calculation of day indexes when weeks start on Monday. The
Today: fixed calculation of day indexes when weeks start on Monday.
The year view now marks days (and fixed bugs in day marking as well).
Next step: make a generic month-marker routine and use that all
over the place.
1998-08-27 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gnome-month-item.c (build_month): Now does the correct thing
when the user wants weeks to start on Monday. Now all the Monday
special casing, as far as day numbering is concerned, is only in
this function.
* year-view.c (mark_days): This function marks the days that have
events in them. It also fixes a memory leak in the old
implementation (it was leaking the whole list).
(unmark_days): New function used to unmark all the days in the
year view.
(mark_event): New function that marks all the days that are
spanned by a time range. It also fixes the bug in the old
implementation where it could possibly mark days past the ends of
the year (if the event crosses year boundaries, for example).
* timeutil.c (time_year_begin): Take the year parameter since year
1, not 1900.
(time_year_end): Likewise.
* year-view.c (year_view_size_allocate): Now changing the size of
the calendars is done in the idle loop.
(idle_handler): This function actually does the resizing of the items.
* year-view.h (struct _YearView): Added idle_id and need_resize
fields.
svn path=/trunk/; revision=346
Diffstat (limited to 'calendar/gui/year-view.c')
-rw-r--r-- | calendar/gui/year-view.c | 525 |
1 files changed, 219 insertions, 306 deletions
diff --git a/calendar/gui/year-view.c b/calendar/gui/year-view.c index 8a5bedc038..bb3a38ecab 100644 --- a/calendar/gui/year-view.c +++ b/calendar/gui/year-view.c @@ -10,6 +10,7 @@ #include <libgnomeui/gnome-canvas-text.h> #include "year-view.h" #include "main.h" +#include "timeutil.h" #define HEAD_SPACING 4 /* Spacing between year heading and months */ @@ -19,6 +20,7 @@ static void year_view_class_init (YearViewClass *class); static void year_view_init (YearView *yv); +static void year_view_destroy (GtkObject *object); static void year_view_size_request (GtkWidget *widget, GtkRequisition *requisition); static void year_view_size_allocate (GtkWidget *widget, @@ -54,16 +56,103 @@ year_view_get_type (void) static void year_view_class_init (YearViewClass *class) { + GtkObjectClass *object_class; GtkWidgetClass *widget_class; + object_class = (GtkObjectClass *) class; widget_class = (GtkWidgetClass *) class; parent_class = gtk_type_class (gnome_canvas_get_type ()); + object_class->destroy = year_view_destroy; + widget_class->size_request = year_view_size_request; widget_class->size_allocate = year_view_size_allocate; } +/* Resizes the year view's child items. This is done in the idle loop for performance (we avoid + * resizing on every size allocation). + */ +static gint +idle_handler (gpointer data) +{ + YearView *yv; + double width, height; + double mwidth, mheight; + double h_yofs, m_yofs; + double x, y; + GtkArg arg; + GdkFont *head_font, *title_font; + int i; + + yv = data; + + /* Get the fonts to get their size later */ + + arg.name = "font_gdk"; + gtk_object_getv (GTK_OBJECT (yv->heading), 1, &arg); + head_font = GTK_VALUE_BOXED (arg); + + arg.name = "font_gdk"; + gtk_object_getv (GTK_OBJECT (yv->titles[0]), 1, &arg); + title_font = GTK_VALUE_BOXED (arg); + + /* Adjust heading */ + + gnome_canvas_item_set (yv->heading, + "x", (double) yv->canvas.width / 2.0, + "y", (double) HEAD_SPACING, + NULL); + + /* Adjust months */ + + h_yofs = 2 * HEAD_SPACING + head_font->ascent + head_font->descent; + m_yofs = SPACING + title_font->ascent + title_font->descent; + + width = (yv->canvas.width + SPACING) / 3.0; + height = (yv->canvas.height - h_yofs + SPACING) / 4.0; + + mwidth = (yv->canvas.width - 2 * SPACING) / 3.0; + mheight = (yv->canvas.height - h_yofs - 3 * SPACING - 4 * m_yofs) / 4.0; + + for (i = 0; i < 12; i++) { + x = (i % 3) * width; + y = (i / 3) * height + h_yofs; + + /* Title */ + + gnome_canvas_item_set (yv->titles[i], + "x", x + width / 2.0, + "y", y, + NULL); + + /* Month item */ + + gnome_canvas_item_set (yv->mitems[i], + "x", x, + "y", y + m_yofs, + "width", mwidth, + "height", mheight, + NULL); + } + + /* Done */ + + yv->need_resize = FALSE; + return FALSE; +} + +/* Marks the year view as needing a resize, which will be performed during the idle loop */ +static void +need_resize (YearView *yv) +{ + if (yv->need_resize) + return; + + yv->need_resize = TRUE; + yv->idle_id = gtk_idle_add (idle_handler, yv); +} + static void year_view_init (YearView *yv) { @@ -107,6 +196,30 @@ year_view_init (YearView *yv) "heading_color", "white", NULL); } + + /* We will need to resize the items when we paint for the first time */ + + yv->idle_id = -1; + need_resize (yv); +} + +static void +year_view_destroy (GtkObject *object) +{ + YearView *yv; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_YEAR_VIEW (object)); + + yv = YEAR_VIEW (object); + + if (yv->need_resize) { + yv->need_resize = FALSE; + gtk_idle_remove (yv->idle_id); + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } GtkWidget * @@ -146,14 +259,6 @@ static void year_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { YearView *yv; - double width, height; - double mwidth, mheight; - double h_yofs; - double m_yofs; - double x, y; - int i; - GtkArg arg; - GdkFont *head_font, *title_font; g_return_if_fail (widget != NULL); g_return_if_fail (IS_YEAR_VIEW (widget)); @@ -165,79 +270,139 @@ year_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); gnome_canvas_set_scroll_region (GNOME_CANVAS (yv), 0, 0, allocation->width, allocation->height); + need_resize (yv); +} - arg.name = "font_gdk"; - gtk_object_getv (GTK_OBJECT (yv->heading), 1, &arg); - head_font = GTK_VALUE_BOXED (arg); +void +year_view_update (YearView *yv, iCalObject *object, int flags) +{ + g_return_if_fail (yv != NULL); + g_return_if_fail (IS_YEAR_VIEW (yv)); - arg.name = "font_gdk"; - gtk_object_getv (GTK_OBJECT (yv->titles[0]), 1, &arg); - title_font = GTK_VALUE_BOXED (arg); + /* If only the summary changed, we don't care */ - /* Adjust heading */ + if (object && ((flags & CHANGE_SUMMARY) == flags)) + return; - gnome_canvas_item_set (yv->heading, - "x", (double) allocation->width / 2.0, - "y", (double) HEAD_SPACING, - NULL); + year_view_set (yv, time_year_begin (yv->year)); +} - /* Adjust months */ +/* Unmarks all the days in the year view by setting their boxes and labels to the default colors */ +static void +unmark_days (YearView *yv) +{ + GnomeCanvasItem *item; + int i, j; - h_yofs = 2 * HEAD_SPACING + head_font->ascent + head_font->descent; - m_yofs = SPACING + title_font->ascent + title_font->descent; + for (i = 0; i < 12; i++) + for (j = 0; j < 42; j++) { + /* Box */ + + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (yv->mitems[i]), + GNOME_MONTH_ITEM_DAY_BOX + j); + gnome_canvas_item_set (item, + "fill_color", "#d6d6d6d6d6d6", + NULL); + + /* Label */ + + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (yv->mitems[i]), + GNOME_MONTH_ITEM_DAY_LABEL + j); + gnome_canvas_item_set (item, + "fill_color", "black", + NULL); + } +} - width = (allocation->width + SPACING) / 3.0; - height = (allocation->height - h_yofs + SPACING) / 4.0; +/* Marks all the days that fall into the specified time span */ +static void +mark_event (YearView *yv, time_t start, time_t end) +{ + time_t t; + struct tm tm; + int day_index; + GnomeCanvasItem *mitem, *item; - mwidth = (allocation->width - 2 * SPACING) / 3.0; - mheight = (allocation->height - h_yofs - 3 * SPACING - 4 * m_yofs) / 4.0; + tm = *localtime (&start); + end = time_end_of_day (end); - for (i = 0; i < 12; i++) { - x = (i % 3) * width; - y = (i / 3) * height + h_yofs; + for (t = start; t < end; t += 60 * 60 * 24) { + mktime (&tm); /* normalize the time */ - /* Title */ + /* We need this comparison because an event may span more than one year (!). + * Yes, this is not the most efficient way of doing this (we could just clip + * the event to the current year), but it will do for now. + */ - gnome_canvas_item_set (yv->titles[i], - "x", x + width / 2.0, - "y", y, - NULL); + if ((tm.tm_year + 1900) == yv->year) { + /* Figure out the month item and day index that correspond to this time */ - /* Month item */ + mitem = yv->mitems[tm.tm_mon]; + day_index = gnome_month_item_day2index (GNOME_MONTH_ITEM (mitem), tm.tm_mday); + g_assert (day_index != -1); - gnome_canvas_item_set (yv->mitems[i], - "x", x, - "y", y + m_yofs, - "width", mwidth, - "height", mheight, - NULL); + /* Mark the day box */ + + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), + GNOME_MONTH_ITEM_DAY_BOX + day_index); + gnome_canvas_item_set (item, + "fill_color", "tan", + NULL); + + /* Mark the day label */ + + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), + GNOME_MONTH_ITEM_DAY_LABEL + day_index); + gnome_canvas_item_set (item, + "fill_color", "black", + NULL); + } + + /* Next day */ + + tm.tm_mday++; } } -void -year_view_update (YearView *yv, iCalObject *object, int flags) +/* Queries the calendar for all the events in the current year and marks the days that have at least + * one event in them. + */ +static void +mark_days (YearView *yv) { - g_return_if_fail (yv != NULL); - g_return_if_fail (IS_YEAR_VIEW (yv)); + time_t year_begin, year_end; + GList *list, *l; + CalendarObject *co; + + year_begin = time_year_begin (yv->year); + year_end = time_year_end (yv->year); - /* FIXME */ + list = calendar_get_events_in_range (yv->calendar->cal, year_begin, year_end); + + for (l = list; l; l = l->next) { + co = l->data; + mark_event (yv, co->ev_start, co->ev_end); + } + + calendar_destroy_event_list (list); } void year_view_set (YearView *yv, time_t year) { - struct tm tm; - int i; + struct tm *tm; char buf[100]; + int i; g_return_if_fail (yv != NULL); g_return_if_fail (IS_YEAR_VIEW (yv)); - tm = *localtime (&year); + tm = localtime (&year); + yv->year = tm->tm_year + 1900; /* Heading */ - sprintf (buf, "%d", tm.tm_year + 1900); + sprintf (buf, "%d", yv->year); gnome_canvas_item_set (yv->heading, "text", buf, NULL); @@ -246,11 +411,12 @@ year_view_set (YearView *yv, time_t year) for (i = 0; i < 12; i++) gnome_canvas_item_set (yv->mitems[i], - "year", tm.tm_year + 1900, + "year", yv->year, "month", i, NULL); - /* FIXME: update events */ + unmark_days (yv); + mark_days (yv); } void @@ -266,258 +432,5 @@ year_view_time_format_changed (YearView *yv) "start_on_monday", week_starts_on_monday, NULL); - /* FIXME: update events */ -} - - - - - - - - - - - - - - -#if 0 - -#include "gncal-year-view.h" -#include "calendar.h" -#include "timeutil.h" - -static void gncal_year_view_init (GncalYearView *yview); - -static void -double_click(GtkCalendar *gc, GncalYearView *yview) -{ - struct tm tm; - time_t t; - - tm.tm_mday = gc->selected_day; - tm.tm_mon = gc->month; - tm.tm_year = gc->year - 1900; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_isdst = -1; - t = mktime (&tm); - - gnome_calendar_dayjump (yview->gcal, t); + year_view_set (yv, time_year_begin (yv->year)); } - -static void -do_nothing(GtkCalendarClass *c) -{ -} - -static void -select_day(GtkWidget *widget, gpointer data) -{ - int i; - - GncalYearView *yview; - - yview = GNCAL_YEAR_VIEW(data); - - for (i = 0; i < 12; i++) - gtk_signal_handler_block(GTK_OBJECT(yview->calendar[i]), - yview->handler[i]); - - for (i = 0; i < 12; i++) - if (GTK_CALENDAR(yview->calendar[i]) != GTK_CALENDAR(widget)) - gtk_calendar_select_day(GTK_CALENDAR(yview->calendar[i]), 0); - - for (i = 0; i < 12; i++) - gtk_signal_handler_unblock(GTK_OBJECT(yview->calendar[i]), - yview->handler[i]); -} - -guint -gncal_year_view_get_type (void) -{ - static guint year_view_type = 0; - - if (!year_view_type) { - GtkTypeInfo year_view_info = { - "GncalYearView", - sizeof (GncalYearView), - sizeof (GncalYearViewClass), - (GtkClassInitFunc) NULL, - (GtkObjectInitFunc) gncal_year_view_init, - (GtkArgSetFunc) NULL, - (GtkArgGetFunc) NULL - }; - - year_view_type = gtk_type_unique (gtk_table_get_type (), - &year_view_info); - } - - return year_view_type; -} - -static void -gncal_year_view_init (GncalYearView *yview) -{ - int i; - - for (i = 0; i < 12; i++) { - yview->calendar[i] = NULL; - yview->handler [i] = 0; - } - - yview->gcal = NULL; - yview->year_label = NULL; - yview->year = 0; -} - -GtkWidget * -gncal_year_view_new (GnomeCalendar *calendar, time_t date) -{ - struct tm my_tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - char monthbuff[40]; - GncalYearView *yview; - GtkWidget *frame, *vbox, *label; - struct tm *tmptm; - int i, x, y; - - yview = gtk_type_new (gncal_year_view_get_type ()); - - tmptm = localtime(&date); - yview->year = tmptm->tm_year; - yview->gcal = calendar; - my_tm.tm_year = tmptm->tm_year; - yview->year_label = gtk_label_new(""); - gtk_table_attach (GTK_TABLE (yview), - GTK_WIDGET (yview->year_label), - 1, 2, - 0, 1, - 0, 0, 0, 5); - gtk_widget_show(GTK_WIDGET(yview->year_label)); - - for (x = 0; x < 3; x++) - for (y = 0; y < 4; y++) { - - i = y * 3 + x; - - yview->calendar[i] = gtk_calendar_new(); - gtk_calendar_display_options(GTK_CALENDAR(yview->calendar[i]), - GTK_CALENDAR_SHOW_DAY_NAMES | - GTK_CALENDAR_NO_MONTH_CHANGE); - frame = gtk_frame_new(NULL); - vbox = gtk_vbox_new(0,0); - - yview->handler[i] = - gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected", - GTK_SIGNAL_FUNC(select_day), (gpointer *) yview); - - gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected_double_click", - GTK_SIGNAL_FUNC(double_click), (gpointer *) yview); - - my_tm.tm_mon = i; - strftime(monthbuff, 40, "%B", &my_tm); - label = gtk_label_new(monthbuff); - - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0); - gtk_box_pack_start(GTK_BOX(vbox), yview->calendar[i], 0, 0, 0); - - gtk_table_attach (GTK_TABLE (yview), - GTK_WIDGET (frame), - x, x + 1, - y + 1, y + 2, - 0, 0, 0, 0); - - gtk_widget_show (frame); - gtk_widget_show (vbox); - gtk_widget_show (GTK_WIDGET (yview->calendar[i])); - } - - gncal_year_view_set (yview, date); - - return GTK_WIDGET (yview); -} - -static void -year_view_mark_day (iCalObject *ical, time_t start, time_t end, void *closure) -{ - GncalYearView *yview = (GncalYearView *) closure; - struct tm tm_s; - time_t t, day_end; - - tm_s = *localtime (&start); - day_end = time_end_of_day (end); - - for (t = start; t <= day_end; t+= 60*60*24){ - time_t new = mktime (&tm_s); - struct tm tm_day; - - tm_day = *localtime (&new); - gtk_calendar_mark_day (GTK_CALENDAR (yview->calendar [tm_day.tm_mon]), - tm_day.tm_mday); - tm_s.tm_mday++; - } -} - -static void -gncal_year_view_set_year (GncalYearView *yview, int year) -{ - time_t year_begin, year_end; - char buff[20]; - GList *l; - int i; - - if (!yview->gcal->cal) - return; - - snprintf(buff, 20, "%d", yview->year + 1900); - gtk_label_set(GTK_LABEL(yview->year_label), buff); - - for (i = 0; i < 12; i++) { - gtk_calendar_freeze (GTK_CALENDAR (yview->calendar [i])); - gtk_calendar_select_month (GTK_CALENDAR(yview->calendar[i]), i, yview->year + 1900); - gtk_calendar_clear_marks (GTK_CALENDAR (yview->calendar[i])); - } - - year_begin = time_year_begin (yview->year); - year_end = time_year_end (yview->year); - - l = calendar_get_events_in_range (yview->gcal->cal, year_begin, year_end); - for (; l; l = l->next){ - CalendarObject *co = l->data; - - year_view_mark_day (co->ico, co->ev_start, co->ev_end, yview); - } - for (i = 0; i < 12; i++) - gtk_calendar_thaw (GTK_CALENDAR (yview->calendar [i])); - - calendar_destroy_event_list (l); -} - -void -gncal_year_view_set (GncalYearView *yview, time_t date) -{ - struct tm *tmptm; - - tmptm = localtime(&date); - yview->year = tmptm->tm_year; - - gncal_year_view_set_year (yview, yview->year); -} - -void -gncal_year_view_update (GncalYearView *yview, iCalObject *ico, int flags) -{ - g_return_if_fail (yview != NULL); - g_return_if_fail (GNCAL_IS_YEAR_VIEW (yview)); - - /* If only the summary changed, we dont care */ - if (flags && (flags & CHANGE_SUMMARY) == flags) - return; - - gncal_year_view_set_year (yview, yview->year); -} - -#endif |