diff options
Diffstat (limited to 'calendar/gui')
-rw-r--r-- | calendar/gui/e-cal-view.c | 71 | ||||
-rw-r--r-- | calendar/gui/e-cal-view.h | 14 | ||||
-rw-r--r-- | calendar/gui/e-calendar-view.c | 71 | ||||
-rw-r--r-- | calendar/gui/e-calendar-view.h | 14 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 197 | ||||
-rw-r--r-- | calendar/gui/e-day-view.h | 3 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 400 | ||||
-rw-r--r-- | calendar/gui/e-week-view.h | 3 |
8 files changed, 575 insertions, 198 deletions
diff --git a/calendar/gui/e-cal-view.c b/calendar/gui/e-cal-view.c index 1f65723d2b..1aade80154 100644 --- a/calendar/gui/e-cal-view.c +++ b/calendar/gui/e-cal-view.c @@ -97,6 +97,7 @@ enum { EVENT_CHANGED, EVENT_ADDED, OPEN_EVENT, + EVENT_MOVE, LAST_SIGNAL }; @@ -166,6 +167,7 @@ e_calendar_view_class_init (ECalendarViewClass *klass) klass->get_visible_time_range = NULL; klass->update_query = NULL; klass->open_event = e_calendar_view_open_event; + klass->event_move = NULL; g_object_class_install_property (gobject_class, PROP_MODEL, g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL, @@ -227,6 +229,16 @@ e_calendar_view_class_init (ECalendarViewClass *klass) G_TYPE_NONE, 1, G_TYPE_POINTER); + e_calendar_view_signals [EVENT_MOVE] = + g_signal_new ("event_move", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalendarViewClass, event_move), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); + /* clipboard atom */ if (!clipboard_atom) clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); @@ -242,6 +254,48 @@ e_calendar_view_class_init (ECalendarViewClass *klass) GDK_CONTROL_MASK, "open_event", 0); + /* Alt+Arrow, move the editing event*/ + gtk_binding_entry_add_signal (binding_set, GDK_Up, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_UP); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_UP); + gtk_binding_entry_add_signal (binding_set, GDK_Down, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_DOWN); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_DOWN); + gtk_binding_entry_add_signal (binding_set, GDK_Left, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_LEFT); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_LEFT); + gtk_binding_entry_add_signal (binding_set, GDK_Right, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_RIGHT); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_RIGHT); + /* init the accessibility support for e_day_view */ e_cal_view_a11y_init (); } @@ -1520,3 +1574,20 @@ e_calendar_view_edit_appointment (ECalendarView *cal_view, comp_editor_focus (ce); } + +void +e_calendar_view_modify_and_send (ECalComponent *comp, + ECal *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean new) +{ + if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { + if (itip_organizer_is_user (comp, client) && + send_component_dialog (toplevel, client, comp, new)) { + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL); + } else { + g_message (G_STRLOC ": Could not update the object!"); + } + } +} diff --git a/calendar/gui/e-cal-view.h b/calendar/gui/e-cal-view.h index c224098554..ebd830c9a0 100644 --- a/calendar/gui/e-cal-view.h +++ b/calendar/gui/e-cal-view.h @@ -25,6 +25,7 @@ #include <libecal/e-cal.h> #include <gtk/gtktable.h> +#include <gtk/gtkwindow.h> #include "e-cal-model.h" #include "gnome-cal.h" @@ -48,6 +49,13 @@ typedef enum { E_CALENDAR_VIEW_POS_BOTTOM_EDGE } ECalendarViewPosition; +typedef enum { + E_CAL_VIEW_MOVE_UP, + E_CAL_VIEW_MOVE_DOWN, + E_CAL_VIEW_MOVE_LEFT, + E_CAL_VIEW_MOVE_RIGHT +} ECalViewMoveDirection; + #define E_CALENDAR_VIEW_EVENT_FIELDS \ GnomeCanvasItem *canvas_item; \ ECalModelComponent *comp_data; \ @@ -88,6 +96,7 @@ struct _ECalendarViewClass { gboolean (* get_visible_time_range) (ECalendarView *cal_view, time_t *start_time, time_t *end_time); void (* update_query) (ECalendarView *cal_view); void (* open_event) (ECalendarView *cal_view); + void (* event_move) (ECalendarView *cal_view, ECalViewMoveDirection direction); }; GType e_calendar_view_get_type (void); @@ -133,6 +142,11 @@ void e_calendar_view_edit_appointment (ECalendarView *cal_view, icalcomponent *icalcomp, gboolean meeting); void e_calendar_view_open_event (ECalendarView *cal_view); +void e_calendar_view_modify_and_send (ECalComponent *comp, + ECal *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean new); G_END_DECLS diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 1f65723d2b..1aade80154 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -97,6 +97,7 @@ enum { EVENT_CHANGED, EVENT_ADDED, OPEN_EVENT, + EVENT_MOVE, LAST_SIGNAL }; @@ -166,6 +167,7 @@ e_calendar_view_class_init (ECalendarViewClass *klass) klass->get_visible_time_range = NULL; klass->update_query = NULL; klass->open_event = e_calendar_view_open_event; + klass->event_move = NULL; g_object_class_install_property (gobject_class, PROP_MODEL, g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL, @@ -227,6 +229,16 @@ e_calendar_view_class_init (ECalendarViewClass *klass) G_TYPE_NONE, 1, G_TYPE_POINTER); + e_calendar_view_signals [EVENT_MOVE] = + g_signal_new ("event_move", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalendarViewClass, event_move), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); + /* clipboard atom */ if (!clipboard_atom) clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); @@ -242,6 +254,48 @@ e_calendar_view_class_init (ECalendarViewClass *klass) GDK_CONTROL_MASK, "open_event", 0); + /* Alt+Arrow, move the editing event*/ + gtk_binding_entry_add_signal (binding_set, GDK_Up, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_UP); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_UP); + gtk_binding_entry_add_signal (binding_set, GDK_Down, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_DOWN); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_DOWN); + gtk_binding_entry_add_signal (binding_set, GDK_Left, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_LEFT); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_LEFT); + gtk_binding_entry_add_signal (binding_set, GDK_Right, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_RIGHT); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, + GDK_MOD1_MASK, + "event_move", 1, + G_TYPE_ENUM, + E_CAL_VIEW_MOVE_RIGHT); + /* init the accessibility support for e_day_view */ e_cal_view_a11y_init (); } @@ -1520,3 +1574,20 @@ e_calendar_view_edit_appointment (ECalendarView *cal_view, comp_editor_focus (ce); } + +void +e_calendar_view_modify_and_send (ECalComponent *comp, + ECal *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean new) +{ + if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { + if (itip_organizer_is_user (comp, client) && + send_component_dialog (toplevel, client, comp, new)) { + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL); + } else { + g_message (G_STRLOC ": Could not update the object!"); + } + } +} diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h index c224098554..ebd830c9a0 100644 --- a/calendar/gui/e-calendar-view.h +++ b/calendar/gui/e-calendar-view.h @@ -25,6 +25,7 @@ #include <libecal/e-cal.h> #include <gtk/gtktable.h> +#include <gtk/gtkwindow.h> #include "e-cal-model.h" #include "gnome-cal.h" @@ -48,6 +49,13 @@ typedef enum { E_CALENDAR_VIEW_POS_BOTTOM_EDGE } ECalendarViewPosition; +typedef enum { + E_CAL_VIEW_MOVE_UP, + E_CAL_VIEW_MOVE_DOWN, + E_CAL_VIEW_MOVE_LEFT, + E_CAL_VIEW_MOVE_RIGHT +} ECalViewMoveDirection; + #define E_CALENDAR_VIEW_EVENT_FIELDS \ GnomeCanvasItem *canvas_item; \ ECalModelComponent *comp_data; \ @@ -88,6 +96,7 @@ struct _ECalendarViewClass { gboolean (* get_visible_time_range) (ECalendarView *cal_view, time_t *start_time, time_t *end_time); void (* update_query) (ECalendarView *cal_view); void (* open_event) (ECalendarView *cal_view); + void (* event_move) (ECalendarView *cal_view, ECalViewMoveDirection direction); }; GType e_calendar_view_get_type (void); @@ -133,6 +142,11 @@ void e_calendar_view_edit_appointment (ECalendarView *cal_view, icalcomponent *icalcomp, gboolean meeting); void e_calendar_view_open_event (ECalendarView *cal_view); +void e_calendar_view_modify_and_send (ECalComponent *comp, + ECal *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean new); G_END_DECLS diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index d4e436dc6d..bdf3483c62 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -342,6 +342,9 @@ static void e_day_view_stop_editing_event (EDayView *day_view); static gboolean e_day_view_on_text_item_event (GnomeCanvasItem *item, GdkEvent *event, EDayView *day_view); +static void e_day_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction); +static void e_day_view_change_event_time (EDayView *day_view, time_t start_dt, +time_t end_dt); static void e_day_view_change_event_end_time_up (EDayView *day_view); static void e_day_view_change_event_end_time_down (EDayView *day_view); static void e_day_view_on_editing_started (EDayView *day_view, @@ -476,6 +479,7 @@ e_day_view_class_init (EDayViewClass *class) view_class->set_selected_time_range = e_day_view_set_selected_time_range; view_class->get_visible_time_range = e_day_view_get_visible_time_range; view_class->update_query = e_day_view_update_query; + view_class->event_move = e_day_view_event_move; /* init the accessibility support for e_day_view */ e_day_view_a11y_init (); @@ -573,6 +577,8 @@ e_day_view_init (EDayView *day_view) day_view->resize_bars_event_day = -1; day_view->resize_bars_event_num = -1; + day_view->last_edited_comp_string = NULL; + day_view->selection_start_row = -1; day_view->selection_start_day = -1; day_view->selection_end_row = -1; @@ -3759,14 +3765,7 @@ e_day_view_finish_long_event_resize (EDayView *day_view) toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) && - send_component_dialog (toplevel, client, comp, TRUE)) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL); - } else { - g_message (G_STRLOC ": Could not update the object!"); - } - } + e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); out: gnome_canvas_item_hide (day_view->resize_long_event_rect_item); @@ -3822,6 +3821,9 @@ e_day_view_finish_resize (EDayView *day_view) e_cal_component_set_dtend (comp, &date); } + e_cal_component_commit_sequence (comp); + day_view->last_edited_comp_string = e_cal_component_get_as_string (comp); + gnome_canvas_item_hide (day_view->resize_rect_item); gnome_canvas_item_hide (day_view->resize_bar_item); @@ -3843,14 +3845,7 @@ e_day_view_finish_resize (EDayView *day_view) toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); e_cal_component_commit_sequence (comp); - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) && - send_component_dialog (toplevel, client, comp, TRUE)) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL); - } else { - g_message (G_STRLOC ": Could not update the object!"); - } - } + e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); out: g_object_unref (comp); @@ -4293,12 +4288,17 @@ e_day_view_reshape_day_events (EDayView *day_view, for (event_num = 0; event_num < day_view->events[day]->len; event_num++) { + EDayViewEvent *event; + gchar *current_comp_string; + e_day_view_reshape_day_event (day_view, day, event_num); - if (event_num == day_view->resize_event_num) { - EDayViewEvent *event; - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); + event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); + current_comp_string = icalcomponent_as_ical_string (event->comp_data->icalcomp); + if (day_view->last_edited_comp_string == NULL) + continue; + if (strncmp (current_comp_string, day_view->last_edited_comp_string,50) == 0) { e_canvas_item_grab_focus (event->canvas_item, TRUE); + day_view-> last_edited_comp_string = NULL; } } } @@ -5549,6 +5549,142 @@ e_day_view_on_text_item_event (GnomeCanvasItem *item, } static void +e_day_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction) +{ + EDayViewEvent *event; + EDayView *day_view; + gint day, event_num, resize_start_row, resize_end_row; + time_t start_dt, end_dt; + struct icaltimetype start_time, end_time; + + day_view = E_DAY_VIEW (cal_view); + day = day_view->editing_event_day; + event_num = day_view->editing_event_num; + + if ((day == -1) || (day == E_DAY_VIEW_LONG_EVENT)) + return; + + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + day_view->resize_event_day = day; + day_view->resize_event_num = event_num; + day_view->resize_bars_event_day = day; + day_view->resize_bars_event_num = event_num; + resize_start_row = event->start_minute / day_view->mins_per_row; + resize_end_row = (event->end_minute - 1) / day_view->mins_per_row; + if (resize_end_row < resize_start_row) + resize_end_row = resize_start_row; + + switch (direction) { + case E_CAL_VIEW_MOVE_UP: + if (resize_start_row <= 0) + return; + resize_start_row--; + resize_end_row--; + start_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_start_row); + end_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_end_row + 1); + break; + case E_CAL_VIEW_MOVE_DOWN: + if (resize_end_row >= day_view->rows - 1) + return; + resize_start_row++; + resize_end_row++; + start_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_start_row); + end_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_end_row + 1); + break; + case E_CAL_VIEW_MOVE_LEFT: + if (day <= 0) + return; + start_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_start_row); + end_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_end_row + 1); + start_time = icaltime_from_timet (start_dt, 0); + end_time = icaltime_from_timet (end_dt, 0); + icaltime_adjust (&start_time ,-1,0,0,0); + icaltime_adjust (&end_time ,-1,0,0,0); + start_dt = icaltime_as_timet (start_time); + end_dt = icaltime_as_timet (end_time); + break; + case E_CAL_VIEW_MOVE_RIGHT: + if (day + 1 >= day_view->days_shown) + return; + start_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_start_row); + end_dt = e_day_view_convert_grid_position_to_time (day_view, day, resize_end_row + 1); + start_time = icaltime_from_timet (start_dt, 0); + end_time = icaltime_from_timet (end_dt, 0); + icaltime_adjust (&start_time ,1,0,0,0); + icaltime_adjust (&end_time ,1,0,0,0); + start_dt = icaltime_as_timet (start_time); + end_dt = icaltime_as_timet (end_time); + break; + default: + break; + } + + e_day_view_change_event_time (day_view, start_dt, end_dt); + e_day_view_ensure_rows_visible (day_view, resize_start_row, resize_end_row); +} + +static void +e_day_view_change_event_time (EDayView *day_view, time_t start_dt, time_t end_dt) +{ + EDayViewEvent *event; + gint day, event_num; + ECalComponent *comp; + ECalComponentDateTime date; + struct icaltimetype itt; + ECal *client; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; + + day = day_view->editing_event_day; + event_num = day_view->editing_event_num; + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + client = event->comp_data->client; + + /* We use a temporary shallow copy of the ico since we don't want to + change the original ico here. Otherwise we would not detect that + the event's time had changed in the "update_event" callback. */ + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + date.value = &itt; + /* FIXME: Should probably keep the timezone of the original start + and end times. */ + date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + + *date.value = icaltime_from_timet_with_zone (start_dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtstart (comp, &date); + *date.value = icaltime_from_timet_with_zone (end_dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtend (comp, &date); + + e_cal_component_commit_sequence (comp); + day_view->last_edited_comp_string = e_cal_component_get_as_string (comp); + + gnome_canvas_item_hide (day_view->resize_rect_item); + gnome_canvas_item_hide (day_view->resize_bar_item); + + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; + + if (e_cal_component_has_recurrences (comp)) { + if (!recur_component_dialog (client, comp, &mod, NULL)) { + gtk_widget_queue_draw (day_view->top_canvas); + goto out; + } + } + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + + e_cal_component_commit_sequence (comp); + e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); + +out: + g_object_unref (comp); +} + +static void e_day_view_change_event_end_time_up (EDayView *day_view) { EDayViewEvent *event; @@ -5750,12 +5886,7 @@ e_day_view_on_editing_stopped (EDayView *day_view, /* FIXME When sending here, what exactly should we send? */ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - if (e_cal_modify_object (client, icalcomp, mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } + e_calendar_view_modify_and_send (comp, client, mod, toplevel, FALSE); } } @@ -6860,12 +6991,7 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); e_cal_component_commit_sequence (comp); - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } + e_calendar_view_modify_and_send (comp, client, mod, toplevel, FALSE); g_object_unref (comp); @@ -7056,12 +7182,7 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); e_cal_component_commit_sequence (comp); - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } + e_calendar_view_modify_and_send (comp, client, mod, toplevel, FALSE); g_object_unref (comp); diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h index 7907b80d18..e68279d123 100644 --- a/calendar/gui/e-day-view.h +++ b/calendar/gui/e-day-view.h @@ -409,6 +409,9 @@ struct _EDayView gint resize_start_row; gint resize_end_row; + /* This is used to remember the last edited event. */ + gchar *last_edited_comp_string; + /* This is the event the mouse button was pressed on. If the button is released we start editing it, but if the mouse is dragged we set this to -1. */ diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index 79c9d0539a..cc4019d4a5 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -177,16 +177,22 @@ static void e_week_view_foreach_event_with_uid (EWeekView *week_view, static gboolean e_week_view_on_text_item_event (GnomeCanvasItem *item, GdkEvent *event, EWeekView *week_view); +static void e_week_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction); +static gint e_week_view_get_day_offset_of_event (EWeekView *week_view, time_t event_time); +static void e_week_view_scroll_a_step (EWeekView *week_view, ECalViewMoveDirection direction); +static void e_week_view_change_event_time (EWeekView *week_view, time_t start_dt, time_t end_dt); static gboolean e_week_view_on_jump_button_event (GnomeCanvasItem *item, GdkEvent *event, EWeekView *week_view); static gboolean e_week_view_key_press (GtkWidget *widget, GdkEventKey *event); static gboolean e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event); -static void e_week_view_on_key_up (EWeekView *week_view, GdkEventKey *event); -static void e_week_view_on_key_down (EWeekView *week_view, GdkEventKey *event); -static void e_week_view_on_key_left (EWeekView *week_view, GdkEventKey *event); -static void e_week_view_on_key_right (EWeekView *week_view, GdkEventKey *event); +static void e_week_view_move_selection_day (EWeekView *week_view, ECalViewMoveDirection direction); +static gint e_week_view_get_adjust_days_for_move_up (EWeekView *week_view, gint +current_day); +static gint e_week_view_get_adjust_days_for_move_down (EWeekView *week_view,gint current_day); +static gint e_week_view_get_adjust_days_for_move_left (EWeekView *week_view,gint current_day); +static gint e_week_view_get_adjust_days_for_move_right (EWeekView *week_view,gint current_day); static gboolean e_week_view_popup_menu (GtkWidget *widget); static gboolean e_week_view_update_event_cb (EWeekView *week_view, @@ -237,6 +243,7 @@ e_week_view_class_init (EWeekViewClass *class) view_class->set_selected_time_range = e_week_view_set_selected_time_range; view_class->get_visible_time_range = e_week_view_get_visible_time_range; view_class->update_query = e_week_view_update_query; + view_class->event_move = e_week_view_event_move; /* init the accessibility support for e_week_view */ e_week_view_a11y_init (); @@ -311,6 +318,8 @@ e_week_view_init (EWeekView *week_view) week_view->pressed_event_num = -1; week_view->editing_event_num = -1; + week_view->last_edited_comp_string = NULL; + week_view->main_gc = NULL; /* Create the small font. */ @@ -2371,8 +2380,19 @@ e_week_view_reshape_events (EWeekView *week_view) event = &g_array_index (week_view->events, EWeekViewEvent, event_num); for (span_num = 0; span_num < event->num_spans; span_num++) { + gchar *current_comp_string; + e_week_view_reshape_event_span (week_view, event_num, span_num); + current_comp_string = icalcomponent_as_ical_string (event->comp_data->icalcomp); + if (week_view->last_edited_comp_string == NULL) + continue; + if (strncmp (current_comp_string, week_view->last_edited_comp_string,50) == 0) { + EWeekViewEventSpan *span; + span = &g_array_index (week_view->spans, EWeekViewEventSpan, event->spans_index + span_num); + e_canvas_item_grab_focus (span->text_item, TRUE); + week_view->last_edited_comp_string = NULL; + } } } @@ -2950,6 +2970,161 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item, return FALSE; } +static void e_week_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction) +{ + EWeekViewEvent *event; + gint event_num, span_num, adjust_days, current_start_day, current_end_day; + time_t start_dt, end_dt; + struct icaltimetype start_time,end_time; + EWeekView *week_view = E_WEEK_VIEW (cal_view); + + event_num = week_view->editing_event_num; + span_num = week_view->editing_span_num; + adjust_days = 0; + + /* If no item is being edited, just return. */ + if (event_num == -1) + return; + + event = &g_array_index (week_view->events, EWeekViewEvent, event_num); + start_dt = event->start; + end_dt = event->end; + start_time = icaltime_from_timet (start_dt, 0); + end_time = icaltime_from_timet (end_dt, 0); + current_end_day = e_week_view_get_day_offset_of_event (week_view,end_dt); + + switch (direction) { + case E_CAL_VIEW_MOVE_UP: + adjust_days = e_week_view_get_adjust_days_for_move_up (week_view,current_end_day); + break; + case E_CAL_VIEW_MOVE_DOWN: + adjust_days = e_week_view_get_adjust_days_for_move_down (week_view,current_end_day); + break; + case E_CAL_VIEW_MOVE_LEFT: + adjust_days = e_week_view_get_adjust_days_for_move_left (week_view,current_end_day); + break; + case E_CAL_VIEW_MOVE_RIGHT: + adjust_days = e_week_view_get_adjust_days_for_move_right (week_view,current_end_day); + break; + default: + break; + } + + icaltime_adjust (&start_time ,adjust_days,0,0,0); + icaltime_adjust (&end_time ,adjust_days,0,0,0); + start_dt = icaltime_as_timet (start_time); + end_dt = icaltime_as_timet (end_time); + + current_start_day = e_week_view_get_day_offset_of_event (week_view,start_dt); + current_end_day = e_week_view_get_day_offset_of_event (week_view,end_dt); + + if (current_start_day < 0) { + return; + } + if (week_view->multi_week_view) { + if (current_end_day > week_view->weeks_shown * 7) { + return; + } + }else { + if (current_end_day >= 7) { + return; + } + } + + e_week_view_change_event_time (week_view, start_dt, end_dt); +} + +static gint +e_week_view_get_day_offset_of_event (EWeekView *week_view, time_t event_time) +{ + struct tm first_day_shown_tm = {0}; + struct tm *event_time_tm; + + event_time_tm = NULL; + + g_date_to_struct_tm (&(week_view->first_day_shown), &first_day_shown_tm); + event_time_tm = gmtime (&event_time); + return (event_time_tm->tm_yday - first_day_shown_tm.tm_yday); +} + +static void +e_week_view_scroll_a_step (EWeekView *week_view, ECalViewMoveDirection direction) +{ + GtkAdjustment *adj = GTK_RANGE (week_view->vscrollbar)->adjustment; + gfloat new_value; + + switch (direction){ + case E_CAL_VIEW_MOVE_UP: + new_value = adj->value - adj->step_increment; + break; + case E_CAL_VIEW_MOVE_DOWN: + new_value = adj->value + adj->step_increment; + break; + default: + break; + } + + new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size); + gtk_adjustment_set_value (adj, new_value); +} + +static void +e_week_view_change_event_time (EWeekView *week_view, time_t start_dt, time_t end_dt) +{ + EWeekViewEvent *event; + gint event_num; + ECalComponent *comp; + ECalComponentDateTime date; + struct icaltimetype itt; + ECal *client; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; + + event_num = week_view->editing_event_num; + + /* If no item is being edited, just return. */ + if (event_num == -1) + return; + + event = &g_array_index (week_view->events, EWeekViewEvent, event_num); + client = event->comp_data->client; + + /* We use a temporary shallow copy of the ico since we don't want to + change the original ico here. Otherwise we would not detect that + the event's time had changed in the "update_event" callback. */ + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + date.value = &itt; + /* FIXME: Should probably keep the timezone of the original start + and end times. */ + date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + + *date.value = icaltime_from_timet_with_zone (start_dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + e_cal_component_set_dtstart (comp, &date); + *date.value = icaltime_from_timet_with_zone (end_dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + e_cal_component_set_dtend (comp, &date); + + e_cal_component_commit_sequence (comp); + week_view->last_edited_comp_string = e_cal_component_get_as_string (comp); + + + if (e_cal_component_has_recurrences (comp)) { + if (!recur_component_dialog (client, comp, &mod, NULL)) { + gtk_widget_queue_draw (week_view->main_canvas); + goto out; + } + } + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (week_view))); + + e_cal_component_commit_sequence (comp); + e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); + +out: + g_object_unref (comp); +} static void e_week_view_on_editing_started (EWeekView *week_view, @@ -3065,12 +3240,7 @@ e_week_view_on_editing_stopped (EWeekView *week_view, /* FIXME When sending here, what exactly should we send? */ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (week_view))); - if (e_cal_modify_object (client, icalcomp, mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } + e_calendar_view_modify_and_send (comp, client, mod, toplevel, FALSE); } } @@ -3206,22 +3376,26 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event) #endif /*Navigation through days with arrow keys*/ + if (!((event->state & GDK_SHIFT_MASK) + ||(event->state & GDK_CONTROL_MASK) + ||(event->state & GDK_MOD1_MASK))) { switch (event->keyval) { case GDK_Up: - e_week_view_on_key_up (week_view, event); + e_week_view_move_selection_day (week_view,E_CAL_VIEW_MOVE_UP); return TRUE; case GDK_Down: - e_week_view_on_key_down (week_view, event); + e_week_view_move_selection_day (week_view,E_CAL_VIEW_MOVE_DOWN); return TRUE; case GDK_Left: - e_week_view_on_key_left (week_view, event); + e_week_view_move_selection_day (week_view,E_CAL_VIEW_MOVE_LEFT); return TRUE; case GDK_Right: - e_week_view_on_key_right (week_view, event); + e_week_view_move_selection_day (week_view,E_CAL_VIEW_MOVE_RIGHT); return TRUE; default: break; } + } if (week_view->selection_start_day == -1) return FALSE; @@ -3291,7 +3465,7 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event) } static void -e_week_view_on_key_up (EWeekView *week_view, GdkEventKey *event) +e_week_view_move_selection_day (EWeekView *week_view, ECalViewMoveDirection direction) { gint selection_start_day, selection_end_day; @@ -3303,24 +3477,37 @@ e_week_view_on_key_up (EWeekView *week_view, GdkEventKey *event) selection_end_day = 0; } - if (week_view->multi_week_view) { - if (selection_end_day < 7) { - g_date_subtract_days (&(week_view->first_day_shown), 7); - } else - selection_end_day -= 7; - } - else { - if (selection_start_day == selection_end_day) { - if (selection_end_day == 0) { - g_date_subtract_days (&(week_view->first_day_shown), 7); - selection_end_day = 6; - } else - selection_end_day--; - } else { - selection_end_day = - (selection_start_day + selection_end_day)/2; - } - } + switch (direction) { + case E_CAL_VIEW_MOVE_UP: + selection_end_day += e_week_view_get_adjust_days_for_move_up (week_view,selection_end_day); + break; + case E_CAL_VIEW_MOVE_DOWN: + selection_end_day += e_week_view_get_adjust_days_for_move_down (week_view,selection_end_day); + break; + case E_CAL_VIEW_MOVE_LEFT: + selection_end_day += e_week_view_get_adjust_days_for_move_left (week_view,selection_end_day); + break; + case E_CAL_VIEW_MOVE_RIGHT: + selection_end_day += e_week_view_get_adjust_days_for_move_right (week_view,selection_end_day); + break; + default: + break; + } + if (selection_end_day < 0) { + e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_UP); + selection_end_day +=7; + } + if (week_view->multi_week_view) { + if (selection_end_day >= week_view->weeks_shown * 7) { + e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_DOWN); + selection_end_day -=7; + } + }else { + if (selection_end_day >= 7) { + e_week_view_scroll_a_step (week_view, E_CAL_VIEW_MOVE_DOWN); + selection_end_day -=7; + } + } week_view->selection_start_day = selection_end_day; week_view->selection_end_day = selection_end_day; @@ -3329,141 +3516,34 @@ e_week_view_on_key_up (EWeekView *week_view, GdkEventKey *event) g_signal_emit_by_name (week_view, "selected_time_changed"); } -static void -e_week_view_on_key_down (EWeekView *week_view, GdkEventKey *event) +static gint +e_week_view_get_adjust_days_for_move_up (EWeekView *week_view,gint current_day) { - gint selection_start_day, selection_end_day; - - selection_start_day = week_view->selection_start_day; - selection_end_day = week_view->selection_end_day; - - if (selection_start_day == -1) { - selection_start_day = 0; - selection_end_day = 0; - } - - if (week_view->multi_week_view) { - if ((selection_end_day+7) / 7 >= week_view->weeks_shown) { - g_date_add_days (&(week_view->first_day_shown), 7); - } else - selection_end_day += 7; - } - else { - if (selection_start_day == selection_end_day) { - if (selection_end_day == 6) { - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day = 0; - } else - selection_end_day++; - } else { - selection_end_day = - (selection_start_day + selection_end_day)/2; - } - } - - week_view->selection_start_day = selection_end_day; - week_view->selection_end_day = selection_end_day; - - gtk_widget_queue_draw (week_view->main_canvas); - g_signal_emit_by_name (week_view, "selected_time_changed"); + if (week_view->multi_week_view) + return -7; + else + return 0; } -static void -e_week_view_on_key_left (EWeekView *week_view, GdkEventKey *event) +static gint +e_week_view_get_adjust_days_for_move_down (EWeekView *week_view,gint current_day) { - gint selection_start_day, selection_end_day; - - selection_start_day = week_view->selection_start_day; - selection_end_day = week_view->selection_end_day; - - if (selection_start_day == -1) { - selection_start_day = 0; - selection_end_day = 0; - } - - if (week_view->multi_week_view) { - if (selection_end_day == 0) { - g_date_subtract_days (&(week_view->first_day_shown), 7); - selection_end_day = 6; - } else - selection_end_day -= 1; - } - else { - switch (selection_end_day) { - case 0: - case 1: - case 2: - g_date_subtract_days (&(week_view->first_day_shown), 7); - selection_end_day += 3; - break; - case 3: - case 4: - case 5: - selection_end_day -= 3; - break; - case 6: - selection_end_day -= 4; - break; - default: - break; - } - } - - week_view->selection_start_day = selection_end_day; - week_view->selection_end_day = selection_end_day; - - gtk_widget_queue_draw (week_view->main_canvas); - g_signal_emit_by_name (week_view, "selected_time_changed"); + if (week_view->multi_week_view) + return 7; + else + return 0; } -static void -e_week_view_on_key_right (EWeekView *week_view, GdkEventKey *event) +static gint +e_week_view_get_adjust_days_for_move_left (EWeekView *week_view,gint current_day) { + return -1; +} - gint selection_start_day, selection_end_day; - - selection_start_day = week_view->selection_start_day; - selection_end_day = week_view->selection_end_day; - - if (selection_start_day == -1) { - selection_start_day = 0; - selection_end_day = 0; - } - - if (week_view->multi_week_view) { - if (selection_end_day == week_view->weeks_shown*7 -1 ) { - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day -= 6; - } else - selection_end_day++; - } - else { - switch (selection_end_day) { - case 0: - case 1: - case 2: - selection_end_day += 3; - break; - case 3: - case 4: - case 5: - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day -= 3; - break; - case 6: - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day -= 4; - break; - default: - break; - } - } - - week_view->selection_start_day = selection_end_day; - week_view->selection_end_day = selection_end_day; - - gtk_widget_queue_draw (week_view->main_canvas); - g_signal_emit_by_name (week_view, "selected_time_changed"); +static gint +e_week_view_get_adjust_days_for_move_right (EWeekView *week_view,gint current_day) +{ + return 1; } static gboolean diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h index aca3f2bc2a..b5734fa35a 100644 --- a/calendar/gui/e-week-view.h +++ b/calendar/gui/e-week-view.h @@ -316,6 +316,9 @@ struct _EWeekView gint editing_event_num; gint editing_span_num; + /* This is used to remember the last edited event. */ + gchar *last_edited_comp_string; + /* The event that the context menu is for. */ gint popup_event_num; |