aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/calendar-commands.c75
-rw-r--r--calendar/gui/e-day-view-main-item.c45
-rw-r--r--calendar/gui/e-day-view.c406
-rw-r--r--calendar/gui/e-day-view.h54
-rw-r--r--calendar/gui/e-week-view-main-item.c12
-rw-r--r--calendar/gui/e-week-view.c363
-rw-r--r--calendar/gui/e-week-view.h57
-rw-r--r--calendar/gui/gnome-cal.c731
-rw-r--r--calendar/gui/gnome-cal.h89
9 files changed, 1315 insertions, 517 deletions
diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c
index 564512dfe4..e5e04dbf8b 100644
--- a/calendar/gui/calendar-commands.c
+++ b/calendar/gui/calendar-commands.c
@@ -28,11 +28,11 @@
#include "workweekview.xpm"
#include "weekview.xpm"
#include "monthview.xpm"
-
#if 0
#include "yearview.xpm"
#endif
+
/* The username, used to set the `owner' field of the event */
char *user_name;
@@ -322,7 +322,12 @@ static void
show_day_view_clicked (BonoboUIHandler *uih, void *user_data, const char *path)
{
GnomeCalendar *gcal = GNOME_CALENDAR (user_data);
- gnome_calendar_set_view (gcal, "dayview");
+
+ /* If we are setting up a view internally we just ignore the clicks. */
+ if (gcal->ignore_view_button_clicks)
+ return;
+
+ gnome_calendar_set_view (gcal, "dayview", FALSE);
gtk_widget_grab_focus (gcal->day_view);
}
@@ -330,7 +335,12 @@ static void
show_work_week_view_clicked (BonoboUIHandler *uih, void *user_data, const char *path)
{
GnomeCalendar *gcal = GNOME_CALENDAR (user_data);
- gnome_calendar_set_view (gcal, "workweekview");
+
+ /* If we are setting up a view internally we just ignore the clicks. */
+ if (gcal->ignore_view_button_clicks)
+ return;
+
+ gnome_calendar_set_view (gcal, "workweekview", FALSE);
gtk_widget_grab_focus (gcal->work_week_view);
}
@@ -338,7 +348,12 @@ static void
show_week_view_clicked (BonoboUIHandler *uih, void *user_data, const char *path)
{
GnomeCalendar *gcal = GNOME_CALENDAR (user_data);
- gnome_calendar_set_view (gcal, "weekview");
+
+ /* If we are setting up a view internally we just ignore the clicks. */
+ if (gcal->ignore_view_button_clicks)
+ return;
+
+ gnome_calendar_set_view (gcal, "weekview", FALSE);
gtk_widget_grab_focus (gcal->week_view);
}
@@ -346,19 +361,15 @@ static void
show_month_view_clicked (BonoboUIHandler *uih, void *user_data, const char *path)
{
GnomeCalendar *gcal = GNOME_CALENDAR (user_data);
- gnome_calendar_set_view (gcal, "monthview");
+
+ /* If we are setting up a view internally we just ignore the clicks. */
+ if (gcal->ignore_view_button_clicks)
+ return;
+
+ gnome_calendar_set_view (gcal, "monthview", FALSE);
gtk_widget_grab_focus (gcal->month_view);
}
-#if 0
-static void
-show_year_view_clicked (BonoboUIHandler *uih, void *user_data, const char *path)
-{
- GnomeCalendar *gcal = GNOME_CALENDAR (user_data);
- gnome_calendar_set_view (gcal, "yearview");
- gtk_widget_grab_focus (gcal->year_view);
-}
-#endif
static void
new_calendar_cmd (BonoboUIHandler *uih, void *user_data, const char *path)
@@ -487,6 +498,8 @@ properties_cmd (BonoboUIHandler *uih, void *user_data, const char *path)
}
+/* Note: if the order of these is changed, make sure you change the indices
+ used to access the widgets in calendar_control_activate(). */
static GnomeUIInfo gnome_toolbar_view_buttons [] = {
GNOMEUIINFO_RADIOITEM (N_("Day"), N_("Show 1 day"),
show_day_view_clicked,
@@ -564,8 +577,6 @@ calendar_control_activate (BonoboControl *control,
BonoboControl *toolbar_control;
GnomeUIBuilderData uibdata;
BonoboUIHandler *uih;
- gchar *page_name;
- gint button, i;
int behavior;
uih = bonobo_control_get_ui_handler (control);
@@ -591,30 +602,15 @@ calendar_control_activate (BonoboControl *control,
/*gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));*/
- for (i = 0; i < GNOME_CALENDAR_NUM_VIEWS; i++)
- cal->view_toolbar_buttons[i] = gnome_toolbar_view_buttons[i].widget;
-
/* Note that these indices should correspond with the button indices
- in gnome_toolbar_view_buttons. */
- page_name = gnome_calendar_get_current_view_name (cal);
- if (!strcmp (page_name, "dayview")) {
- button = 0;
- } else if (!strcmp (page_name, "workweekview")) {
- button = 1;
- } else if (!strcmp (page_name, "weekview")) {
- button = 2;
- } else if (!strcmp (page_name, "monthview")) {
- button = 3;
-#if 0
- } else if (!strcmp (page_name, "yearview")) {
- button = 4;
-#endif
- } else {
- g_warning ("Unknown calendar view: %s", page_name);
- button = 0;
- }
+ in the gnome_toolbar_view_buttons UIINFO struct. */
+ cal->day_button = gnome_toolbar_view_buttons[0].widget;
+ cal->work_week_button = gnome_toolbar_view_buttons[1].widget;
+ cal->week_button = gnome_toolbar_view_buttons[2].widget;
+ cal->month_button = gnome_toolbar_view_buttons[3].widget;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cal->view_toolbar_buttons[button]), TRUE);
+ /* This makes the appropriate radio button in the toolbar active. */
+ gnome_calendar_update_view_buttons (cal);
gtk_widget_show_all (toolbar);
@@ -730,7 +726,8 @@ new_calendar (char *full_name, char *geometry, char *page, gboolean hidden)
}
if (page)
- gnome_calendar_set_view (GNOME_CALENDAR (toplevel), page);
+ gnome_calendar_set_view (GNOME_CALENDAR (toplevel), page,
+ FALSE);
gtk_signal_connect (GTK_OBJECT (toplevel), "delete_event",
GTK_SIGNAL_FUNC(calendar_close_event), toplevel);
diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c
index 8353c0497e..7b2449b7bf 100644
--- a/calendar/gui/e-day-view-main-item.c
+++ b/calendar/gui/e-day-view-main-item.c
@@ -187,8 +187,9 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
gint day, grid_y1, grid_y2;
gint work_day_start_row, work_day_end_row;
gint work_day_start_y, work_day_end_y;
- gint work_day_x, work_day_w;
+ gint day_x, day_w, work_day;
gint start_row, end_row, rect_x, rect_y, rect_width, rect_height;
+ struct tm *day_start;
#if 0
g_print ("In e_day_view_main_item_draw %i,%i %ix%i\n",
@@ -212,20 +213,34 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
work_day_end_row = e_day_view_convert_time_to_row (day_view, day_view->work_day_end_hour, day_view->work_day_end_minute);
work_day_end_y = work_day_end_row * day_view->row_height - y;
- work_day_x = day_view->day_offsets[0] - x;
- work_day_w = width - work_day_x;
- gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
- gdk_draw_rectangle (drawable, gc, TRUE,
- work_day_x, 0 - y,
- work_day_w, work_day_start_y - (0 - y));
- gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING]);
- gdk_draw_rectangle (drawable, gc, TRUE,
- work_day_x, work_day_start_y,
- work_day_w, work_day_end_y - work_day_start_y);
- gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
- gdk_draw_rectangle (drawable, gc, TRUE,
- work_day_x, work_day_end_y,
- work_day_w, height - work_day_end_y);
+ for (day = 0; day < day_view->days_shown; day++) {
+ day_start = localtime (&day_view->day_starts[day]);
+
+ work_day = day_view->working_days & (1 << day_start->tm_wday);
+
+ day_x = day_view->day_offsets[day] - x;
+ day_w = day_view->day_widths[day];
+
+ if (work_day) {
+ gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
+ gdk_draw_rectangle (drawable, gc, TRUE,
+ day_x, 0 - y,
+ day_w, work_day_start_y - (0 - y));
+ gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING]);
+ gdk_draw_rectangle (drawable, gc, TRUE,
+ day_x, work_day_start_y,
+ day_w, work_day_end_y - work_day_start_y);
+ gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
+ gdk_draw_rectangle (drawable, gc, TRUE,
+ day_x, work_day_end_y,
+ day_w, height - work_day_end_y);
+ } else {
+ gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]);
+ gdk_draw_rectangle (drawable, gc, TRUE,
+ day_x, 0,
+ day_w, height);
+ }
+ }
/* Paint the selection background. */
if (GTK_WIDGET_HAS_FOCUS (day_view)
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 1767624627..32d9380bb5 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -194,6 +194,7 @@ static void e_day_view_on_event_right_click (EDayView *day_view,
static void e_day_view_recalc_day_starts (EDayView *day_view,
time_t start_time);
static void e_day_view_recalc_num_rows (EDayView *day_view);
+static void e_day_view_recalc_cell_sizes (EDayView *day_view);
static EDayViewPosition e_day_view_convert_position_in_top_canvas (EDayView *day_view,
gint x,
@@ -225,6 +226,8 @@ static void e_day_view_foreach_event_with_uid (EDayView *day_view,
EDayViewForeachEventCallback callback,
gpointer data);
+static void e_day_view_queue_reload_events (EDayView *day_view);
+static gboolean e_day_view_reload_events_idle_cb (gpointer data);
static void e_day_view_reload_events (EDayView *day_view);
static void e_day_view_free_events (EDayView *day_view);
static void e_day_view_free_event_array (EDayView *day_view,
@@ -432,15 +435,11 @@ e_day_view_class_init (EDayViewClass *class)
static void
e_day_view_init (EDayView *day_view)
{
- GdkColormap *colormap;
- gboolean success[E_DAY_VIEW_COLOR_LAST];
- gint day, nfailed;
+ gint day;
GnomeCanvasGroup *canvas_group;
GTK_WIDGET_SET_FLAGS (day_view, GTK_CAN_FOCUS);
- colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view));
-
day_view->calendar = NULL;
day_view->client = NULL;
@@ -449,6 +448,7 @@ e_day_view_init (EDayView *day_view)
day_view->long_events_sorted = TRUE;
day_view->long_events_need_layout = FALSE;
day_view->long_events_need_reshape = FALSE;
+ day_view->reload_events_idle_id = 0;
for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) {
day_view->events[day] = g_array_new (FALSE, FALSE,
@@ -463,6 +463,7 @@ e_day_view_init (EDayView *day_view)
day_view->upper = 0;
/* FIXME: Initialize day_starts. */
+ day_view->work_week_view = FALSE;
day_view->days_shown = 1;
day_view->mins_per_row = 30;
@@ -480,6 +481,10 @@ e_day_view_init (EDayView *day_view)
day_view->main_gc = NULL;
e_day_view_recalc_num_rows (day_view);
+ day_view->working_days = E_DAY_VIEW_MONDAY | E_DAY_VIEW_TUESDAY
+ | E_DAY_VIEW_WEDNESDAY | E_DAY_VIEW_THURSDAY
+ | E_DAY_VIEW_FRIDAY;
+
day_view->work_day_start_hour = 9;
day_view->work_day_start_minute = 0;
day_view->work_day_end_hour = 17;
@@ -518,48 +523,6 @@ e_day_view_init (EDayView *day_view)
g_warning ("Couldn't load font");
- /* Allocate the colors. */
-#if 1
- day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].red = 247 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].green = 247 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].blue = 244 * 257;
-
- day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].red = 216 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].green = 216 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].blue = 214 * 257;
-#else
-
- /* FG: MistyRose1, LightPink3 | RosyBrown | MistyRose3. */
-
- day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].red = 255 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].green = 228 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].blue = 225 * 257;
-
- day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].red = 238 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].green = 162 * 257;
- day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].blue = 173 * 257;
-#endif
-
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].red = 0;
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].green = 0;
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].blue = 65535;
-
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].red = 65535;
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].green = 65535;
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].blue = 65535;
-
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].red = 0;
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].green = 0;
- day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].blue = 0;
-
- nfailed = gdk_colormap_alloc_colors (colormap, day_view->colors,
- E_DAY_VIEW_COLOR_LAST, FALSE,
- TRUE, success);
- if (nfailed)
- g_warning ("Failed to allocate all colors");
-
-
-
/*
* Top Canvas
*/
@@ -612,8 +575,6 @@ e_day_view_init (EDayView *day_view)
day_view->resize_long_event_rect_item =
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type(),
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->resize_long_event_rect_item);
@@ -621,8 +582,6 @@ e_day_view_init (EDayView *day_view)
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type (),
"width_pixels", 1,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->drag_long_event_rect_item);
@@ -696,16 +655,12 @@ e_day_view_init (EDayView *day_view)
day_view->resize_rect_item =
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type(),
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->resize_rect_item);
day_view->resize_bar_item =
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type(),
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->resize_bar_item);
@@ -713,8 +668,6 @@ e_day_view_init (EDayView *day_view)
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type (),
"width_pixels", 1,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item);
@@ -722,8 +675,6 @@ e_day_view_init (EDayView *day_view)
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type (),
"width_pixels", 1,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item);
@@ -732,8 +683,6 @@ e_day_view_init (EDayView *day_view)
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type (),
"width_pixels", 1,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->drag_rect_item);
@@ -741,8 +690,6 @@ e_day_view_init (EDayView *day_view)
gnome_canvas_item_new (canvas_group,
gnome_canvas_rect_get_type (),
"width_pixels", 1,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
NULL);
gnome_canvas_item_hide (day_view->drag_bar_item);
@@ -790,11 +737,6 @@ e_day_view_init (EDayView *day_view)
gtk_widget_show (day_view->vscrollbar);
- /* Create the pixmaps. */
- day_view->reminder_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->reminder_mask, NULL, bell_xpm);
- day_view->recurrence_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->recurrence_mask, NULL, recur_xpm);
-
-
/* Create the cursors. */
day_view->normal_cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
day_view->move_cursor = gdk_cursor_new (GDK_FLEUR);
@@ -851,14 +793,19 @@ e_day_view_destroy (GtkObject *object)
day_view = E_DAY_VIEW (object);
+ e_day_view_stop_auto_scroll (day_view);
+
+ if (day_view->reload_events_idle_id != 0) {
+ g_source_remove (day_view->reload_events_idle_id);
+ day_view->reload_events_idle_id = 0;
+ }
+
if (day_view->client) {
gtk_signal_disconnect_by_data (GTK_OBJECT (day_view->client), day_view);
gtk_object_unref (GTK_OBJECT (day_view->client));
day_view->client = NULL;
}
- e_day_view_stop_auto_scroll (day_view);
-
if (day_view->large_font)
gdk_font_unref (day_view->large_font);
@@ -880,12 +827,104 @@ static void
e_day_view_realize (GtkWidget *widget)
{
EDayView *day_view;
+ GdkColormap *colormap;
+ gboolean success[E_DAY_VIEW_COLOR_LAST];
+ gint nfailed;
if (GTK_WIDGET_CLASS (parent_class)->realize)
(*GTK_WIDGET_CLASS (parent_class)->realize)(widget);
day_view = E_DAY_VIEW (widget);
day_view->main_gc = gdk_gc_new (widget->window);
+
+ colormap = gtk_widget_get_colormap (widget);
+
+ /* Allocate the colors. */
+ day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].red = 247 * 257;
+ day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].green = 247 * 257;
+ day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].blue = 244 * 257;
+
+ day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].red = 216 * 257;
+ day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].green = 216 * 257;
+ day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].blue = 214 * 257;
+
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].red = 0;
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].green = 0;
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].blue = 65535;
+
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].red = 65535;
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].green = 65535;
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].blue = 65535;
+
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].red = 0;
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].green = 0;
+ day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].blue = 0;
+
+ nfailed = gdk_colormap_alloc_colors (colormap, day_view->colors,
+ E_DAY_VIEW_COLOR_LAST, FALSE,
+ TRUE, success);
+ if (nfailed)
+ g_warning ("Failed to allocate all colors");
+
+
+ /* Create the pixmaps. */
+ day_view->reminder_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->reminder_mask, NULL, bell_xpm);
+ day_view->recurrence_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->recurrence_mask, NULL, recur_xpm);
+
+
+
+ /* Set the canvas item colors. */
+ gnome_canvas_item_set (day_view->resize_long_event_rect_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+ gnome_canvas_item_set (day_view->drag_long_event_rect_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+
+ gnome_canvas_item_set (day_view->resize_rect_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+ gnome_canvas_item_set (day_view->resize_bar_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+ gnome_canvas_item_set (day_view->main_canvas_top_resize_bar_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+ gnome_canvas_item_set (day_view->main_canvas_bottom_resize_bar_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+
+ gnome_canvas_item_set (day_view->drag_rect_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+ gnome_canvas_item_set (day_view->drag_bar_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+
+
+ /* Set the fonts for the text items used when dragging. */
+ gnome_canvas_item_set (day_view->drag_long_event_item,
+ "font_gdk", GTK_WIDGET (day_view)->style->font,
+ NULL);
+
+ gnome_canvas_item_set (day_view->drag_item,
+ "font_gdk", GTK_WIDGET (day_view)->style->font,
+ NULL);
}
@@ -893,12 +932,23 @@ static void
e_day_view_unrealize (GtkWidget *widget)
{
EDayView *day_view;
+ GdkColormap *colormap;
+ gint i;
day_view = E_DAY_VIEW (widget);
gdk_gc_unref (day_view->main_gc);
day_view->main_gc = NULL;
+ colormap = gtk_widget_get_colormap (widget);
+ for (i = 0; i < E_DAY_VIEW_COLOR_LAST; i++)
+ gdk_colors_free (colormap, &day_view->colors[i].pixel, 1, 0);
+
+ gdk_pixmap_unref (day_view->reminder_icon);
+ day_view->reminder_icon = NULL;
+ gdk_pixmap_unref (day_view->recurrence_icon);
+ day_view->recurrence_icon = NULL;
+
if (GTK_WIDGET_CLASS (parent_class)->unrealize)
(*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget);
}
@@ -992,8 +1042,7 @@ static void
e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
{
EDayView *day_view;
- gfloat width, offset;
- gint col, day, scroll_y;
+ gint day, scroll_y;
gboolean need_reshape;
gdouble old_x2, old_y2, new_x2, new_y2;
@@ -1004,29 +1053,7 @@ e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
(*GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
- /* Calculate the column sizes, using floating point so that pixels
- get divided evenly. Note that we use one more element than the
- number of columns, to make it easy to get the column widths. */
- width = day_view->main_canvas->allocation.width;
- width /= day_view->days_shown;
- offset = 0;
- for (col = 0; col <= day_view->days_shown; col++) {
- day_view->day_offsets[col] = floor (offset + 0.5);
- offset += width;
- }
-
- /* Calculate the days widths based on the offsets. */
- for (col = 0; col < day_view->days_shown; col++) {
- day_view->day_widths[col] = day_view->day_offsets[col + 1] - day_view->day_offsets[col];
- }
-
- /* Determine which date format to use, based on the column widths. */
- if (day_view->day_widths[0] > day_view->long_format_width)
- day_view->date_format = E_DAY_VIEW_DATE_FULL;
- else if (day_view->day_widths[0] > day_view->abbreviated_format_width)
- day_view->date_format = E_DAY_VIEW_DATE_ABBREVIATED;
- else
- day_view->date_format = E_DAY_VIEW_DATE_SHORT;
+ e_day_view_recalc_cell_sizes (day_view);
/* Set the scroll region of the top canvas to its allocated size. */
gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->top_canvas),
@@ -1060,6 +1087,38 @@ e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
}
+static void
+e_day_view_recalc_cell_sizes (EDayView *day_view)
+{
+ gfloat width, offset;
+ gint day;
+
+ /* Calculate the column sizes, using floating point so that pixels
+ get divided evenly. Note that we use one more element than the
+ number of columns, to make it easy to get the column widths. */
+ width = day_view->main_canvas->allocation.width;
+ width /= day_view->days_shown;
+ offset = 0;
+ for (day = 0; day <= day_view->days_shown; day++) {
+ day_view->day_offsets[day] = floor (offset + 0.5);
+ offset += width;
+ }
+
+ /* Calculate the days widths based on the offsets. */
+ for (day = 0; day < day_view->days_shown; day++) {
+ day_view->day_widths[day] = day_view->day_offsets[day + 1] - day_view->day_offsets[day];
+ }
+
+ /* Determine which date format to use, based on the column widths. */
+ if (day_view->day_widths[0] > day_view->long_format_width)
+ day_view->date_format = E_DAY_VIEW_DATE_FULL;
+ else if (day_view->day_widths[0] > day_view->abbreviated_format_width)
+ day_view->date_format = E_DAY_VIEW_DATE_ABBREVIATED;
+ else
+ day_view->date_format = E_DAY_VIEW_DATE_SHORT;
+}
+
+
static gint
e_day_view_focus_in (GtkWidget *widget, GdkEventFocus *event)
{
@@ -1123,7 +1182,7 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
if (status != CAL_CLIENT_LOAD_SUCCESS)
return;
- e_day_view_reload_events (day_view);
+ e_day_view_queue_reload_events (day_view);
}
/* Callback used when the calendar client tells us that an object changed */
@@ -1136,6 +1195,8 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
CalClientGetStatus status;
gint day, event_num;
+ g_return_if_fail (E_IS_DAY_VIEW (data));
+
day_view = E_DAY_VIEW (data);
/* If our time hasn't been set yet, just return. */
@@ -1182,6 +1243,20 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
#ifndef NO_WARNINGS
#warning "FIX ME"
#endif
+
+ /* If we are editing an event which we have just created, we
+ will get an update_event callback from the server. But we
+ need to ignore it or we will lose the text the user has
+ already typed in. */
+ if (day_view->editing_new_event
+ && day_view->editing_event_day == day
+ && day_view->editing_event_num == event_num) {
+ gtk_object_unref (GTK_OBJECT (event->comp));
+ event->comp = comp; /* Takes over ref count. */
+ return;
+ }
+
+
/* Do this the long way every time for now */
#if 0
if (ical_object_compare_dates (event->ico, ico)) {
@@ -1429,7 +1504,7 @@ e_day_view_update_event_label (EDayView *day_view,
return;
cal_component_get_summary (event->comp, &summary);
- text = summary.value ? (char *) summary.value : "";
+ text = summary.value ? (char*) summary.value : "";
if (day_view->editing_event_day == day
&& day_view->editing_event_num == event_num)
@@ -1591,9 +1666,9 @@ e_day_view_set_selected_time_range (EDayView *day_view,
and the days_shown setting. If we are showing 1 day it is just the
start of the day given by start_time, otherwise it is the previous
Monday. */
- if (day_view->days_shown == 1)
+ if (!day_view->work_week_view) {
lower = time_day_begin (start_time);
- else {
+ } else {
g_date_clear (&date, 1);
g_date_set_time (&date, start_time);
g_date_subtract_days (&date, g_date_weekday (&date) - 1);
@@ -1605,8 +1680,7 @@ e_day_view_set_selected_time_range (EDayView *day_view,
/* See if we need to change the days shown. */
if (lower != day_view->lower) {
e_day_view_recalc_day_starts (day_view, lower);
- e_day_view_reload_events (day_view);
- need_redraw = TRUE;
+ e_day_view_queue_reload_events (day_view);
}
/* Set the selection. */
@@ -1710,6 +1784,32 @@ e_day_view_recalc_day_starts (EDayView *day_view,
}
+/* Whether we are displaying a work-week, in which case the display always
+ starts on the first day of the working week. */
+gboolean
+e_day_view_get_work_week_view (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), FALSE);
+
+ return day_view->work_week_view;
+}
+
+
+void
+e_day_view_set_work_week_view (EDayView *day_view,
+ gboolean work_week_view)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ if (day_view->work_week_view == work_week_view)
+ return;
+
+ day_view->work_week_view = work_week_view;
+
+ /* FIXME: need to recalc the first day shown if now work-week view. */
+}
+
+
gint
e_day_view_get_days_shown (EDayView *day_view)
{
@@ -1729,8 +1829,9 @@ e_day_view_set_days_shown (EDayView *day_view,
if (day_view->days_shown != days_shown) {
day_view->days_shown = days_shown;
-
- /* FIXME: Update everything. */
+ e_day_view_recalc_day_starts (day_view, day_view->lower);
+ e_day_view_recalc_cell_sizes (day_view);
+ e_day_view_queue_reload_events (day_view);
}
}
@@ -1781,6 +1882,30 @@ e_day_view_set_mins_per_row (EDayView *day_view,
}
+/* This specifies the working days in the week. The value is a bitwise
+ combination of day flags. Defaults to Mon-Fri. */
+EDayViewDays
+e_day_view_get_working_days (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0);
+
+ return day_view->working_days;
+}
+
+
+void
+e_day_view_set_working_days (EDayView *day_view,
+ EDayViewDays days)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ if (day_view->working_days != days) {
+ day_view->working_days = days;
+ gtk_widget_queue_draw (day_view->main_canvas);
+ }
+}
+
+
static gboolean
e_day_view_update_scroll_regions (EDayView *day_view)
{
@@ -2583,6 +2708,8 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data)
the start & end times to the instances times. */
new_comp = cal_component_clone (event->comp);
cal_component_set_uid (new_comp, cal_component_gen_uid ());
+ cal_component_set_rdate_list (new_comp, NULL);
+ cal_component_set_rrule_list (new_comp, NULL);
cal_component_set_exdate_list (new_comp, NULL);
cal_component_set_exrule_list (new_comp, NULL);
@@ -3218,18 +3345,46 @@ e_day_view_abort_resize (EDayView *day_view,
}
+/* This frees any events currently loaded, and queues a reload. */
static void
-e_day_view_reload_events (EDayView *day_view)
+e_day_view_queue_reload_events (EDayView *day_view)
{
e_day_view_free_events (day_view);
- /* Reset all our indices. */
- day_view->editing_event_day = -1;
- day_view->popup_event_day = -1;
- day_view->resize_bars_event_day = -1;
- day_view->resize_event_day = -1;
- day_view->pressed_event_day = -1;
- day_view->drag_event_day = -1;
+ if (day_view->reload_events_idle_id == 0) {
+ /* We'll use a high idle priority here, so the events are
+ reloaded before the canvas is updated. */
+ day_view->reload_events_idle_id = g_idle_add_full
+ (G_PRIORITY_HIGH_IDLE,
+ e_day_view_reload_events_idle_cb, day_view, NULL);
+ }
+}
+
+
+static gboolean
+e_day_view_reload_events_idle_cb (gpointer data)
+{
+ EDayView *day_view;
+
+ g_return_val_if_fail (E_IS_DAY_VIEW (data), FALSE);
+
+ GDK_THREADS_ENTER ();
+
+ day_view = E_DAY_VIEW (data);
+
+ day_view->reload_events_idle_id = 0;
+
+ e_day_view_reload_events (day_view);
+
+ GDK_THREADS_LEAVE ();
+ return FALSE;
+}
+
+
+static void
+e_day_view_reload_events (EDayView *day_view)
+{
+ e_day_view_free_events (day_view);
if (!(day_view->client && cal_client_is_loaded (day_view->client)))
return;
@@ -3262,6 +3417,14 @@ e_day_view_free_events (EDayView *day_view)
{
gint day;
+ /* Reset all our indices. */
+ day_view->editing_event_day = -1;
+ day_view->popup_event_day = -1;
+ day_view->resize_bars_event_day = -1;
+ day_view->resize_event_day = -1;
+ day_view->pressed_event_day = -1;
+ day_view->drag_event_day = -1;
+
e_day_view_free_event_array (day_view, day_view->long_events);
for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++)
@@ -4475,6 +4638,8 @@ e_day_view_start_editing_event (EDayView *day_view,
ETextEventProcessor *event_processor = NULL;
ETextEventProcessorCommand command;
+ g_print ("In e_day_view_start_editing_event\n");
+
/* If we are already editing the event, just return. */
if (day == day_view->editing_event_day
&& event_num == day_view->editing_event_num)
@@ -4492,6 +4657,8 @@ e_day_view_start_editing_event (EDayView *day_view,
if (!event->canvas_item)
return;
+ g_print ("In e_day_view_start_editing_event 2\n");
+
/* We must grab the focus before setting the initial text, since
grabbing the focus will result in a call to
e_day_view_on_editing_started(), which will reset the text to get
@@ -4586,7 +4753,7 @@ e_day_view_on_editing_started (EDayView *day_view,
&day, &event_num))
return;
-#if 0
+#if 1
g_print ("In e_day_view_on_editing_started Day:%i Event:%i\n",
day, event_num);
#endif
@@ -4629,6 +4796,9 @@ e_day_view_on_editing_stopped (EDayView *day_view,
day = day_view->editing_event_day;
event_num = day_view->editing_event_num;
+ g_print ("In e_day_view_on_editing_stopped Day:%i Event:%i\n",
+ day, event_num);
+
/* If no item is being edited, just return. */
if (day == -1)
return;
@@ -5249,9 +5419,9 @@ e_day_view_update_top_canvas_drag (EDayView *day_view,
"clip_width", item_w - (E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD) * 2,
"clip_height", item_h - (E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD) * 2,
NULL);
- e_canvas_item_move_absolute(day_view->drag_long_event_item,
- item_x + E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD,
- item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD);
+ e_canvas_item_move_absolute (day_view->drag_long_event_item,
+ item_x + E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD,
+ item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD);
if (!(day_view->drag_long_event_rect_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) {
gnome_canvas_item_raise_to_top (day_view->drag_long_event_rect_item);
@@ -5407,9 +5577,9 @@ e_day_view_update_main_canvas_drag (EDayView *day_view,
"clip_width", item_w - E_DAY_VIEW_BAR_WIDTH - E_DAY_VIEW_EVENT_X_PAD * 2,
"clip_height", item_h - (E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD) * 2,
NULL);
- e_canvas_item_move_absolute(event->canvas_item,
- item_x + E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_EVENT_X_PAD,
- item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD);
+ e_canvas_item_move_absolute (day_view->drag_item,
+ item_x + E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_EVENT_X_PAD,
+ item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD);
if (!(day_view->drag_bar_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) {
gnome_canvas_item_raise_to_top (day_view->drag_bar_item);
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index 379699accd..cfd11b057c 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -38,8 +38,9 @@ extern "C" {
* EDayView - displays the Day & Work-Week views of the calendar.
*/
-/* The maximum number of days shown. We use 7 since we only show 1 week max. */
-#define E_DAY_VIEW_MAX_DAYS 7
+/* The maximum number of days shown. We use the week view for anything more
+ than about 9 days. */
+#define E_DAY_VIEW_MAX_DAYS 10
/* This is used as a special code to signify a long event instead of the day
of a normal event. */
@@ -90,6 +91,21 @@ extern "C" {
#define E_DAY_VIEW_TOP_CANVAS_Y_GAP 2
+/* These are used to get/set the working days in the week. The bit-flags are
+ combined together. The bits must be from 0 (Sun) to 6 (Sat) to match the
+ day values used by localtime etc. */
+typedef enum
+{
+ E_DAY_VIEW_SUNDAY = 1 << 0,
+ E_DAY_VIEW_MONDAY = 1 << 1,
+ E_DAY_VIEW_TUESDAY = 1 << 2,
+ E_DAY_VIEW_WEDNESDAY = 1 << 3,
+ E_DAY_VIEW_THURSDAY = 1 << 4,
+ E_DAY_VIEW_FRIDAY = 1 << 5,
+ E_DAY_VIEW_SATURDAY = 1 << 6
+} EDayViewDays;
+
+
/* These are used to specify the type of an appointment. They match those
used in EMeetingTimeSelector. */
typedef enum
@@ -195,7 +211,12 @@ struct _EDayView
time_t lower;
time_t upper;
- /* The number of days we are showing. Usually 1 or 5. Maybe 6 or 7. */
+ /* Whether we are showing the work-week view. */
+ gboolean work_week_view;
+
+ /* The number of days we are showing. Usually 1 or 5, but can be up
+ to E_DAY_VIEW_MAX_DAYS, e.g. when the user selects a range of
+ days in the mini calendar. */
gint days_shown;
/* The start of each day & an extra element to hold the last time. */
@@ -221,6 +242,9 @@ struct _EDayView
gboolean long_events_need_reshape;
gboolean need_reshape[E_DAY_VIEW_MAX_DAYS];
+ /* The id of our idle function to reload all events. */
+ gint reload_events_idle_id;
+
/* The number of minutes per row. 5, 10, 15, 30 or 60. */
gint mins_per_row;
@@ -244,6 +268,9 @@ struct _EDayView
gint last_hour_shown;
gint last_minute_shown;
+ /* Bitwise combination of working days. Defaults to Mon-Fri. */
+ EDayViewDays working_days;
+
/* The start and end of the work day, rounded to the nearest row. */
gint work_day_start_hour;
gint work_day_start_minute;
@@ -433,6 +460,21 @@ void e_day_view_get_selected_time_range (EDayView *day_view,
time_t *start_time,
time_t *end_time);
+/* This is called when one event has been added or updated. */
+void e_day_view_update_event (EDayView *day_view,
+ const gchar *uid);
+
+/* This removes all the events associated with the given uid. Note that for
+ recurring events there may be more than one. If any events are found and
+ removed we need to layout the events again. */
+void e_day_view_remove_event (EDayView *day_view,
+ const gchar *uid);
+
+/* Whether we are displaying a work-week, in which case the display always
+ starts on the first day of the working week. */
+gboolean e_day_view_get_work_week_view (EDayView *day_view);
+void e_day_view_set_work_week_view (EDayView *day_view,
+ gboolean work_week_view);
/* The number of days shown in the EDayView, from 1 to 7. This is normally
either 1 or 5 (for the Work-Week view). */
@@ -446,6 +488,12 @@ gint e_day_view_get_mins_per_row (EDayView *day_view);
void e_day_view_set_mins_per_row (EDayView *day_view,
gint mins_per_row);
+/* This specifies the working days in the week. The value is a bitwise
+ combination of day flags. Defaults to Mon-Fri. */
+EDayViewDays e_day_view_get_working_days (EDayView *day_view);
+void e_day_view_set_working_days (EDayView *day_view,
+ EDayViewDays days);
+
/*
diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c
index 49c2ca3d7d..d30404305d 100644
--- a/calendar/gui/e-week-view-main-item.c
+++ b/calendar/gui/e-week-view-main-item.c
@@ -193,7 +193,7 @@ e_week_view_main_item_draw (GnomeCanvasItem *canvas_item,
if (!g_date_valid (&date))
g_date_set_dmy (&date, 27, 12, 1999);
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
for (day = 0; day < num_days; day++) {
e_week_view_get_day_position (week_view, day,
&day_x, &day_y,
@@ -246,6 +246,8 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem,
selected_bg_gc = style->bg_gc[GTK_STATE_SELECTED];
gc = week_view->main_gc;
+ g_return_if_fail (gc != NULL);
+
month = g_date_month (date);
day_of_month = g_date_day (date);
line_y = y + E_WEEK_VIEW_DATE_T_PAD + font->ascent
@@ -256,7 +258,7 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem,
month starts (defaults are white for odd - January, March, ... and
light gray for even). In the week view the background is always the
same color, the color used for the odd months in the month view. */
- if (week_view->display_month && (month % 2 == 0))
+ if (week_view->multi_week_view && (month % 2 == 0))
bg_color = &week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS];
else
bg_color = &week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS];
@@ -283,7 +285,7 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem,
|| week_view->selection_end_day < day)
selected = FALSE;
if (selected) {
- if (week_view->display_month)
+ if (week_view->multi_week_view)
gdk_draw_rectangle (drawable, selected_bg_gc, TRUE,
x + 2, y + 1,
width - 5,
@@ -302,7 +304,7 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem,
the 1st of each month, otherwise use "10". */
show_day_name = FALSE;
show_month_name = FALSE;
- if (!week_view->display_month) {
+ if (!week_view->multi_week_view) {
show_day_name = TRUE;
show_month_name = TRUE;
} else if (day == 0 || day_of_month == 1) {
@@ -342,7 +344,7 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem,
buffer);
/* Draw the line under the date. */
- if (!week_view->display_month) {
+ if (!week_view->multi_week_view) {
gdk_draw_line (drawable, fg_gc,
x + E_WEEK_VIEW_DATE_LINE_L_PAD, line_y,
right_edge, line_y);
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index fef239b065..04da509a92 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -99,6 +99,8 @@ static gint e_week_view_convert_position_to_day (EWeekView *week_view,
static void e_week_view_update_selection (EWeekView *week_view,
gint day);
+static void e_week_view_queue_reload_events (EWeekView *week_view);
+static gboolean e_week_view_reload_events_idle_cb (gpointer data);
static void e_week_view_reload_events (EWeekView *week_view);
static void e_week_view_free_events (EWeekView *week_view);
static gboolean e_week_view_add_event (CalComponent *comp,
@@ -229,9 +231,6 @@ e_week_view_class_init (EWeekViewClass *class)
static void
e_week_view_init (EWeekView *week_view)
{
- GdkColormap *colormap;
- gboolean success[E_WEEK_VIEW_COLOR_LAST];
- gint nfailed;
GnomeCanvasGroup *canvas_group;
GtkObject *adjustment;
GdkPixbuf *pixbuf;
@@ -239,8 +238,6 @@ e_week_view_init (EWeekView *week_view)
GTK_WIDGET_SET_FLAGS (week_view, GTK_CAN_FOCUS);
- colormap = gtk_widget_get_colormap (GTK_WIDGET (week_view));
-
week_view->calendar = NULL;
week_view->client = NULL;
@@ -249,10 +246,12 @@ e_week_view_init (EWeekView *week_view)
week_view->events_sorted = TRUE;
week_view->events_need_layout = FALSE;
week_view->events_need_reshape = FALSE;
+ week_view->reload_events_idle_id = 0;
week_view->spans = NULL;
- week_view->display_month = FALSE;
+ week_view->multi_week_view = FALSE;
+ week_view->weeks_shown = 6;
week_view->rows = 6;
week_view->columns = 2;
week_view->compress_weekend = TRUE;
@@ -270,6 +269,8 @@ e_week_view_init (EWeekView *week_view)
week_view->editing_event_num = -1;
week_view->editing_new_event = FALSE;
+ week_view->main_gc = NULL;
+
/* Create the small font. */
week_view->use_small_font = TRUE;
week_view->small_font = gdk_font_load (E_WEEK_VIEW_SMALL_FONT);
@@ -278,29 +279,6 @@ e_week_view_init (EWeekView *week_view)
if (!week_view->small_font)
g_warning ("Couldn't load font");
- /* Allocate the colors. */
- week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].red = 0xeded;
- week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].green = 0xeded;
- week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].blue = 0xeded;
-
- week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].red = 65535;
- week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].green = 65535;
- week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].blue = 65535;
-
- week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].red = 0xd6d6;
- week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green = 0xd6d6;
- week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].blue = 0xd6d6;
-
- week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].red = 0;
- week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].green = 0;
- week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].blue = 0;
-
- nfailed = gdk_colormap_alloc_colors (colormap, week_view->colors,
- E_WEEK_VIEW_COLOR_LAST, FALSE,
- TRUE, success);
- if (nfailed)
- g_warning ("Failed to allocate all colors");
-
/*
* Titles Canvas. Note that we don't show it is only shown in the
@@ -379,11 +357,6 @@ e_week_view_init (EWeekView *week_view)
gtk_widget_show (week_view->vscrollbar);
- /* Create the pixmaps. */
- week_view->reminder_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &week_view->reminder_mask, NULL, bell_xpm);
- week_view->recurrence_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &week_view->recurrence_mask, NULL, recur_xpm);
-
-
/* Create the cursors. */
week_view->normal_cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
week_view->move_cursor = gdk_cursor_new (GDK_FLEUR);
@@ -416,15 +389,19 @@ e_week_view_destroy (GtkObject *object)
week_view = E_WEEK_VIEW (object);
+ e_week_view_free_events (week_view);
+
+ if (week_view->reload_events_idle_id != 0) {
+ g_source_remove (week_view->reload_events_idle_id);
+ week_view->reload_events_idle_id = 0;
+ }
+
if (week_view->client) {
gtk_signal_disconnect_by_data (GTK_OBJECT (week_view->client), week_view);
gtk_object_unref (GTK_OBJECT (week_view->client));
week_view->client = NULL;
}
- /* FIXME: free the colors. In EDayView as well. */
- /* FIXME: free the events and the spans. In EDayView as well? */
-
if (week_view->small_font)
gdk_font_unref (week_view->small_font);
@@ -440,12 +417,45 @@ static void
e_week_view_realize (GtkWidget *widget)
{
EWeekView *week_view;
+ GdkColormap *colormap;
+ gboolean success[E_WEEK_VIEW_COLOR_LAST];
+ gint nfailed;
if (GTK_WIDGET_CLASS (parent_class)->realize)
(*GTK_WIDGET_CLASS (parent_class)->realize)(widget);
week_view = E_WEEK_VIEW (widget);
week_view->main_gc = gdk_gc_new (widget->window);
+
+ colormap = gtk_widget_get_colormap (widget);
+
+ /* Allocate the colors. */
+ week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].red = 0xeded;
+ week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].green = 0xeded;
+ week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].blue = 0xeded;
+
+ week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].red = 65535;
+ week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].green = 65535;
+ week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].blue = 65535;
+
+ week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].red = 0xd6d6;
+ week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green = 0xd6d6;
+ week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].blue = 0xd6d6;
+
+ week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].red = 0;
+ week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].green = 0;
+ week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].blue = 0;
+
+ nfailed = gdk_colormap_alloc_colors (colormap, week_view->colors,
+ E_WEEK_VIEW_COLOR_LAST, FALSE,
+ TRUE, success);
+ if (nfailed)
+ g_warning ("Failed to allocate all colors");
+
+
+ /* Create the pixmaps. */
+ week_view->reminder_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &week_view->reminder_mask, NULL, bell_xpm);
+ week_view->recurrence_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &week_view->recurrence_mask, NULL, recur_xpm);
}
@@ -453,12 +463,23 @@ static void
e_week_view_unrealize (GtkWidget *widget)
{
EWeekView *week_view;
+ GdkColormap *colormap;
+ gint i;
week_view = E_WEEK_VIEW (widget);
gdk_gc_unref (week_view->main_gc);
week_view->main_gc = NULL;
+ colormap = gtk_widget_get_colormap (widget);
+ for (i = 0; i < E_WEEK_VIEW_COLOR_LAST; i++)
+ gdk_colors_free (colormap, &week_view->colors[i].pixel, 1, 0);
+
+ gdk_pixmap_unref (week_view->reminder_icon);
+ week_view->reminder_icon = NULL;
+ gdk_pixmap_unref (week_view->recurrence_icon);
+ week_view->recurrence_icon = NULL;
+
if (GTK_WIDGET_CLASS (parent_class)->unrealize)
(*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget);
}
@@ -557,7 +578,7 @@ e_week_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
/* Calculate the number of rows of events in each cell, for the large
cells and the compressed weekend cells. */
- if (week_view->display_month) {
+ if (week_view->multi_week_view) {
week_view->events_y_offset = E_WEEK_VIEW_DATE_T_PAD
+ font->ascent + font->descent
+ E_WEEK_VIEW_DATE_B_PAD;
@@ -635,9 +656,9 @@ e_week_view_recalc_cell_sizes (EWeekView *week_view)
gfloat width, height, offset;
gint row, col;
- if (week_view->display_month) {
- week_view->rows = 10;
- week_view->columns = 6;
+ if (week_view->multi_week_view) {
+ week_view->rows = week_view->weeks_shown * 2;
+ week_view->columns = week_view->compress_weekend ? 6 : 7;
} else {
week_view->rows = 6;
week_view->columns = 2;
@@ -807,6 +828,7 @@ static void
obj_updated_cb (CalClient *client, const char *uid, gpointer data)
{
EWeekView *week_view;
+ EWeekViewEvent *event;
gint event_num, num_days;
CalComponent *comp;
CalClientGetStatus status;
@@ -847,11 +869,24 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
#ifndef NO_WARNINGS
#warning "FIX ME"
#endif
- /* Do this the long way every time for now */
-#if 0
+
event = &g_array_index (week_view->events, EWeekViewEvent,
event_num);
+ /* If we are editing an event which we have just created, we
+ will get an update_event callback from the server. But we
+ need to ignore it or we will lose the text the user has
+ already typed in. */
+ if (week_view->editing_new_event
+ && week_view->editing_event_num == event_num) {
+ gtk_object_unref (GTK_OBJECT (event->comp));
+ event->comp = comp; /* Takes over ref count. */
+ return;
+ }
+
+
+ /* Do this the long way every time for now */
+#if 0
if (ical_object_compare_dates (event->ico, ico)) {
e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_update_event_cb, comp);
gtk_object_unref (GTK_OBJECT (comp));
@@ -867,7 +902,7 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
}
/* Add the occurrences of the event. */
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
cal_recur_generate_instances (comp,
week_view->day_starts[0],
@@ -958,7 +993,7 @@ e_week_view_set_selected_time_range (EWeekView *week_view,
g_date_clear (&date, 1);
g_date_set_time (&date, start_time);
- if (week_view->display_month) {
+ if (week_view->multi_week_view) {
/* Find the number of days since the start of the month. */
day_offset = g_date_day (&date) - 1;
@@ -990,7 +1025,7 @@ e_week_view_set_selected_time_range (EWeekView *week_view,
start_time = time_add_day (start_time, -day_offset);
start_time = time_day_begin (start_time);
e_week_view_recalc_day_starts (week_view, start_time);
- e_week_view_reload_events (week_view);
+ e_week_view_queue_reload_events (week_view);
}
/* Set the selection to the given days. */
@@ -1007,7 +1042,7 @@ e_week_view_set_selected_time_range (EWeekView *week_view,
}
/* Make sure the selection is valid. */
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
num_days--;
week_view->selection_start_day = CLAMP (week_view->selection_start_day,
0, num_days);
@@ -1050,6 +1085,96 @@ e_week_view_get_selected_time_range (EWeekView *week_view,
}
+/* Note that the returned date may be invalid if no date has been set yet. */
+void
+e_week_view_get_first_day_shown (EWeekView *week_view,
+ GDate *date)
+{
+ *date = week_view->first_day_shown;
+}
+
+
+/* This sets the first day shown in the view. It will be rounded down to the
+ nearest week. */
+void
+e_week_view_set_first_day_shown (EWeekView *week_view,
+ GDate *date)
+{
+ GDate base_date;
+ gint day_offset, num_days;
+ gboolean update_adjustment_value = FALSE;
+ guint32 old_selection_start_julian, old_selection_end_julian;
+ struct tm start_tm;
+ time_t start_time;
+
+ g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+
+ /* Calculate the old selection range. */
+ if (week_view->selection_start_day != -1) {
+ old_selection_start_julian =
+ g_date_julian (&week_view->base_date)
+ + week_view->selection_start_day;
+ old_selection_end_julian =
+ g_date_julian (&week_view->base_date)
+ + week_view->selection_end_day;
+ }
+
+ /* Find the 1st Monday at or before the given day. */
+ day_offset = g_date_weekday (date) - 1;
+
+ /* Calculate the base date, i.e. the first day shown when the
+ scrollbar adjustment value is 0. */
+ base_date = *date;
+ g_date_subtract_days (&base_date, day_offset);
+
+ /* See if we need to update the base date. */
+ if (!g_date_valid (&week_view->base_date)
+ || g_date_compare (&week_view->base_date, &base_date)) {
+ week_view->base_date = base_date;
+ update_adjustment_value = TRUE;
+ }
+
+ /* See if we need to update the first day shown. */
+ if (!g_date_valid (&week_view->first_day_shown)
+ || g_date_compare (&week_view->first_day_shown, &base_date)) {
+ week_view->first_day_shown = base_date;
+ g_date_to_struct_tm (&base_date, &start_tm);
+ start_time = mktime (&start_tm);
+ e_week_view_recalc_day_starts (week_view, start_time);
+ e_week_view_queue_reload_events (week_view);
+ }
+
+ /* Try to keep the previous selection, but if it is no longer shown
+ just select the first day. */
+ if (week_view->selection_start_day != -1) {
+ week_view->selection_start_day = old_selection_start_julian
+ - g_date_julian (&base_date);
+ week_view->selection_end_day = old_selection_end_julian
+ - g_date_julian (&base_date);
+
+ /* Make sure the selection is valid. */
+ num_days = week_view->multi_week_view
+ ? week_view->weeks_shown * 7 : 7;
+ num_days--;
+ week_view->selection_start_day =
+ CLAMP (week_view->selection_start_day, 0, num_days);
+ week_view->selection_end_day =
+ CLAMP (week_view->selection_end_day,
+ week_view->selection_start_day,
+ num_days);
+ }
+
+ /* Reset the adjustment value to 0 if the base address has changed.
+ Note that we do this after updating first_day_shown so that our
+ signal handler will not try to reload the events. */
+ if (update_adjustment_value)
+ gtk_adjustment_set_value (GTK_RANGE (week_view->vscrollbar)->adjustment, 0);
+
+
+ gtk_widget_queue_draw (week_view->main_canvas);
+}
+
+
/* Recalculates the time_t corresponding to the start of each day. */
static void
e_week_view_recalc_day_starts (EWeekView *week_view,
@@ -1058,7 +1183,7 @@ e_week_view_recalc_day_starts (EWeekView *week_view,
gint num_days, day;
time_t tmp_time;
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
tmp_time = lower;
week_view->day_starts[0] = tmp_time;
@@ -1074,29 +1199,29 @@ e_week_view_recalc_day_starts (EWeekView *week_view,
gboolean
-e_week_view_get_display_month (EWeekView *week_view)
+e_week_view_get_multi_week_view (EWeekView *week_view)
{
g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE);
- return week_view->display_month;
+ return week_view->multi_week_view;
}
void
-e_week_view_set_display_month (EWeekView *week_view,
- gboolean display_month)
+e_week_view_set_multi_week_view (EWeekView *week_view,
+ gboolean multi_week_view)
{
GtkAdjustment *adjustment;
gint page_increment, page_size;
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
- if (week_view->display_month == display_month)
+ if (week_view->multi_week_view == multi_week_view)
return;
- week_view->display_month = display_month;
+ week_view->multi_week_view = multi_week_view;
- if (display_month) {
+ if (multi_week_view) {
gtk_widget_show (week_view->titles_canvas);
page_increment = 4;
page_size = 5;
@@ -1114,7 +1239,50 @@ e_week_view_set_display_month (EWeekView *week_view,
e_week_view_recalc_day_starts (week_view, week_view->day_starts[0]);
e_week_view_recalc_cell_sizes (week_view);
- e_week_view_reload_events (week_view);
+ e_week_view_queue_reload_events (week_view);
+}
+
+
+gint
+e_week_view_get_weeks_shown (EWeekView *week_view)
+{
+ g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), 1);
+
+ return week_view->weeks_shown;
+}
+
+
+void
+e_week_view_set_weeks_shown (EWeekView *week_view,
+ gint weeks_shown)
+{
+ GtkAdjustment *adjustment;
+ gint page_increment, page_size;
+
+ g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+
+ weeks_shown = MIN (weeks_shown, E_WEEK_VIEW_MAX_WEEKS);
+
+ if (week_view->weeks_shown == weeks_shown)
+ return;
+
+ week_view->weeks_shown = weeks_shown;
+
+ if (week_view->multi_week_view) {
+ page_increment = 4;
+ page_size = 5;
+
+ adjustment = GTK_RANGE (week_view->vscrollbar)->adjustment;
+ adjustment->page_increment = page_increment;
+ adjustment->page_size = page_size;
+ gtk_adjustment_changed (adjustment);
+
+ /* FIXME: Need to change start date and adjustment value? */
+ e_week_view_recalc_day_starts (week_view,
+ week_view->day_starts[0]);
+ e_week_view_recalc_cell_sizes (week_view);
+ e_week_view_queue_reload_events (week_view);
+ }
}
@@ -1139,7 +1307,7 @@ e_week_view_set_compress_weekend (EWeekView *week_view,
week_view->compress_weekend = compress;
/* The option only affects the month view. */
- if (!week_view->display_month)
+ if (!week_view->multi_week_view)
return;
/* FIXME: Need to update layout. */
@@ -1161,6 +1329,8 @@ e_week_view_update_event_cb (EWeekView *week_view,
comp = data;
event = &g_array_index (week_view->events, EWeekViewEvent, event_num);
+
+ gtk_object_unref (GTK_OBJECT (event->comp));
event->comp = comp;
gtk_object_ref (GTK_OBJECT (comp));
@@ -1180,11 +1350,10 @@ e_week_view_update_event_cb (EWeekView *week_view,
CalComponentText t;
cal_component_get_summary (event->comp, &t);
- text = g_strdup (t.value);
+ text = (char*) t.value;
gnome_canvas_item_set (span->text_item,
"text", text ? text : "",
NULL);
- g_free (text);
e_week_view_reshape_event_span (week_view, event_num,
span_num);
@@ -1279,8 +1448,8 @@ e_week_view_get_day_position (EWeekView *week_view,
*day_x = *day_y = *day_w = *day_h = 0;
g_return_if_fail (day >= 0);
- if (week_view->display_month) {
- g_return_if_fail (day < E_WEEK_VIEW_MAX_WEEKS * 7);
+ if (week_view->multi_week_view) {
+ g_return_if_fail (day < week_view->weeks_shown * 7);
week = day / 7;
day_of_week = day % 7;
@@ -1367,7 +1536,7 @@ e_week_view_get_span_position (EWeekView *week_view,
num_days = span->num_days;
/* Check if the row will not be visible in compressed cells. */
if (span->row >= week_view->rows_per_compressed_cell) {
- if (week_view->display_month) {
+ if (week_view->multi_week_view) {
if (week_view->compress_weekend) {
/* If it ends on a Saturday and is 1 day long
we skip it, else we shorten it. If it ends
@@ -1554,7 +1723,7 @@ e_week_view_convert_position_to_day (EWeekView *week_view,
return -1;
/* Now convert the grid position to a week and day. */
- if (week_view->display_month) {
+ if (week_view->multi_week_view) {
week = grid_y / 2;
if (week_view->compress_weekend && grid_x == 5
&& grid_y % 2 == 1)
@@ -1616,6 +1785,42 @@ e_week_view_update_selection (EWeekView *week_view,
}
+/* This frees any events currently loaded, and queues a reload. */
+static void
+e_week_view_queue_reload_events (EWeekView *week_view)
+{
+ e_week_view_free_events (week_view);
+
+ if (week_view->reload_events_idle_id == 0) {
+ /* We'll use a low priority here, so the user can scroll
+ the view quickly. */
+ week_view->reload_events_idle_id = g_idle_add_full
+ (G_PRIORITY_LOW,
+ e_week_view_reload_events_idle_cb, week_view, NULL);
+ }
+}
+
+
+static gboolean
+e_week_view_reload_events_idle_cb (gpointer data)
+{
+ EWeekView *week_view;
+
+ g_return_val_if_fail (E_IS_WEEK_VIEW (data), FALSE);
+
+ GDK_THREADS_ENTER ();
+
+ week_view = E_WEEK_VIEW (data);
+
+ week_view->reload_events_idle_id = 0;
+
+ e_week_view_reload_events (week_view);
+
+ GDK_THREADS_LEAVE ();
+ return FALSE;
+}
+
+
static void
e_week_view_reload_events (EWeekView *week_view)
{
@@ -1628,8 +1833,8 @@ e_week_view_reload_events (EWeekView *week_view)
if (week_view->calendar
&& g_date_valid (&week_view->first_day_shown)) {
- num_days = week_view->display_month
- ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view
+ ? week_view->weeks_shown * 7 : 7;
cal_client_generate_instances (week_view->client,
CALOBJ_TYPE_EVENT,
@@ -1652,6 +1857,8 @@ e_week_view_free_events (EWeekView *week_view)
EWeekViewEventSpan *span;
gint event_num, span_num;
+ /* FIXME: set any indices into the arrays to -1? */
+
for (event_num = 0; event_num < week_view->events->len; event_num++) {
event = &g_array_index (week_view->events, EWeekViewEvent,
event_num);
@@ -1693,7 +1900,7 @@ e_week_view_add_event (CalComponent *comp,
week_view = E_WEEK_VIEW (data);
/* Check that the event times are valid. */
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
#if 0
g_print ("View start:%li end:%li Event start:%li end:%li\n",
@@ -1770,7 +1977,7 @@ e_week_view_layout_events (EWeekView *week_view)
spans = g_array_new (FALSE, FALSE, sizeof (EWeekViewEventSpan));
/* Clear the number of rows used per day. */
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
for (day = 0; day <= num_days; day++) {
week_view->rows_per_day[day] = 0;
}
@@ -1817,7 +2024,7 @@ e_week_view_layout_event (EWeekView *week_view,
start_day = e_week_view_find_day (week_view, event->start, FALSE);
end_day = e_week_view_find_day (week_view, event->end, TRUE);
- max_day = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 - 1
+ max_day = week_view->multi_week_view ? week_view->weeks_shown * 7 - 1
: 7 - 1;
start_day = CLAMP (start_day, 0, max_day);
end_day = CLAMP (end_day, 0, max_day);
@@ -1952,11 +2159,11 @@ e_week_view_reshape_events (EWeekView *week_view)
}
/* Reshape the jump buttons and show/hide them as appropriate. */
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
for (day = 0; day < num_days; day++) {
is_weekend = (day % 7 >= 5) ? TRUE : FALSE;
- if (!is_weekend || (week_view->display_month
+ if (!is_weekend || (week_view->multi_week_view
&& !week_view->compress_weekend))
max_rows = week_view->rows_per_cell;
else
@@ -2203,7 +2410,7 @@ e_week_view_find_day (EWeekView *week_view,
gint num_days, day;
time_t *day_starts;
- num_days = week_view->display_month ? E_WEEK_VIEW_MAX_WEEKS * 7 : 7;
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
day_starts = week_view->day_starts;
if (time_to_find < day_starts[0])
@@ -2237,7 +2444,7 @@ e_week_view_find_span_end (EWeekView *week_view,
{
gint week, day_of_week, end_day;
- if (week_view->display_month) {
+ if (week_view->multi_week_view) {
week = day / 7;
day_of_week = day % 7;
if (week_view->compress_weekend && day_of_week <= 5)
@@ -2287,7 +2494,7 @@ e_week_view_on_adjustment_changed (GtkAdjustment *adjustment,
lower = time_day_begin (lower);
e_week_view_recalc_day_starts (week_view, lower);
- e_week_view_reload_events (week_view);
+ e_week_view_queue_reload_events (week_view);
/* Update the selection, if needed. */
if (week_view->selection_start_day != -1) {
@@ -2937,6 +3144,8 @@ e_week_view_on_unrecur_appointment (GtkWidget *widget, gpointer data)
the start & end times to the instances times. */
new_comp = cal_component_clone (event->comp);
cal_component_set_uid (new_comp, cal_component_gen_uid ());
+ cal_component_set_rdate_list (new_comp, NULL);
+ cal_component_set_rrule_list (new_comp, NULL);
cal_component_set_exdate_list (new_comp, NULL);
cal_component_set_exrule_list (new_comp, NULL);
@@ -2970,11 +3179,9 @@ e_week_view_on_jump_button_event (GnomeCanvasItem *item,
if (event->type == GDK_BUTTON_PRESS) {
for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) {
if (item == week_view->jump_buttons[day]) {
- gnome_calendar_dayjump (week_view->calendar,
- week_view->day_starts[day]);
- /* A quick hack to make the 'Day' toolbar
- button active. */
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (week_view->calendar->view_toolbar_buttons[0]), TRUE);
+ gnome_calendar_dayjump
+ (week_view->calendar,
+ week_view->day_starts[day]);
return TRUE;
}
}
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index f27b5db336..42a1ced9f7 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -37,8 +37,9 @@ extern "C" {
* EWeekView - displays the Week & Month views of the calendar.
*/
-/* The maximum number of weeks we show. 5 is usually enough for 1 month. */
-#define E_WEEK_VIEW_MAX_WEEKS 5
+/* The maximum number of weeks we show. 5 is usually enough for 1 month,
+ but we allow 6 for longer selections. */
+#define E_WEEK_VIEW_MAX_WEEKS 6
/* The size of the reminder & recurrence icons, and padding around them. */
#define E_WEEK_VIEW_ICON_WIDTH 16
@@ -177,6 +178,9 @@ struct _EWeekView
gboolean events_need_layout;
gboolean events_need_reshape;
+ /* The id of our idle function to reload all events. */
+ gint reload_events_idle_id;
+
/* An array of EWeekViewEventSpan elements. Each event has its own
space within this array, and uses the spans_index and num_spans
fields of the EWeekViewEvent struct to access it. */
@@ -191,8 +195,13 @@ struct _EWeekView
/* The first day shown in the view. */
GDate first_day_shown;
- /* If we are displaying 1 week or 1 month. */
- gboolean display_month;
+ /* If we are displaying multiple weeks in rows. If this is FALSE only
+ one week is shown, with a different layout. */
+ gboolean multi_week_view;
+
+ /* How many weeks we are showing. This is only relevant if
+ display_month is TRUE. */
+ gint weeks_shown;
/* If Sat & Sun are compressed. Only applicable in month view, since
they are always compressed into 1 cell in the week view. */
@@ -233,15 +242,17 @@ struct _EWeekView
gint abbr_month_widths[12];
gint max_abbr_month_width;
- /* The size of the main grid of days and of the cells. Note that the
- offsets arrays have one more element than the widths/heights arrays
- since they also contain the right/bottom edge. */
+ /* The size of the main grid of days and of the cells. A row
+ corresponds to a compressed day, so normal days usually take
+ up 2 rows. Note that the offsets arrays have one more element
+ than the widths/heights arrays since they also contain the
+ right/bottom edge. */
gint rows;
gint columns;
gint col_widths[7];
gint col_offsets[8];
- gint row_heights[10];
- gint row_offsets[11];
+ gint row_heights[E_WEEK_VIEW_MAX_WEEKS * 2];
+ gint row_offsets[E_WEEK_VIEW_MAX_WEEKS * 2 + 1];
/* This specifies which times we are showing for the events, depending
on how much room is available. */
@@ -312,25 +323,37 @@ GtkWidget* e_week_view_new (void);
void e_week_view_set_calendar (EWeekView *week_view,
GnomeCalendar *calendar);
+/* The first day shown. Note that it will be rounded down to the start of a
+ week when set. The returned value will be invalid if no date has been set
+ yet. */
+void e_week_view_get_first_day_shown (EWeekView *week_view,
+ GDate *date);
+void e_week_view_set_first_day_shown (EWeekView *week_view,
+ GDate *date);
+
void e_week_view_set_cal_client (EWeekView *week_view,
CalClient *client);
-/* This sets the selected time range. The EWeekView will show the corresponding
+/* The selected time range. The EWeekView will show the corresponding
month and the days between start_time and end_time will be selected.
To select a single day, use the same value for start_time & end_time. */
+void e_week_view_get_selected_time_range (EWeekView *week_view,
+ time_t *start_time,
+ time_t *end_time);
void e_week_view_set_selected_time_range (EWeekView *week_view,
time_t start_time,
time_t end_time);
-/* Returns the selected time range. */
-void e_week_view_get_selected_time_range (EWeekView *week_view,
- time_t *start_time,
- time_t *end_time);
/* Whether to display 1 week or 1 month (5 weeks). It defaults to 1 week. */
-gboolean e_week_view_get_display_month (EWeekView *week_view);
-void e_week_view_set_display_month (EWeekView *week_view,
- gboolean display_month);
+gboolean e_week_view_get_multi_week_view (EWeekView *week_view);
+void e_week_view_set_multi_week_view (EWeekView *week_view,
+ gboolean multi_week_view);
+
+/* The number of weeks shown in the multi-week view. */
+gint e_week_view_get_weeks_shown (EWeekView *week_view);
+void e_week_view_set_weeks_shown (EWeekView *week_view,
+ gint weeks_shown);
/* Whether the weekend (Sat/Sun) should be compressed into 1 cell in the Month
view. In the Week view they are always compressed. */
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index ea61dafabc..2f6a8ddf4a 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -42,13 +42,27 @@ static void gnome_calendar_class_init (GnomeCalendarClass *class);
static void gnome_calendar_init (GnomeCalendar *gcal);
static void gnome_calendar_destroy (GtkObject *object);
-static void gnome_calendar_update_view_times (GnomeCalendar *gcal,
- GtkWidget *page);
-static void gnome_calendar_update_gtk_calendar (GnomeCalendar *gcal);
-static void gnome_calendar_on_day_selected (GtkCalendar *calendar,
- GnomeCalendar *gcal);
-static void gnome_calendar_on_month_changed (GtkCalendar *calendar,
- GnomeCalendar *gcal);
+static void gnome_calendar_set_view_internal (GnomeCalendar *gcal,
+ char *page_name,
+ gboolean range_selected);
+static void gnome_calendar_set_pane_positions (GnomeCalendar *gcal);
+static void gnome_calendar_update_view_times (GnomeCalendar *gcal);
+static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal);
+
+static void gnome_calendar_on_date_navigator_style_set (GtkWidget *widget,
+ GtkStyle *previous_style,
+ GnomeCalendar *gcal);
+static void gnome_calendar_on_date_navigator_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ GnomeCalendar *gcal);
+static void gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem,
+ GnomeCalendar *gcal);
+static void gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem,
+ GnomeCalendar *gcal);
+static gboolean gnome_calendar_get_days_shown (GnomeCalendar *gcal,
+ GDate *start_date,
+ gint *days_shown);
+
static GtkVBoxClass *parent_class;
@@ -98,6 +112,19 @@ gnome_calendar_init (GnomeCalendar *gcal)
{
gcal->object_editor_hash = g_hash_table_new (g_str_hash, g_str_equal);
gcal->alarms = g_hash_table_new (g_str_hash, g_str_equal);
+
+ gcal->current_view_type = GNOME_CALENDAR_VIEW_NOT_SET;
+ gcal->range_selected = FALSE;
+
+ /* Set the default pane positions. These will eventually come from
+ gconf settings. They are multiples of calendar month widths &
+ heights in the date navigator. */
+ gcal->hpane_pos = 1.0;
+ gcal->vpane_pos = 1.0;
+ gcal->hpane_pos_month_view = 0.0;
+ gcal->vpane_pos_month_view = 1.0;
+
+ gcal->ignore_view_button_clicks = FALSE;
}
/* Used from g_hash_table_foreach(); frees an object alarms entry */
@@ -157,56 +184,51 @@ gnome_calendar_destroy (GtkObject *object)
static void
setup_widgets (GnomeCalendar *gcal)
{
- GtkWidget *vpane, *w;
-
- /* The Main Notebook. */
- gcal->main_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_border (GTK_NOTEBOOK (gcal->main_notebook),
- FALSE);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (gcal->main_notebook), FALSE);
- gtk_widget_show (gcal->main_notebook);
- gtk_box_pack_start (GTK_BOX (gcal), gcal->main_notebook,
- TRUE, TRUE, 0);
+ GtkWidget *w;
- /* The First Page of the Main Notebook, containing a HPaned with the
- Sub-Notebook on the left and the GtkCalendar and ToDo list on the
- right. */
+ /* The main HPaned, with the notebook of calendar views on the left
+ and the ECalendar and ToDo list on the right. */
gcal->hpane = e_hpaned_new ();
gtk_widget_show (gcal->hpane);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->main_notebook),
- gcal->hpane, gtk_label_new (""));
-
- /* The Sub-Notebook, to contain the Day, Work-Week & Week views. */
- gcal->sub_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_border (GTK_NOTEBOOK (gcal->sub_notebook),
- FALSE);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (gcal->sub_notebook), FALSE);
- gtk_widget_show (gcal->sub_notebook);
- e_paned_pack1 (E_PANED (gcal->hpane), gcal->sub_notebook,
- TRUE, TRUE);
+ gtk_box_pack_start (GTK_BOX (gcal), gcal->hpane, TRUE, TRUE, 0);
+
+ /* The Notebook containing the 4 calendar views. */
+ gcal->notebook = gtk_notebook_new ();
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (gcal->notebook), FALSE);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (gcal->notebook), FALSE);
+ gtk_widget_show (gcal->notebook);
+ e_paned_pack1 (E_PANED (gcal->hpane), gcal->notebook, TRUE, TRUE);
/* The VPaned widget, to contain the GtkCalendar & ToDo list. */
- vpane = e_vpaned_new ();
- gtk_widget_show (vpane);
- e_paned_pack2 (E_PANED (gcal->hpane), vpane, FALSE, TRUE);
+ gcal->vpane = e_vpaned_new ();
+ gtk_widget_show (gcal->vpane);
+ e_paned_pack2 (E_PANED (gcal->hpane), gcal->vpane, FALSE, TRUE);
- /* The GtkCalendar. */
- w = gtk_calendar_new ();
- gcal->gtk_calendar = GTK_CALENDAR (w);
+ /* The ECalendar. */
+ w = e_calendar_new ();
+ gcal->date_navigator = E_CALENDAR (w);
gtk_widget_show (w);
- e_paned_pack1 (E_PANED (vpane), w, FALSE, TRUE);
- gcal->day_selected_id = gtk_signal_connect (GTK_OBJECT (gcal->gtk_calendar),
- "day_selected",
- (GtkSignalFunc) gnome_calendar_on_day_selected,
- gcal);
- gtk_signal_connect (GTK_OBJECT (gcal->gtk_calendar), "month_changed",
- GTK_SIGNAL_FUNC (gnome_calendar_on_month_changed),
+ e_paned_pack1 (E_PANED (gcal->vpane), w, FALSE, TRUE);
+ gtk_signal_connect (GTK_OBJECT (gcal->date_navigator),
+ "style_set",
+ GTK_SIGNAL_FUNC (gnome_calendar_on_date_navigator_style_set),
+ gcal);
+ gtk_signal_connect_after (GTK_OBJECT (gcal->date_navigator),
+ "size_allocate",
+ (GtkSignalFunc) gnome_calendar_on_date_navigator_size_allocate,
+ gcal);
+ gtk_signal_connect (GTK_OBJECT (gcal->date_navigator->calitem),
+ "selection_changed",
+ (GtkSignalFunc) gnome_calendar_on_date_navigator_selection_changed,
+ gcal);
+ gtk_signal_connect (GTK_OBJECT (gcal->date_navigator->calitem),
+ "date_range_changed",
+ GTK_SIGNAL_FUNC (gnome_calendar_on_date_navigator_date_range_changed),
gcal);
/* The ToDo list. */
-
gcal->todo = e_calendar_table_new ();
- e_paned_pack2 (E_PANED (vpane), gcal->todo, TRUE, TRUE);
+ e_paned_pack2 (E_PANED (gcal->vpane), gcal->todo, TRUE, TRUE);
gtk_widget_show (gcal->todo);
e_calendar_table_set_cal_client (E_CALENDAR_TABLE (gcal->todo),
gcal->client);
@@ -217,16 +239,18 @@ setup_widgets (GnomeCalendar *gcal)
e_day_view_set_calendar (E_DAY_VIEW (gcal->day_view), gcal);
e_day_view_set_cal_client (E_DAY_VIEW (gcal->day_view), gcal->client);
gtk_widget_show (gcal->day_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->sub_notebook),
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook),
gcal->day_view, gtk_label_new (""));
/* The Work Week View. */
gcal->work_week_view = e_day_view_new ();
+ e_day_view_set_work_week_view (E_DAY_VIEW (gcal->work_week_view),
+ TRUE);
e_day_view_set_days_shown (E_DAY_VIEW (gcal->work_week_view), 5);
e_day_view_set_calendar (E_DAY_VIEW (gcal->work_week_view), gcal);
e_day_view_set_cal_client (E_DAY_VIEW (gcal->work_week_view), gcal->client);
gtk_widget_show (gcal->work_week_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->sub_notebook),
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook),
gcal->work_week_view, gtk_label_new (""));
/* The Week View. */
@@ -234,29 +258,23 @@ setup_widgets (GnomeCalendar *gcal)
e_week_view_set_calendar (E_WEEK_VIEW (gcal->week_view), gcal);
e_week_view_set_cal_client (E_WEEK_VIEW (gcal->week_view), gcal->client);
gtk_widget_show (gcal->week_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->sub_notebook),
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook),
gcal->week_view, gtk_label_new (""));
/* The Month View. */
gcal->month_view = e_week_view_new ();
e_week_view_set_calendar (E_WEEK_VIEW (gcal->month_view), gcal);
+ e_week_view_set_multi_week_view (E_WEEK_VIEW (gcal->month_view), TRUE);
e_week_view_set_cal_client (E_WEEK_VIEW (gcal->month_view), gcal->client);
- e_week_view_set_display_month (E_WEEK_VIEW (gcal->month_view), TRUE);
gtk_widget_show (gcal->month_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->main_notebook),
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook),
gcal->month_view, gtk_label_new (""));
}
static GtkWidget *
get_current_page (GnomeCalendar *gcal)
{
- GtkWidget *page;
-
- page = GTK_NOTEBOOK (gcal->main_notebook)->cur_page->child;
- if (page == gcal->hpane)
- return GTK_NOTEBOOK (gcal->sub_notebook)->cur_page->child;
- else
- return page;
+ return GTK_NOTEBOOK (gcal->notebook)->cur_page->child;
}
char *
@@ -291,29 +309,29 @@ gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time)
gcal->selection_start_time = time_day_begin (new_time);
gcal->selection_end_time = time_add_day (gcal->selection_start_time,
1);
- gnome_calendar_update_view_times (gcal, NULL);
- gnome_calendar_update_gtk_calendar (gcal);
+ gnome_calendar_update_view_times (gcal);
+ gnome_calendar_update_date_navigator (gcal);
}
static void
-gnome_calendar_update_view_times (GnomeCalendar *gcal,
- GtkWidget *page)
+gnome_calendar_update_view_times (GnomeCalendar *gcal)
{
- if (page == NULL)
- page = get_current_page (gcal);
+ GtkWidget *page;
- if (page == gcal->day_view
- || page == gcal->work_week_view)
- e_day_view_set_selected_time_range (E_DAY_VIEW (page),
- gcal->selection_start_time,
- gcal->selection_end_time);
- else if (page == gcal->week_view
- || page == gcal->month_view)
- e_week_view_set_selected_time_range (E_WEEK_VIEW (page),
- gcal->selection_start_time,
- gcal->selection_end_time);
- else {
+ page = get_current_page (gcal);
+
+ if (page == gcal->day_view || page == gcal->work_week_view) {
+ e_day_view_set_selected_time_range
+ (E_DAY_VIEW (page),
+ gcal->selection_start_time,
+ gcal->selection_end_time);
+ } else if (page == gcal->week_view || page == gcal->month_view) {
+ e_week_view_set_selected_time_range
+ (E_WEEK_VIEW (page),
+ gcal->selection_start_time,
+ gcal->selection_end_time);
+ } else {
g_warning ("My penguin is gone!");
g_assert_not_reached ();
}
@@ -350,8 +368,8 @@ gnome_calendar_direction (GnomeCalendar *gcal, int direction)
gcal->selection_start_time = start_time;
gcal->selection_end_time = end_time;
- gnome_calendar_update_view_times (gcal, NULL);
- gnome_calendar_update_gtk_calendar (gcal);
+ gnome_calendar_update_view_times (gcal);
+ gnome_calendar_update_date_navigator (gcal);
}
void
@@ -378,8 +396,11 @@ gnome_calendar_dayjump (GnomeCalendar *gcal, time_t time)
g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- gnome_calendar_set_view (gcal, "dayview");
- gnome_calendar_goto (gcal, time);
+ gcal->selection_start_time = time_day_begin (time);
+ gcal->selection_end_time = time_add_day (gcal->selection_start_time,
+ 1);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gcal->day_button),
+ TRUE);
}
void
@@ -389,48 +410,129 @@ gnome_calendar_goto_today (GnomeCalendar *gcal)
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
gnome_calendar_goto (gcal, time (NULL));
+
+ gtk_widget_grab_focus (get_current_page (gcal));
}
/* This sets which view is currently shown. It also updates the selection time
of the view so it shows the appropriate days. */
void
-gnome_calendar_set_view (GnomeCalendar *gcal, char *page_name)
+gnome_calendar_set_view (GnomeCalendar *gcal,
+ char *page_name,
+ gboolean range_selected)
{
- GtkWidget *page;
- int main_page = 0, sub_page = -1;
-
g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
g_return_if_fail (page_name != NULL);
- if (strcmp (page_name, "dayview") == 0) {
- page = gcal->day_view;
- sub_page = 0;
- } else if (strcmp (page_name, "workweekview") == 0) {
- page = gcal->work_week_view;
- sub_page = 1;
- } else if (strcmp (page_name, "weekview") == 0) {
- page = gcal->week_view;
- sub_page = 2;
- } else if (strcmp (page_name, "monthview") == 0) {
- page = gcal->month_view;
- main_page = 1;
+ gnome_calendar_set_view_internal (gcal, page_name, range_selected);
+ gnome_calendar_update_view_times (gcal);
+ gnome_calendar_update_date_navigator (gcal);
+}
+
+
+/* This sets the view without changing the selection or updating the date
+ navigator. If a range of dates isn't selected it will also reset the number
+ of days/weeks shown to the default (i.e. 1 day for the day view or 5 weeks
+ for the month view). */
+static void
+gnome_calendar_set_view_internal (GnomeCalendar *gcal,
+ char *page_name,
+ gboolean range_selected)
+{
+ int view;
+ gboolean round_selection = FALSE;
+
+ g_print ("In gnome_calendar_set_view_internal: %s\n", page_name);
+
+ if (!strcmp (page_name, "dayview")) {
+ view = GNOME_CALENDAR_VIEW_DAY;
+ if (!range_selected)
+ e_day_view_set_days_shown
+ (E_DAY_VIEW (gcal->day_view), 1);
+ } else if (!strcmp (page_name, "workweekview")) {
+ view = GNOME_CALENDAR_VIEW_WORK_WEEK;
+ } else if (!strcmp (page_name, "weekview")) {
+ view = GNOME_CALENDAR_VIEW_WEEK;
+ round_selection = TRUE;
+ } else if (!strcmp (page_name, "monthview")) {
+ view = GNOME_CALENDAR_VIEW_MONTH;
+ if (!range_selected)
+ e_week_view_set_weeks_shown
+ (E_WEEK_VIEW (gcal->month_view), 5);
+ round_selection = TRUE;
} else {
g_warning ("Unknown calendar view: %s", page_name);
return;
}
- gnome_calendar_update_view_times (gcal, page);
+ gcal->current_view_type = view;
+ gcal->range_selected = range_selected;
+
+ gtk_notebook_set_page (GTK_NOTEBOOK (gcal->notebook), view);
+
+ gnome_calendar_set_pane_positions (gcal);
+
+ /* For the week & month views we want the selection in the date
+ navigator to be rounded to the nearest week when the arrow buttons
+ are pressed to move to the previous/next month. */
+ gtk_object_set (GTK_OBJECT (gcal->date_navigator->calitem),
+ "round_selection_when_moving", round_selection,
+ NULL);
+}
+
- if (sub_page != -1)
- gtk_notebook_set_page (GTK_NOTEBOOK (gcal->sub_notebook),
- sub_page);
- gtk_notebook_set_page (GTK_NOTEBOOK (gcal->main_notebook), main_page);
+static void
+gnome_calendar_set_pane_positions (GnomeCalendar *gcal)
+{
+ gint top_border, bottom_border, left_border, right_border;
+ gint col_width, row_height;
+ gfloat right_pane_width, top_pane_height;
+
+ /* Get the size of the calendar month width & height. */
+ e_calendar_get_border_size (gcal->date_navigator,
+ &top_border, &bottom_border,
+ &left_border, &right_border);
+ gtk_object_get (GTK_OBJECT (gcal->date_navigator->calitem),
+ "row_height", &row_height,
+ "column_width", &col_width,
+ NULL);
+
+ if (gcal->current_view_type == GNOME_CALENDAR_VIEW_MONTH
+ && !gcal->range_selected) {
+ right_pane_width = gcal->hpane_pos_month_view;
+ top_pane_height = gcal->vpane_pos_month_view;
+ } else {
+ right_pane_width = gcal->hpane_pos;
+ top_pane_height = gcal->vpane_pos;
+ }
- gnome_calendar_update_gtk_calendar (gcal);
+ /* We add the borders before multiplying due to the way we are using
+ the EPaned quantum feature. */
+ if (right_pane_width < 0.001)
+ right_pane_width = 0.0;
+ else
+ right_pane_width = right_pane_width * (col_width
+ + left_border + right_border) + 0.5;
+ if (top_pane_height < 0.001)
+ top_pane_height = 0.0;
+ else
+ top_pane_height = top_pane_height * (row_height
+ + top_border + bottom_border) + 0.5;
+
+ g_print ("right width:%g top height:%g\n", right_pane_width,
+ top_pane_height);
+
+ e_paned_set_position (E_PANED (gcal->hpane), -1);
+ e_paned_set_position (E_PANED (gcal->vpane), -1);
+ /* We add one to each dimension since we can't use 0. */
+ gtk_widget_set_usize (gcal->vpane, right_pane_width + 1, -2);
+ gtk_widget_set_usize (GTK_WIDGET (gcal->date_navigator),
+ -2, top_pane_height + 1);
}
+
#ifndef NO_WARNINGS
/* Sends a mail notification of an alarm trigger */
static void
@@ -811,7 +913,7 @@ static void
gnome_calendar_update_all (GnomeCalendar *cal)
{
load_alarms (cal);
- gnome_calendar_tag_calendar (cal, cal->gtk_calendar);
+ gnome_calendar_tag_calendar (cal, cal->date_navigator);
}
/* Removes any queued alarms for the specified UID */
@@ -873,7 +975,7 @@ gnome_calendar_object_updated_cb (GtkWidget *cal_client,
remove_alarms_for_object (gcal, uid);
add_alarms_for_object (gcal, uid);
- gnome_calendar_tag_calendar (gcal, gcal->gtk_calendar);
+ gnome_calendar_tag_calendar (gcal, gcal->date_navigator);
}
@@ -884,7 +986,7 @@ gnome_calendar_object_removed_cb (GtkWidget *cal_client,
{
remove_alarms_for_object (gcal, uid);
- gnome_calendar_tag_calendar (gcal, gcal->gtk_calendar);
+ gnome_calendar_tag_calendar (gcal, gcal->date_navigator);
}
@@ -904,7 +1006,7 @@ gnome_calendar_new (char *title)
setup_widgets (gcal);
- gnome_calendar_set_view (gcal, "dayview");
+ gnome_calendar_set_view (gcal, "dayview", FALSE);
gtk_signal_connect (GTK_OBJECT (gcal->client), "obj_updated",
gnome_calendar_object_updated_cb, gcal);
@@ -1134,91 +1236,93 @@ calendar_notify (time_t activation_time, CalendarAlarm *which, void *data)
#endif
+struct calendar_tag_closure
+{
+ ECalendarItem *calitem;
+ time_t start_time;
+ time_t end_time;
+};
+
/* Marks the specified range in a GtkCalendar */
-static void
-mark_gtk_calendar_day (GtkCalendar *calendar, time_t start, time_t end)
+static gboolean
+gnome_calendar_tag_calendar_cb (CalComponent *comp,
+ time_t istart,
+ time_t iend,
+ gpointer data)
{
+ struct calendar_tag_closure *c = data;
time_t t;
- t = time_day_begin (start);
+ t = time_day_begin (istart);
do {
struct tm tm;
tm = *localtime (&t);
- gtk_calendar_mark_day (calendar, tm.tm_mday);
+
+ e_calendar_item_mark_day (c->calitem, tm.tm_year + 1900,
+ tm.tm_mon, tm.tm_mday,
+ E_CALENDAR_ITEM_MARK_BOLD);
t = time_day_end (t);
- } while (t < end);
+ } while (t < iend);
+
+ return TRUE;
}
/*
* Tags the dates with appointments in a GtkCalendar based on the
* GnomeCalendar contents
*/
-struct calendar_tag_closure
-{
- GtkCalendar *gtk_cal;
- time_t month_begin;
- time_t month_end;
-};
-
-static gboolean
-gnome_calendar_tag_calendar_cb (CalComponent *comp, time_t istart, time_t iend, gpointer data)
-{
- struct calendar_tag_closure *c = data;
- time_t start, end;
-
- start = MAX (istart, c->month_begin);
- end = MIN (iend, c->month_end);
-
- if (start > end)
- return TRUE;
-
- /* Clip the occurrence's start and end times to the month's limits */
- mark_gtk_calendar_day (c->gtk_cal, start, end);
-
- return TRUE;
-}
-
void
-gnome_calendar_tag_calendar (GnomeCalendar *cal, GtkCalendar *gtk_cal)
+gnome_calendar_tag_calendar (GnomeCalendar *gcal, ECalendar *ecal)
{
struct calendar_tag_closure c;
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ struct tm start_tm = { 0 }, end_tm = { 0 };
- g_return_if_fail (cal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (cal));
- g_return_if_fail (gtk_cal != NULL);
- g_return_if_fail (GTK_IS_CALENDAR (gtk_cal));
-
- /* If the GtkCalendar isn't visible, we just return. */
- if (!GTK_WIDGET_VISIBLE (cal->gtk_calendar))
- return;
-
- c.gtk_cal = gtk_cal;
-
- c.month_begin = time_from_day (gtk_cal->year, gtk_cal->month, 1);
- if (c.month_begin == -1) {
- g_message ("gnome_calendar_tag_calendar(): Generated invalid month begin!");
- return;
- }
+ g_return_if_fail (gcal != NULL);
+ g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+ g_return_if_fail (ecal != NULL);
+ g_return_if_fail (E_IS_CALENDAR (ecal));
- c.month_end = time_month_end (c.month_begin);
- if (c.month_end == -1) {
- g_message ("gnome_calendar_tag_calendar(): Generated invalid month end!");
+ /* If the ECalendar isn't visible, we just return. */
+ if (!GTK_WIDGET_VISIBLE (ecal))
return;
- }
- gtk_calendar_freeze (gtk_cal);
- gtk_calendar_clear_marks (gtk_cal);
-
- cal_client_generate_instances (cal->client, CALOBJ_TYPE_EVENT,
- c.month_begin, c.month_end,
+ e_calendar_item_get_date_range (ecal->calitem,
+ &start_year, &start_month, &start_day,
+ &end_year, &end_month, &end_day);
+
+ start_tm.tm_year = start_year - 1900;
+ start_tm.tm_mon = start_month;
+ start_tm.tm_mday = start_day;
+ start_tm.tm_hour = 0;
+ start_tm.tm_min = 0;
+ start_tm.tm_sec = 0;
+ start_tm.tm_isdst = -1;
+
+ end_tm.tm_year = end_year - 1900;
+ end_tm.tm_mon = end_month;
+ end_tm.tm_mday = end_day;
+ end_tm.tm_hour = 0;
+ end_tm.tm_min = 0;
+ end_tm.tm_sec = 0;
+ end_tm.tm_isdst = -1;
+
+ e_calendar_item_clear_marks (ecal->calitem);
+
+ c.calitem = ecal->calitem;
+ c.start_time = mktime (&start_tm);
+ c.end_time = mktime (&end_tm);
+
+ cal_client_generate_instances (gcal->client, CALOBJ_TYPE_EVENT,
+ c.start_time, c.end_time,
gnome_calendar_tag_calendar_cb, &c);
-
- gtk_calendar_thaw (gtk_cal);
}
+
/* This is called when the day begin & end times, the AM/PM flag, or the
week_starts_on_monday flags are changed.
FIXME: Which of these options do we want the new views to support? */
@@ -1227,13 +1331,14 @@ gnome_calendar_time_format_changed (GnomeCalendar *gcal)
{
g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
+#if 0
gtk_calendar_display_options (gcal->gtk_calendar,
(week_starts_on_monday
? (gcal->gtk_calendar->display_flags
| GTK_CALENDAR_WEEK_START_MONDAY)
: (gcal->gtk_calendar->display_flags
& ~GTK_CALENDAR_WEEK_START_MONDAY)));
+#endif
}
/* This is called when any of the color settings are changed.
@@ -1261,9 +1366,10 @@ gnome_calendar_set_selected_time_range (GnomeCalendar *gcal,
gcal->selection_start_time = start_time;
gcal->selection_end_time = end_time;
- gnome_calendar_update_gtk_calendar (gcal);
+ gnome_calendar_update_date_navigator (gcal);
}
+
/* Callback used when an event editor requests that an object be saved */
static void
save_event_object_cb (EventEditor *ee, CalComponent *comp, gpointer data)
@@ -1275,6 +1381,7 @@ save_event_object_cb (EventEditor *ee, CalComponent *comp, gpointer data)
g_message ("save_event_object_cb(): Could not update the object!");
}
+
/* Callback used when an event editor finishes editing an object */
static void
released_event_object_cb (EventEditor *ee, const char *uid, gpointer data)
@@ -1328,7 +1435,6 @@ gnome_calendar_edit_object (GnomeCalendar *gcal, CalComponent *comp)
g_hash_table_insert (gcal->object_editor_hash, g_strdup (uid), ee);
-
gtk_signal_connect (GTK_OBJECT (ee), "save_event_object",
GTK_SIGNAL_FUNC (save_event_object_cb),
gcal);
@@ -1411,77 +1517,268 @@ gnome_calendar_get_current_time_range (GnomeCalendar *gcal,
-/* This updates the month shown and the day selected in the calendar, if
+/* This updates the month shown and the days selected in the calendar, if
necessary. */
static void
-gnome_calendar_update_gtk_calendar (GnomeCalendar *gcal)
+gnome_calendar_update_date_navigator (GnomeCalendar *gcal)
{
- GDate date;
- guint current_year, current_month, current_day;
- guint new_year, new_month, new_day;
- gboolean set_day = FALSE;
+ GDate start_date, end_date;
+ gint days_shown;
- /* If the GtkCalendar isn't visible, we just return. */
- if (!GTK_WIDGET_VISIBLE (gcal->gtk_calendar))
+ /* If the ECalendar isn't visible, we just return. */
+ if (!GTK_WIDGET_VISIBLE (gcal->date_navigator))
return;
- gtk_calendar_get_date (gcal->gtk_calendar, &current_year,
- &current_month, &current_day);
-
- g_date_clear (&date, 1);
- g_date_set_time (&date, gcal->selection_start_time);
- new_year = g_date_year (&date);
- new_month = g_date_month (&date) - 1;
- new_day = g_date_day (&date);
-
- /* Block the "day_selected" signal while we update the calendar. */
- gtk_signal_handler_block (GTK_OBJECT (gcal->gtk_calendar),
- gcal->day_selected_id);
-
- /* If the year & month don't match, update it. */
- if (new_year != current_year || new_month != current_month) {
- /* FIXME: GtkCalendar bug workaround. If we select a month
- which has less days than the currently selected day, it
- causes a problem next time we set the day. */
- if (current_day > 28) {
- gtk_calendar_select_day (gcal->gtk_calendar, 28);
- set_day = TRUE;
- }
- gtk_calendar_select_month (gcal->gtk_calendar, new_month,
- new_year);
+ if (gnome_calendar_get_days_shown (gcal, &start_date, &days_shown)) {
+ end_date = start_date;
+ g_date_add_days (&end_date, days_shown - 1);
+
+ e_calendar_item_set_selection (gcal->date_navigator->calitem,
+ &start_date, &end_date);
}
+}
+
- /* If the day doesn't match, update it. */
- if (new_day != current_day || set_day)
- gtk_calendar_select_day (gcal->gtk_calendar, new_day);
+static gboolean
+gnome_calendar_get_days_shown (GnomeCalendar *gcal,
+ GDate *start_date,
+ gint *days_shown)
+{
+ GtkWidget *page;
+
+ page = get_current_page (gcal);
- gtk_signal_handler_unblock (GTK_OBJECT (gcal->gtk_calendar),
- gcal->day_selected_id);
+ if (page == gcal->day_view || page == gcal->work_week_view) {
+ g_date_clear (start_date, 1);
+ g_date_set_time (start_date, E_DAY_VIEW (page)->lower);
+ *days_shown = e_day_view_get_days_shown (E_DAY_VIEW (page));
+ return TRUE;
+ } else if (page == gcal->week_view || page == gcal->month_view) {
+ *start_date = E_WEEK_VIEW (page)->first_day_shown;
+ if (e_week_view_get_multi_week_view (E_WEEK_VIEW (page)))
+ *days_shown = e_week_view_get_weeks_shown (E_WEEK_VIEW (page)) * 7;
+ else
+ *days_shown = 7;
+ return TRUE;
+ } else {
+ g_warning ("gnome_calendar_get_days_shown - Invalid page");
+ return FALSE;
+ }
}
+
static void
-gnome_calendar_on_day_selected (GtkCalendar *calendar,
- GnomeCalendar *gcal)
+gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem,
+ GnomeCalendar *gcal)
{
- gint y, m, d;
+ GDate start_date, end_date, new_start_date, new_end_date;
+ gint days_shown, new_days_shown;
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ gboolean starts_on_week_start_day = FALSE;
struct tm tm;
- gtk_calendar_get_date (calendar, &y, &m, &d);
+ g_print ("In gnome_calendar_on_date_navigator_selection_changed\n");
+
+ if (!gnome_calendar_get_days_shown (gcal, &start_date, &days_shown))
+ return;
+
+ end_date = start_date;
+ g_date_add_days (&end_date, days_shown - 1);
+
+ e_calendar_item_get_selection (calitem, &new_start_date,
+ &new_end_date);
+
+ /* If the selection hasn't changed just return. */
+ if (!g_date_compare (&start_date, &new_start_date)
+ && !g_date_compare (&end_date, &new_end_date))
+ return;
+
+ new_days_shown = g_date_julian (&new_end_date)
+ - g_date_julian (&new_start_date) + 1;
+
+ /* FIXME: This assumes weeks start on Monday for now. */
+ if (g_date_weekday (&new_start_date) - 1 == 0)
+ starts_on_week_start_day = TRUE;
+
+ /* Switch views as appropriate, and change the number of days or weeks
+ shown. */
+ if (new_days_shown > 9) {
+ e_week_view_set_weeks_shown (E_WEEK_VIEW (gcal->month_view),
+ (new_days_shown + 6) / 7);
+ e_week_view_set_first_day_shown (E_WEEK_VIEW (gcal->month_view),
+ &new_start_date);
+ gnome_calendar_set_view_internal (gcal, "monthview", TRUE);
+ gnome_calendar_update_date_navigator (gcal);
+ } else if (new_days_shown == 7 && starts_on_week_start_day) {
+ e_week_view_set_first_day_shown (E_WEEK_VIEW (gcal->week_view),
+ &new_start_date);
+ gnome_calendar_set_view_internal (gcal, "weekview", TRUE);
+ gnome_calendar_update_date_navigator (gcal);
+ } else {
+ start_year = g_date_year (&new_start_date);
+ start_month = g_date_month (&new_start_date) - 1;
+ start_day = g_date_day (&new_start_date);
+ end_year = g_date_year (&new_end_date);
+ end_month = g_date_month (&new_end_date) - 1;
+ end_day = g_date_day (&new_end_date);
+
+ tm.tm_year = start_year - 1900;
+ tm.tm_mon = start_month;
+ tm.tm_mday = start_day;
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ tm.tm_isdst = -1;
+ gcal->selection_start_time = mktime (&tm);
+
+ tm.tm_year = end_year - 1900;
+ tm.tm_mon = end_month;
+ tm.tm_mday = end_day + 1; /* mktime() will normalize this. */
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
+ tm.tm_isdst = -1;
+ gcal->selection_end_time = mktime (&tm);
+
+ e_day_view_set_days_shown (E_DAY_VIEW (gcal->day_view),
+ new_days_shown);
+ gnome_calendar_set_view (gcal, "dayview", TRUE);
+ }
+
+ gnome_calendar_update_view_buttons (gcal);
+ gtk_widget_grab_focus (get_current_page (gcal));
+}
+
+
+static void
+gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem,
+ GnomeCalendar *gcal)
+{
+ gnome_calendar_tag_calendar (gcal, gcal->date_navigator);
+}
- tm.tm_year = y - 1900;
- tm.tm_mon = m;
- tm.tm_mday = d;
- tm.tm_hour = 5; /* for daylight savings time fix */
- tm.tm_min = 0;
- tm.tm_sec = 0;
- gnome_calendar_goto (gcal, mktime (&tm));
+static void
+gnome_calendar_on_date_navigator_style_set (GtkWidget *widget,
+ GtkStyle *previous_style,
+ GnomeCalendar *gcal)
+{
+ ECalendar *ecal;
+ gint row_height, col_width;
+ gint top_border, bottom_border, left_border, right_border;
+
+ g_return_if_fail (E_IS_CALENDAR (widget));
+ g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+
+ ecal = E_CALENDAR (widget);
+
+ e_calendar_get_border_size (gcal->date_navigator,
+ &top_border, &bottom_border,
+ &left_border, &right_border);
+ gtk_object_get (GTK_OBJECT (ecal->calitem),
+ "row_height", &row_height,
+ "column_width", &col_width,
+ NULL);
+
+ /* The EPaned quantum feature works better if we add on the calendar
+ borders to the quantum size. Otherwise if you shrink the date
+ navigator you get left with the border widths/heights which looks
+ bad. EPaned should be more flexible really. */
+ col_width += left_border + right_border;
+ row_height += top_border + bottom_border;
+
+ /* We don't have to use the EPaned quantum feature. We could just let
+ the calendar expand to fill the allocated space, showing as many
+ months as will fit. But for that to work nicely the EPaned should
+ resize the widgets as the bar is dragged. Otherwise the user has
+ to mess around to get the number of months that they want. */
+#if 1
+ gtk_object_set (GTK_OBJECT (gcal->hpane),
+ "quantum", (guint) col_width,
+ NULL);
+ gtk_object_set (GTK_OBJECT (gcal->vpane),
+ "quantum", (guint) row_height,
+ NULL);
+#endif
+
+ gnome_calendar_set_pane_positions (gcal);
}
static void
-gnome_calendar_on_month_changed (GtkCalendar *calendar,
- GnomeCalendar *gcal)
+gnome_calendar_on_date_navigator_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ GnomeCalendar *gcal)
+{
+ gint width, height, row_height, col_width;
+ gint top_border, bottom_border, left_border, right_border;
+ gfloat hpane_pos, vpane_pos;
+
+ g_print ("In gnome_calendar_on_date_navigator_size_allocate %ix%i\n",
+ allocation->width, allocation->height);
+
+ if (gcal->current_view_type != GNOME_CALENDAR_VIEW_NOT_SET) {
+ e_calendar_get_border_size (gcal->date_navigator,
+ &top_border, &bottom_border,
+ &left_border, &right_border);
+ gtk_object_get (GTK_OBJECT (gcal->date_navigator->calitem),
+ "row_height", &row_height,
+ "column_width", &col_width,
+ NULL);
+
+ /* We subtract one from each dimension since we added 1 in
+ gnome_calendar_set_view_internal(). */
+ width = allocation->width - 1;
+ height = allocation->height - 1;
+
+ /* We add the border sizes to work around the EPaned
+ quantized feature. */
+ col_width += left_border + right_border;
+ row_height += top_border + bottom_border;
+
+ hpane_pos = (gfloat) width / col_width;
+ vpane_pos = (gfloat) height / row_height;
+
+ if (gcal->current_view_type == GNOME_CALENDAR_VIEW_MONTH
+ && !gcal->range_selected) {
+ gcal->hpane_pos_month_view = hpane_pos;
+ gcal->vpane_pos_month_view = vpane_pos;
+ } else {
+ gcal->hpane_pos = hpane_pos;
+ gcal->vpane_pos = vpane_pos;
+ }
+
+ g_print (" hpane_pos:%g vpane_pos:%g\n", hpane_pos, vpane_pos);
+
+ }
+}
+
+
+/* This makes the appropriate radio button in the toolbar active.
+ It sets the ignore_view_button_clicks flag so the "clicked" signal handlers
+ just return without doing anything. */
+void
+gnome_calendar_update_view_buttons (GnomeCalendar *gcal)
{
- gnome_calendar_tag_calendar (gcal, gcal->gtk_calendar);
+ GtkWidget *page, *button;
+
+ page = get_current_page (gcal);
+
+ if (page == gcal->day_view)
+ button = gcal->day_button;
+ else if (page == gcal->work_week_view)
+ button = gcal->work_week_button;
+ else if (page == gcal->week_view)
+ button = gcal->week_button;
+ else if (page == gcal->month_view)
+ button = gcal->month_button;
+ else {
+ g_warning ("Unknown calendar view");
+ button = gcal->day_button;
+ }
+
+ gcal->ignore_view_button_clicks = TRUE;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ gcal->ignore_view_button_clicks = FALSE;
}
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index df087395e1..b484caff1e 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -10,22 +10,31 @@
#define GNOME_CALENDAR_APP_H
#include <time.h>
-#include <gtk/gtkcalendar.h>
-#include <gtk/gtkvbox.h>
#include <libgnome/gnome-defs.h>
+#include <gtk/gtkvbox.h>
#include <bonobo.h>
+#include <widgets/misc/e-calendar.h>
#include <cal-client/cal-client.h>
BEGIN_GNOME_DECLS
+/* These must match the page numbers in the GtkNotebook. */
+typedef enum {
+ GNOME_CALENDAR_VIEW_DAY = 0,
+ GNOME_CALENDAR_VIEW_WORK_WEEK = 1,
+ GNOME_CALENDAR_VIEW_WEEK = 2,
+ GNOME_CALENDAR_VIEW_MONTH = 3,
+
+ GNOME_CALENDAR_VIEW_NOT_SET = 9
+} GnomeCalendarViewType;
+
+
#define GNOME_CALENDAR(obj) GTK_CHECK_CAST(obj, gnome_calendar_get_type(), GnomeCalendar)
#define GNOME_CALENDAR_CLASS(class) GTK_CHECK_CAST_CLASS(class, gnome_calendar_get_type(), GnomeCalendarClass)
#define GNOME_IS_CALENDAR(obj) GTK_CHECK_TYPE(obj, gnome_calendar_get_type())
-#define GNOME_CALENDAR_NUM_VIEWS 4
-
typedef struct {
GtkVBox vbox;
@@ -36,13 +45,17 @@ typedef struct {
GHashTable *object_editor_hash;
+ /* This is the last selection explicitly selected by the user. We try
+ to keep it the same when we switch views, but we may have to alter
+ it depending on the view (e.g. the week views only select days, so
+ any times are lost. */
time_t selection_start_time;
time_t selection_end_time;
- GtkWidget *main_notebook;
- GtkWidget *sub_notebook;
GtkWidget *hpane;
- GtkCalendar *gtk_calendar;
+ GtkWidget *notebook;
+ GtkWidget *vpane;
+ ECalendar *date_navigator;
GtkWidget *todo;
GtkWidget *day_view;
@@ -50,13 +63,33 @@ typedef struct {
GtkWidget *week_view;
GtkWidget *month_view;
- GtkWidget *view_toolbar_buttons[GNOME_CALENDAR_NUM_VIEWS];
+ /* These are the toolbar radio buttons for switching views. */
+ GtkWidget *day_button;
+ GtkWidget *work_week_button;
+ GtkWidget *week_button;
+ GtkWidget *month_button;
+
+ /* This is the view currently shown. We use it to keep track of the
+ positions of the panes. range_selected is TRUE if a range of dates
+ was selected in the date navigator to show the view. */
+ GnomeCalendarViewType current_view_type;
+ gboolean range_selected;
+
+ /* These are the saved positions of the panes. They are multiples of
+ calendar month widths & heights in the date navigator, so that they
+ will work OK after theme changes. */
+ gfloat hpane_pos;
+ gfloat vpane_pos;
+ gfloat hpane_pos_month_view;
+ gfloat vpane_pos_month_view;
+
+ /* This is TRUE when we just want to set the state of the toolbar
+ radio buttons without causing any related code to be executed.
+ The "clicked" signal handlers just return when this is set. */
+ gboolean ignore_view_button_clicks;
void *event_editor;
- /* The signal handler id for our GtkCalendar "day_selected" handler. */
- guint day_selected_id;
-
/* Alarm ID for the midnight refresh function */
gpointer midnight_alarm_refresh_id;
@@ -91,11 +124,12 @@ void gnome_calendar_dayjump (GnomeCalendar *gcal,
time_t time);
/* Jumps to the current day */
void gnome_calendar_goto_today (GnomeCalendar *gcal);
-void gnome_calendar_tag_calendar (GnomeCalendar *cal,
- GtkCalendar *gtk_cal);
+void gnome_calendar_tag_calendar (GnomeCalendar *gcal,
+ ECalendar *ecal);
char *gnome_calendar_get_current_view_name (GnomeCalendar *gcal);
-void gnome_calendar_set_view (GnomeCalendar *gcal,
- char *page_name);
+void gnome_calendar_set_view (GnomeCalendar *gcal,
+ char *page_name,
+ gboolean reset_range_shown);
void gnome_calendar_set_selected_time_range (GnomeCalendar *gcal,
time_t start_time,
@@ -114,18 +148,23 @@ void gnome_calendar_get_current_time_range (GnomeCalendar *gcal,
time_t *end_time);
-/* Notifies the calendar that the time format has changed and it must update all its views */
-void gnome_calendar_time_format_changed (GnomeCalendar *gcal);
+/* Notifies the calendar that the time format has changed and it must update
+ all its views */
+void gnome_calendar_time_format_changed (GnomeCalendar *gcal);
-/* Notifies the calendar that the todo list properties have changed and its time
- * to update the views.
- */
-void gnome_calendar_colors_changed (GnomeCalendar *gcal);
+/* Notifies the calendar that the todo list properties have changed and its
+ time to update the views. */
+void gnome_calendar_colors_changed (GnomeCalendar *gcal);
-/* Notifies the calendar that the todo list properties have changed and its time
- * to update the views.
- */
-void gnome_calendar_todo_properties_changed (GnomeCalendar *gcal);
+/* Notifies the calendar that the todo list properties have changed and its
+ time to update the views. */
+void gnome_calendar_todo_properties_changed (GnomeCalendar *gcal);
+
+
+/* This makes the appropriate radio button in the toolbar active.
+ It sets the ignore_view_button_clicks flag so the "clicked" signal handlers
+ just return without doing anything. */
+void gnome_calendar_update_view_buttons (GnomeCalendar *gcal);