/* Year view display for gncal * * Copyright (C) 1998 The Free Software Foundation * * Authors: Arturo Espinosa * Federico Mena */ #include #include #include "year-view.h" #include "main.h" #define HEAD_SPACING 4 /* Spacing between year heading and months */ #define TITLE_SPACING 2 /* Spacing between title and calendar */ #define SPACING 4 /* Spacing between months */ static void year_view_class_init (YearViewClass *class); static void year_view_init (YearView *yv); static void year_view_size_request (GtkWidget *widget, GtkRequisition *requisition); static void year_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static GnomeCanvas *parent_class; GtkType year_view_get_type (void) { static GtkType year_view_type = 0; if (!year_view_type) { GtkTypeInfo year_view_info = { "YearView", sizeof (YearView), sizeof (YearViewClass), (GtkClassInitFunc) year_view_class_init, (GtkObjectInitFunc) year_view_init, NULL, /* reserved_1 */ NULL, /* reserved_2 */ (GtkClassInitFunc) NULL }; year_view_type = gtk_type_unique (gnome_canvas_get_type (), &year_view_info); } return year_view_type; } static void year_view_class_init (YearViewClass *class) { GtkWidgetClass *widget_class; widget_class = (GtkWidgetClass *) class; parent_class = gtk_type_class (gnome_canvas_get_type ()); widget_class->size_request = year_view_size_request; widget_class->size_allocate = year_view_size_allocate; } static void year_view_init (YearView *yv) { int i; char buf[100]; struct tm tm; memset (&tm, 0, sizeof (tm)); /* Heading */ yv->heading = gnome_canvas_item_new (GNOME_CANVAS_GROUP (yv->canvas.root), gnome_canvas_text_get_type (), "anchor", GTK_ANCHOR_N, "font", "-*-helvetica-bold-r-normal--14-*-*-*-*-*-iso8859-1", "fill_color", "black", NULL); /* Months */ for (i = 0; i < 12; i++) { /* Title */ strftime (buf, 100, "%B", &tm); tm.tm_mon++; yv->titles[i] = gnome_canvas_item_new (GNOME_CANVAS_GROUP (yv->canvas.root), gnome_canvas_text_get_type (), "text", buf, "anchor", GTK_ANCHOR_N, "font", "-*-helvetica-bold-r-normal--12-*-*-*-*-*-iso8859-1", "fill_color", "black", NULL); /* Month item */ yv->mitems[i] = gnome_month_item_new (GNOME_CANVAS_GROUP (yv->canvas.root)); gnome_canvas_item_set (yv->mitems[i], "anchor", GTK_ANCHOR_NW, "start_on_monday", week_starts_on_monday, "heading_color", "white", NULL); } } GtkWidget * year_view_new (GnomeCalendar *calendar, time_t year) { YearView *yv; g_return_val_if_fail (calendar != NULL, NULL); g_return_val_if_fail (GNOME_IS_CALENDAR (calendar), NULL); yv = gtk_type_new (year_view_get_type ()); yv->calendar = calendar; year_view_set (yv, year); return GTK_WIDGET (yv); } static void year_view_size_request (GtkWidget *widget, GtkRequisition *requisition) { YearView *yv; g_return_if_fail (widget != NULL); g_return_if_fail (IS_YEAR_VIEW (widget)); g_return_if_fail (requisition != NULL); yv = YEAR_VIEW (widget); if (GTK_WIDGET_CLASS (parent_class)->size_request) (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition); requisition->width = 200; requisition->height = 150; } 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)); g_return_if_fail (allocation != NULL); yv = YEAR_VIEW (widget); if (GTK_WIDGET_CLASS (parent_class)->size_allocate) (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); gnome_canvas_set_scroll_region (GNOME_CANVAS (yv), 0, 0, allocation->width, allocation->height); 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) allocation->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 = (allocation->width + SPACING) / 3.0; height = (allocation->height - h_yofs + SPACING) / 4.0; mwidth = (allocation->width - 2 * SPACING) / 3.0; mheight = (allocation->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); } } void year_view_update (YearView *yv, iCalObject *object, int flags) { g_return_if_fail (yv != NULL); g_return_if_fail (IS_YEAR_VIEW (yv)); /* FIXME */ } void year_view_set (YearView *yv, time_t year) { struct tm tm; int i; char buf[100]; g_return_if_fail (yv != NULL); g_return_if_fail (IS_YEAR_VIEW (yv)); tm = *localtime (&year); /* Heading */ sprintf (buf, "%d", tm.tm_year + 1900); gnome_canvas_item_set (yv->heading, "text", buf, NULL); /* Months */ for (i = 0; i < 12; i++) gnome_canvas_item_set (yv->mitems[i], "year", tm.tm_year + 1900, "month", i, NULL); /* FIXME: update events */ } void year_view_time_format_changed (YearView *yv) { int i; g_return_if_fail (yv != NULL); g_return_if_fail (IS_YEAR_VIEW (yv)); for (i = 0; i < 12; i++) gnome_canvas_item_set (yv->mitems[i], "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); } 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