diff options
Diffstat (limited to 'calendar/gui/e-day-view.c')
-rw-r--r-- | calendar/gui/e-day-view.c | 266 |
1 files changed, 176 insertions, 90 deletions
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 84cd31464a..0963b00acb 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -92,6 +92,7 @@ static gint e_day_view_focus_out (GtkWidget *widget, GdkEventFocus *event); static gint e_day_view_key_press (GtkWidget *widget, GdkEventKey *event); +static gboolean e_day_view_check_if_new_event_fits (EDayView *day_view); static void e_day_view_on_canvas_realized (GtkWidget *widget, EDayView *day_view); @@ -121,9 +122,6 @@ static gboolean e_day_view_convert_event_coords (EDayView *day_view, GdkWindow *window, gint *x_return, gint *y_return); -static void e_day_view_update_selection (EDayView *day_view, - gint row, - gint col); static void e_day_view_update_long_event_resize (EDayView *day_view, gint day); static void e_day_view_update_resize (EDayView *day_view, @@ -271,11 +269,8 @@ static gboolean e_day_view_convert_time_to_grid_position (EDayView *day_view, gint *col, gint *row); -static void e_day_view_check_auto_scroll (EDayView *day_view, - gint event_y); static void e_day_view_start_auto_scroll (EDayView *day_view, gboolean scroll_up); -static void e_day_view_stop_auto_scroll (EDayView *day_view); static gboolean e_day_view_auto_scroll_handler (gpointer data); static void e_day_view_on_new_appointment (GtkWidget *widget, @@ -470,9 +465,9 @@ e_day_view_init (EDayView *day_view) day_view->resize_bars_event_num = -1; day_view->selection_start_row = -1; - day_view->selection_start_col = -1; + day_view->selection_start_day = -1; day_view->selection_end_row = -1; - day_view->selection_end_col = -1; + day_view->selection_end_day = -1; day_view->selection_drag_pos = E_DAY_VIEW_DRAG_NONE; day_view->selection_in_top_canvas = FALSE; @@ -1098,9 +1093,10 @@ e_day_view_update_event (EDayView *day_view, g_return_if_fail (E_IS_DAY_VIEW (day_view)); -#if 0 +#if 1 /* FIXME: Just for testing. */ chdir ("/home/damon/tmp"); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); g_print ("In e_day_view_update_event day_view:%p uid:%s\n", day_view, uid); @@ -1146,6 +1142,7 @@ e_day_view_update_event (EDayView *day_view, EDayViewEvent, event_num); if (ical_object_compare_dates (event->ico, ico)) { + g_print ("updated object's dates unchanged\n"); e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_update_event_cb, ico); ical_object_unref (ico); gtk_widget_queue_draw (day_view->top_canvas); @@ -1155,6 +1152,7 @@ e_day_view_update_event (EDayView *day_view, /* The dates have changed, so we need to remove the old occurrrences before adding the new ones. */ + g_print ("dates changed - removing occurrences\n"); e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_remove_event_cb, NULL); @@ -1269,7 +1267,7 @@ e_day_view_remove_event (EDayView *day_view, { g_return_if_fail (E_IS_DAY_VIEW (day_view)); -#if 0 +#if 1 g_print ("In e_day_view_remove_event day_view:%p uid:%s\n", day_view, uid); #endif @@ -1291,6 +1289,11 @@ e_day_view_remove_event_cb (EDayView *day_view, { EDayViewEvent *event; +#if 1 + g_print ("In e_day_view_remove_event_cb day:%i event_num:%i\n", + day, event_num); +#endif + if (day == E_DAY_VIEW_LONG_EVENT) event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); @@ -1334,6 +1337,10 @@ e_day_view_update_event_label (EDayView *day_view, event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); + /* If the event isn't visible just return. */ + if (!event->canvas_item) + return; + text = event->ico->summary ? event->ico->summary : ""; if (day_view->editing_event_day == day @@ -1374,6 +1381,10 @@ e_day_view_update_long_event_label (EDayView *day_view, event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); + /* If the event isn't visible just return. */ + if (!event->canvas_item) + return; + gnome_canvas_item_set (event->canvas_item, "text", event->ico->summary ? event->ico->summary : "", NULL); @@ -1527,19 +1538,19 @@ e_day_view_set_selected_time_range (EDayView *day_view, } if (start_row != day_view->selection_start_row - || start_col != day_view->selection_start_col) { + || start_col != day_view->selection_start_day) { need_redraw = TRUE; day_view->selection_in_top_canvas = FALSE; day_view->selection_start_row = start_row; - day_view->selection_start_col = start_col; + day_view->selection_start_day = start_col; } if (end_row != day_view->selection_end_row - || end_col != day_view->selection_end_col) { + || end_col != day_view->selection_end_day) { need_redraw = TRUE; day_view->selection_in_top_canvas = FALSE; day_view->selection_end_row = end_row; - day_view->selection_end_col = end_col; + day_view->selection_end_day = end_col; } if (need_redraw) { @@ -1557,9 +1568,9 @@ e_day_view_get_selected_time_range (EDayView *day_view, { gint start_col, start_row, end_col, end_row; - start_col = day_view->selection_start_col; + start_col = day_view->selection_start_day; start_row = day_view->selection_start_row; - end_col = day_view->selection_end_col; + end_col = day_view->selection_end_day; end_row = day_view->selection_end_row; if (start_col == -1) { @@ -1799,16 +1810,7 @@ e_day_view_on_top_canvas_button_press (GtkWidget *widget, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, FALSE, NULL, event->time) == 0) { - day_view->selection_start_row = -1; - day_view->selection_start_col = day; - day_view->selection_end_row = -1; - day_view->selection_end_col = day; - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; - day_view->selection_in_top_canvas = TRUE; - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); + e_day_view_start_selection (day_view, day, -1); } } else if (event->button == 3) { e_day_view_on_event_right_click (day_view, event, -1, -1); @@ -1912,16 +1914,7 @@ e_day_view_on_main_canvas_button_press (GtkWidget *widget, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, FALSE, NULL, event->time) == 0) { - day_view->selection_start_row = row; - day_view->selection_start_col = day; - day_view->selection_end_row = row; - day_view->selection_end_col = day; - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; - day_view->selection_in_top_canvas = FALSE; - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); + e_day_view_start_selection (day_view, day, row); } } else if (event->button == 3) { e_day_view_on_event_right_click (day_view, event, -1, -1); @@ -2257,7 +2250,7 @@ e_day_view_on_event_right_click (EDayView *day_view, }; have_selection = GTK_WIDGET_HAS_FOCUS (day_view) - && day_view->selection_start_col != -1; + && day_view->selection_start_day != -1; if (event_num == -1) { items = 1; @@ -2352,6 +2345,7 @@ e_day_view_on_delete_occurrence (GtkWidget *widget, gpointer data) { EDayView *day_view; EDayViewEvent *event; + iCalObject *ico; day_view = E_DAY_VIEW (data); @@ -2359,9 +2353,13 @@ e_day_view_on_delete_occurrence (GtkWidget *widget, gpointer data) if (event == NULL) return; - ical_object_add_exdate (event->ico, event->start); - gnome_calendar_object_changed (day_view->calendar, event->ico, - CHANGE_DATES); + /* We must duplicate the iCalObject, or we won't know it has changed + when we get the "update_event" callback. */ + ico = ical_object_duplicate (event->ico); + + ical_object_add_exdate (ico, event->start); + gnome_calendar_object_changed (day_view->calendar, ico, CHANGE_DATES); + ical_object_unref (ico); } @@ -2389,7 +2387,7 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data) { EDayView *day_view; EDayViewEvent *event; - iCalObject *ico; + iCalObject *ico, *new_ico; day_view = E_DAY_VIEW (data); @@ -2397,26 +2395,29 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data) if (event == NULL) return; - /* For the unrecurred instance we duplicate the original object, - create a new uid for it, get rid of the recurrence rules, and set - the start & end times to the instances times. */ - ico = ical_object_duplicate (event->ico); - g_free (ico->uid); - ico->uid = ical_gen_uid (); - g_free (ico->recur); - ico->recur = 0; - ico->dtstart = event->start; - ico->dtend = event->end; - /* For the recurring object, we add a exception to get rid of the instance. */ - ical_object_add_exdate (event->ico, event->start); - - gnome_calendar_object_changed (day_view->calendar, event->ico, - CHANGE_ALL); - gnome_calendar_add_object (day_view->calendar, ico); + ico = ical_object_duplicate (event->ico); + ical_object_add_exdate (ico, event->start); + /* For the unrecurred instance we duplicate the original object, + create a new uid for it, get rid of the recurrence rules, and set + the start & end times to the instances times. */ + new_ico = ical_object_duplicate (event->ico); + g_free (new_ico->uid); + new_ico->uid = ical_gen_uid (); + ical_object_reset_recurrence (new_ico); + new_ico->dtstart = event->start; + new_ico->dtend = event->end; + + /* Now update both iCalObjects. Note that we do this last since at + present the updates happen synchronously so our event may disappear. + */ + gnome_calendar_object_changed (day_view->calendar, ico, CHANGE_ALL); ical_object_unref (ico); + + gnome_calendar_add_object (day_view->calendar, new_ico); + ical_object_unref (new_ico); } @@ -2443,9 +2444,8 @@ e_day_view_on_top_canvas_button_release (GtkWidget *widget, EDayView *day_view) { if (day_view->selection_drag_pos != E_DAY_VIEW_DRAG_NONE) { - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_NONE; gdk_pointer_ungrab (event->time); - e_day_view_update_calendar_selection_time (day_view); + e_day_view_finish_selection (day_view); } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { e_day_view_finish_long_event_resize (day_view); gdk_pointer_ungrab (event->time); @@ -2468,10 +2468,9 @@ e_day_view_on_main_canvas_button_release (GtkWidget *widget, EDayView *day_view) { if (day_view->selection_drag_pos != E_DAY_VIEW_DRAG_NONE) { - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_NONE; gdk_pointer_ungrab (event->time); + e_day_view_finish_selection (day_view); e_day_view_stop_auto_scroll (day_view); - e_day_view_update_calendar_selection_time (day_view); } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { e_day_view_finish_resize (day_view); gdk_pointer_ungrab (event->time); @@ -2536,7 +2535,7 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, event_num); if (day_view->selection_drag_pos != E_DAY_VIEW_DRAG_NONE) { - e_day_view_update_selection (day_view, -1, day); + e_day_view_update_selection (day_view, day, -1); return TRUE; } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { if (pos != E_DAY_VIEW_POS_OUTSIDE) { @@ -2620,9 +2619,6 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, &event_x, &event_y)) return FALSE; - day_view->last_mouse_x = event_x; - day_view->last_mouse_y = event_y; - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), &scroll_x, &scroll_y); canvas_x = event_x + scroll_x; @@ -2638,14 +2634,16 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, if (day_view->selection_drag_pos != E_DAY_VIEW_DRAG_NONE) { if (pos != E_DAY_VIEW_POS_OUTSIDE) { - e_day_view_update_selection (day_view, row, day); - e_day_view_check_auto_scroll (day_view, event_y); + e_day_view_update_selection (day_view, day, row); + e_day_view_check_auto_scroll (day_view, + event_x, event_y); return TRUE; } } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { if (pos != E_DAY_VIEW_POS_OUTSIDE) { e_day_view_update_resize (day_view, row); - e_day_view_check_auto_scroll (day_view, event_y); + e_day_view_check_auto_scroll (day_view, + event_x, event_y); return TRUE; } } else if (day_view->pressed_event_day != -1 @@ -2705,45 +2703,81 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, } -static void +/* This sets the selection to a single cell. If day is -1 then the current + start day is reused. If row is -1 then the selection is in the top canvas. +*/ +void +e_day_view_start_selection (EDayView *day_view, + gint day, + gint row) +{ + if (day == -1) { + day = day_view->selection_start_day; + if (day == -1) + day = 0; + } + + day_view->selection_start_day = day; + day_view->selection_end_day = day; + + day_view->selection_start_row = row; + day_view->selection_end_row = row; + + day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; + day_view->selection_in_top_canvas = (row == -1) ? TRUE : FALSE; + + /* FIXME: Optimise? */ + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); +} + + +/* Updates the selection during a drag. If day is -1 the selection day is + unchanged. */ +void e_day_view_update_selection (EDayView *day_view, - gint row, - gint col) + gint day, + gint row) { - gint tmp_row, tmp_col; + gint tmp_row, tmp_day; gboolean need_redraw = FALSE; #if 0 - g_print ("Updating selection %i,%i\n", col, row); + g_print ("Updating selection %i,%i\n", day, row); #endif day_view->selection_in_top_canvas = (row == -1) ? TRUE : FALSE; + if (day == -1) + day = (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) + ? day_view->selection_start_day + : day_view->selection_end_day; + if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) { if (row != day_view->selection_start_row - || col != day_view->selection_start_col) { + || day != day_view->selection_start_day) { need_redraw = TRUE; day_view->selection_start_row = row; - day_view->selection_start_col = col; + day_view->selection_start_day = day; } } else { if (row != day_view->selection_end_row - || col != day_view->selection_end_col) { + || day != day_view->selection_end_day) { need_redraw = TRUE; day_view->selection_end_row = row; - day_view->selection_end_col = col; + day_view->selection_end_day = day; } } /* Switch the drag position if necessary. */ - if (day_view->selection_start_col > day_view->selection_end_col - || (day_view->selection_start_col == day_view->selection_end_col + if (day_view->selection_start_day > day_view->selection_end_day + || (day_view->selection_start_day == day_view->selection_end_day && day_view->selection_start_row > day_view->selection_end_row)) { tmp_row = day_view->selection_start_row; - tmp_col = day_view->selection_start_col; - day_view->selection_start_col = day_view->selection_end_col; + tmp_day = day_view->selection_start_day; + day_view->selection_start_day = day_view->selection_end_day; day_view->selection_start_row = day_view->selection_end_row; - day_view->selection_end_col = tmp_col; + day_view->selection_end_day = tmp_day; day_view->selection_end_row = tmp_row; if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; @@ -2759,6 +2793,14 @@ e_day_view_update_selection (EDayView *day_view, } +void +e_day_view_finish_selection (EDayView *day_view) +{ + day_view->selection_drag_pos = E_DAY_VIEW_DRAG_NONE; + e_day_view_update_calendar_selection_time (day_view); +} + + static void e_day_view_update_long_event_resize (EDayView *day_view, gint day) @@ -3808,9 +3850,16 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) return FALSE; } + if (day_view->selection_start_day == -1) + return FALSE; - if (day_view->selection_start_col == -1) + /* Check if there is room for a new event to be typed in. If there + isn't we don't want to add an event as we will then add a new + event for every key press. */ + if (!e_day_view_check_if_new_event_fits (day_view)) { + g_print ("Skipping new event. No more room\n"); return FALSE; + } /* We only want to start an edit with a return key or a simple character. */ @@ -3861,6 +3910,33 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) } +static gboolean +e_day_view_check_if_new_event_fits (EDayView *day_view) +{ + gint day, start_row, end_row, row; + + day = day_view->selection_start_day; + start_row = day_view->selection_start_row; + end_row = day_view->selection_end_row; + + /* Long events always fit, since we keep adding rows to the top + canvas. */ + if (day != day_view->selection_end_day) + return FALSE; + if (start_row == 0 && end_row == day_view->rows) + return FALSE; + + /* If any of the rows already have E_DAY_VIEW_MAX_COLUMNS columns, + return FALSE. */ + for (row = start_row; row <= end_row; row++) { + if (day_view->cols_per_row[day][row] >= E_DAY_VIEW_MAX_COLUMNS) + return FALSE; + } + + return TRUE; +} + + static void e_day_view_start_editing_event (EDayView *day_view, gint day, @@ -4160,10 +4236,14 @@ e_day_view_convert_time_to_grid_position (EDayView *day_view, /* This starts or stops auto-scrolling when dragging a selection or resizing an event. */ -static void +void e_day_view_check_auto_scroll (EDayView *day_view, + gint event_x, gint event_y) { + day_view->last_mouse_x = event_x; + day_view->last_mouse_y = event_y; + if (event_y < E_DAY_VIEW_AUTO_SCROLL_OFFSET) e_day_view_start_auto_scroll (day_view, TRUE); else if (event_y >= day_view->main_canvas->allocation.height @@ -4186,7 +4266,7 @@ e_day_view_start_auto_scroll (EDayView *day_view, } -static void +void e_day_view_stop_auto_scroll (EDayView *day_view) { if (day_view->auto_scroll_timeout_id != 0) { @@ -4241,14 +4321,23 @@ e_day_view_auto_scroll_handler (gpointer data) canvas_x = day_view->last_mouse_x + scroll_x; canvas_y = day_view->last_mouse_y + new_scroll_y; + /* The last_mouse_x position is set to -1 when we are selecting using + the time column. In this case we set canvas_x to 0 and we ignore + the resulting day. */ + if (day_view->last_mouse_x == -1) + canvas_x = 0; + /* Update the selection/resize/drag if necessary. */ pos = e_day_view_convert_position_in_main_canvas (day_view, canvas_x, canvas_y, &day, &row, NULL); + if (day_view->last_mouse_x == -1) + day = -1; + if (pos != E_DAY_VIEW_POS_OUTSIDE) { if (day_view->selection_drag_pos != E_DAY_VIEW_DRAG_NONE) { - e_day_view_update_selection (day_view, row, day); + e_day_view_update_selection (day_view, day, row); } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { e_day_view_update_resize (day_view, row); } else if (day_view->drag_item->object.flags @@ -4675,9 +4764,6 @@ e_day_view_on_main_canvas_drag_motion (GtkWidget *widget, { gint scroll_x, scroll_y; - day_view->last_mouse_x = x; - day_view->last_mouse_y = y; - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), &scroll_x, &scroll_y); day_view->drag_event_x = x + scroll_x; @@ -4686,7 +4772,7 @@ e_day_view_on_main_canvas_drag_motion (GtkWidget *widget, e_day_view_reshape_main_canvas_drag_item (day_view); e_day_view_reshape_main_canvas_resize_bars (day_view); - e_day_view_check_auto_scroll (day_view, y); + e_day_view_check_auto_scroll (day_view, x, y); return TRUE; } |