diff --git a/src/gcal-edit-dialog.h b/src/gcal-edit-dialog.h index 17b5253e..9bfee768 100644 --- a/src/gcal-edit-dialog.h +++ b/src/gcal-edit-dialog.h @@ -57,6 +57,8 @@ GDateTime* gcal_edit_dialog_get_date_start (GcalEditDialog *d gboolean gcal_edit_dialog_get_recurrence_changed (GcalEditDialog *self); +GcalRecurrenceModType gcal_edit_dialog_get_recurrence_mod_type (GcalEditDialog *self); + G_END_DECLS #endif /* __GCAL_EDIT_DIALOG_H__ */ diff --git a/src/gcal-utils.c b/src/gcal-utils.c index cbe91595..09cd87fb 100644 --- a/src/gcal-utils.c +++ b/src/gcal-utils.c @@ -1314,3 +1314,92 @@ is_workday (guint day) return !(no_work_days & 1 << day); } + +GList* +filter_event_list_by_uid_and_modtype (GList *widgets, + GcalRecurrenceModType mod, + const gchar *uid) +{ + GcalEvent *event; + GList *result; + GList *l; + + event = NULL; + result = NULL; + + g_message ("Checking for %s", uid); + + /* First pass: find the GcalEvent */ + for (l = widgets; l != NULL; l = l->next) + { + GcalEventWidget *event_widget; + GcalEvent *ev; + + event_widget = l->data; + + /* Safeguard against stray widgets */ + if (!GCAL_IS_EVENT_WIDGET (event_widget)) + continue; + + ev = gcal_event_widget_get_event (event_widget); + + /* + * We can assume only one event will have the exact uuid. Even among + * recurrencies. + */ + if (g_str_equal (uid, gcal_event_get_uid (ev))) + { + result = g_list_prepend (result, event_widget); + event = ev; + } + } + + /* Second pass: find the other related events */ + if (event && mod != GCAL_RECURRENCE_MOD_THIS_ONLY) + { + ECalComponentId *id; + ECalComponent *component; + ESource *source; + g_autofree gchar *id_prefix; + + component = gcal_event_get_component (event); + source = gcal_event_get_source (event); + id = e_cal_component_get_id (component); + id_prefix = g_strdup_printf ("%s:%s", e_source_get_uid (source), id->uid); + + for (l = widgets; l != NULL; l = l->next) + { + GcalEventWidget *event_widget; + GcalEvent *ev; + + event_widget = l->data; + + /* Safeguard against stray widgets */ + if (!GCAL_IS_EVENT_WIDGET (event_widget)) + continue; + + ev = gcal_event_widget_get_event (event_widget); + + if (g_str_equal (gcal_event_get_uid (ev), uid)) + continue; + + if (!g_str_has_prefix (gcal_event_get_uid (ev), id_prefix)) + continue; + + if (mod == GCAL_RECURRENCE_MOD_ALL) + { + result = g_list_prepend (result, event_widget); + } + else if (mod == GCAL_RECURRENCE_MOD_THIS_AND_FUTURE) + { + if (g_date_time_compare (gcal_event_get_date_start (event), gcal_event_get_date_start (ev)) < 0) + result = g_list_prepend (result, event_widget); + } + + } + + e_cal_component_free_id (id); + } + + return result; +} diff --git a/src/gcal-utils.h b/src/gcal-utils.h index 3be75771..4499e321 100644 --- a/src/gcal-utils.h +++ b/src/gcal-utils.h @@ -157,4 +157,8 @@ gboolean ask_recurrence_modification_type (GtkWidget gboolean is_workday (guint day); +GList* filter_event_list_by_uid_and_modtype (GList *widgets, + GcalRecurrenceModType mod, + const gchar *uid); + #endif // __GCAL_UTILS_H__ diff --git a/src/gcal-view.c b/src/gcal-view.c index efcbb1f8..f6fd54cb 100644 --- a/src/gcal-view.c +++ b/src/gcal-view.c @@ -134,11 +134,12 @@ gcal_view_clear_marks (GcalView *view) * Returns: (transfer full): a {@link GList} instance **/ GList* -gcal_view_get_children_by_uuid (GcalView *view, - const gchar *uuid) +gcal_view_get_children_by_uuid (GcalView *view, + GcalRecurrenceModType mod, + const gchar *uuid) { g_return_val_if_fail (GCAL_IS_VIEW (view), NULL); g_return_val_if_fail (GCAL_VIEW_GET_IFACE (view)->get_children_by_uuid, NULL); - return GCAL_VIEW_GET_IFACE (view)->get_children_by_uuid (view, uuid); + return GCAL_VIEW_GET_IFACE (view)->get_children_by_uuid (view, mod, uuid); } diff --git a/src/gcal-view.h b/src/gcal-view.h index c38fb86e..a746bfd4 100644 --- a/src/gcal-view.h +++ b/src/gcal-view.h @@ -51,8 +51,9 @@ struct _GcalViewInterface /* Marks related API */ void (*clear_marks) (GcalView *view); - GList* (*get_children_by_uuid) (GcalView *view, - const gchar *uuid); + GList* (*get_children_by_uuid) (GcalView *view, + GcalRecurrenceModType mod, + const gchar *uuid); }; void gcal_view_set_date (GcalView *view, @@ -62,8 +63,9 @@ icaltimetype* gcal_view_get_date (GcalView void gcal_view_clear_marks (GcalView *view); -GList* gcal_view_get_children_by_uuid (GcalView *view, - const gchar *uuid); +GList* gcal_view_get_children_by_uuid (GcalView *view, + GcalRecurrenceModType mod, + const gchar *uuid); G_END_DECLS diff --git a/src/gcal-window.c b/src/gcal-window.c index 368cfd48..fea1adce 100644 --- a/src/gcal-window.c +++ b/src/gcal-window.c @@ -1145,7 +1145,7 @@ edit_dialog_closed (GtkDialog *dialog, window->event_to_delete_mod = mod; /* hide widget of the event */ - widgets = gcal_view_get_children_by_uuid (view, gcal_event_get_uid (event)); + widgets = gcal_view_get_children_by_uuid (view, mod, gcal_event_get_uid (event)); g_list_foreach (widgets, (GFunc) gtk_widget_hide, NULL); g_list_free (widgets); @@ -1242,6 +1242,7 @@ undo_remove_action (GtkButton *button, window = GCAL_WINDOW (user_data); widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (window->views[window->active_view]), + window->event_to_delete_mod, gcal_event_get_uid (window->event_to_delete)); /* Show the hidden to-be-deleted events */ @@ -1263,7 +1264,9 @@ schedule_open_edit_dialog_by_uuid (OpenEditDialogData *edit_dialog_data) GList *widgets; window = edit_dialog_data->window; - widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (window->month_view), edit_dialog_data->uuid); + widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (window->month_view), + GCAL_RECURRENCE_MOD_THIS_ONLY, + edit_dialog_data->uuid); if (widgets != NULL) { window->open_edit_dialog_timeout_id = 0; @@ -1798,7 +1801,9 @@ gcal_window_open_event_by_uuid (GcalWindow *self, /* XXX: show events on month view */ gtk_stack_set_visible_child (GTK_STACK (self->views_stack), self->month_view); - widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (self->month_view), uuid); + widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (self->month_view), + GCAL_RECURRENCE_MOD_THIS_ONLY, + uuid); if (widgets) { diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c index bb5d0647..392c1b41 100644 --- a/src/views/gcal-month-view.c +++ b/src/views/gcal-month-view.c @@ -972,17 +972,23 @@ gcal_month_view_clear_marks (GcalView *view) } static GList* -gcal_month_view_get_children_by_uuid (GcalView *view, - const gchar *uuid) +gcal_month_view_get_children_by_uuid (GcalView *view, + GcalRecurrenceModType mod, + const gchar *uuid) { GcalSubscriberViewPrivate *ppriv = GCAL_SUBSCRIBER_VIEW (view)->priv; - GList *l; + GHashTableIter iter; + GList *children; + GList *tmp; - l = g_hash_table_lookup (ppriv->children, uuid); - if (l != NULL) - return g_list_reverse (g_list_copy (l)); + children = NULL; - return NULL; + g_hash_table_iter_init (&iter, ppriv->children); + + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tmp)) + children = g_list_concat (children, g_list_copy (tmp)); + + return filter_event_list_by_uid_and_modtype (children, mod, uuid); } static void diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c index e33c8c71..a070a3d5 100644 --- a/src/views/gcal-week-grid.c +++ b/src/views/gcal-week-grid.c @@ -19,6 +19,7 @@ #define G_LOG_DOMAIN "GcalWeekGrid" +#include "gcal-debug.h" #include "gcal-week-grid.h" #include "gcal-week-view.h" #include "gcal-utils.h" @@ -1238,32 +1239,33 @@ gcal_week_grid_remove_event (GcalWeekGrid *self, } GList* -gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self, - const gchar *uid) +gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self, + GcalRecurrenceModType mod, + const gchar *uid) { GPtrArray *widgets; + GList *events; GList *result; guint i; + GCAL_ENTRY; + + events = NULL; result = NULL; widgets = gcal_range_tree_get_data_at_range (self->events, 0, MAX_MINUTES); for (i = 0; widgets && i < widgets->len; i++) { - ChildData *data; - GcalEvent *event; - - data = g_ptr_array_index (widgets, i); - event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (data->widget)); - - if (g_strcmp0 (gcal_event_get_uid (event), uid) == 0) - result = g_list_prepend (result, data->widget); - + ChildData *data = g_ptr_array_index (widgets, i); + events = g_list_prepend (events, data->widget); } - g_clear_pointer (&widgets, g_ptr_array_unref); + result = filter_event_list_by_uid_and_modtype (events, mod, uid); - return result; + g_clear_pointer (&widgets, g_ptr_array_unref); + g_clear_pointer (&events, g_list_free); + + GCAL_RETURN (result); } void diff --git a/src/views/gcal-week-grid.h b/src/views/gcal-week-grid.h index 2d519b32..ca6692f9 100644 --- a/src/views/gcal-week-grid.h +++ b/src/views/gcal-week-grid.h @@ -46,8 +46,9 @@ void gcal_week_grid_add_event (GcalWeekGrid void gcal_week_grid_remove_event (GcalWeekGrid *self, const gchar *uid); -GList* gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self, - const gchar *uid); +GList* gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self, + GcalRecurrenceModType mod, + const gchar *uid); void gcal_week_grid_clear_marks (GcalWeekGrid *self); diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c index b59f5541..1ac9548f 100644 --- a/src/views/gcal-week-header.c +++ b/src/views/gcal-week-header.c @@ -1677,32 +1677,20 @@ gcal_week_header_remove_event (GcalWeekHeader *self, } GList* -gcal_week_header_get_children_by_uuid (GcalWeekHeader *self, - const gchar *uuid) +gcal_week_header_get_children_by_uuid (GcalWeekHeader *self, + GcalRecurrenceModType mod, + const gchar *uuid) { - GList *children, *l, *result; + GList *children, *result; + + GCAL_ENTRY; - result = NULL; children = gtk_container_get_children (GTK_CONTAINER (self->grid)); - - for (l = children; l != NULL; l = l->next) - { - GcalEventWidget *child_widget; - GcalEvent *event; - - if (!GCAL_IS_EVENT_WIDGET (l->data)) - continue; - - child_widget = GCAL_EVENT_WIDGET (l->data); - event = gcal_event_widget_get_event (child_widget); - - if (g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0) - result = g_list_prepend (result, l->data); - } + result = filter_event_list_by_uid_and_modtype (children, mod, uuid); g_list_free (children); - return result; + GCAL_RETURN (result); } GtkSizeGroup* diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h index 8c9d9046..da0289d1 100644 --- a/src/views/gcal-week-header.h +++ b/src/views/gcal-week-header.h @@ -46,8 +46,9 @@ void gcal_week_header_add_event (GcalWeekHeader void gcal_week_header_remove_event (GcalWeekHeader *self, const gchar *uuid); -GList* gcal_week_header_get_children_by_uuid (GcalWeekHeader *self, - const gchar *uuid); +GList* gcal_week_header_get_children_by_uuid (GcalWeekHeader *self, + GcalRecurrenceModType mod, + const gchar *uuid); GtkSizeGroup* gcal_week_header_get_sidebar_size_group (GcalWeekHeader *self); diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c index ebbbcd83..9e92faf3 100644 --- a/src/views/gcal-week-view.c +++ b/src/views/gcal-week-view.c @@ -220,17 +220,20 @@ gcal_week_view_set_date (GcalView *view, } static GList* -gcal_week_view_get_children_by_uuid (GcalView *view, - const gchar *uuid) +gcal_week_view_get_children_by_uuid (GcalView *view, + GcalRecurrenceModType mod, + const gchar *uuid) { GcalWeekView *self; GList *grid, *header; - self = GCAL_WEEK_VIEW (view); - grid = gcal_week_grid_get_children_by_uuid (GCAL_WEEK_GRID (self->week_grid), uuid); - header = gcal_week_header_get_children_by_uuid (GCAL_WEEK_HEADER (self->header), uuid); + GCAL_ENTRY; - return g_list_concat (grid, header); + self = GCAL_WEEK_VIEW (view); + grid = gcal_week_grid_get_children_by_uuid (GCAL_WEEK_GRID (self->week_grid), mod, uuid); + header = gcal_week_header_get_children_by_uuid (GCAL_WEEK_HEADER (self->header), mod, uuid); + + GCAL_RETURN (g_list_concat (grid, header)); } static void diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c index 4780af8b..a7b13a39 100644 --- a/src/views/gcal-year-view.c +++ b/src/views/gcal-year-view.c @@ -1589,26 +1589,17 @@ gcal_year_view_set_date (GcalView *view, } static GList* -gcal_year_view_get_children_by_uuid (GcalView *view, - const gchar *uuid) +gcal_year_view_get_children_by_uuid (GcalView *view, + GcalRecurrenceModType mod, + const gchar *uuid) { - GcalYearView *year_view = GCAL_YEAR_VIEW (view); - GList *children, *l, *result = NULL; + GcalYearView *self = GCAL_YEAR_VIEW (view); + GList *result, *children; - children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar)); + result = NULL; - for (l = children; l != NULL; l = g_list_next (l)) - { - GcalEventWidget *child_widget; - GcalEvent *event; - - child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data))); - event = gcal_event_widget_get_event (child_widget); - - - if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0) - result = g_list_append (result, child_widget); - } + children = gtk_container_get_children (GTK_CONTAINER (self->sidebar)); + result = filter_event_list_by_uid_and_modtype (children, mod, uuid); g_list_free (children);