diff options
author | Ray Strode <rstrode@redhat.com> | 2022-10-14 17:09:28 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2022-10-15 10:02:42 -0400 |
commit | 7d7c27d0750279a1ac2560358187f20951c7a505 (patch) | |
tree | 3f140f53cfdc2026541db55be9d08f6b4b066716 | |
parent | d071c5e2b02859f469657a40391e2c625dd74612 (diff) | |
download | gnome-calendar-fix-shifting-events.tar.gz |
core: Handle exceptions in event listfix-shifting-events
If a recurrence of events is set up and one of the events gets
deleted, that event needs to be marked as an exception on the
main event so that it doesn't get recreated any time the main
event is edited.
This commit adds code to manage setting up this exception.
-rw-r--r-- | src/core/gcal-event.c | 81 | ||||
-rw-r--r-- | src/core/gcal-event.h | 8 | ||||
-rw-r--r-- | src/core/gcal-manager.c | 18 | ||||
-rw-r--r-- | src/core/gcal-timeline.c | 11 |
4 files changed, 114 insertions, 4 deletions
diff --git a/src/core/gcal-event.c b/src/core/gcal-event.c index 88087337..e03ab82b 100644 --- a/src/core/gcal-event.c +++ b/src/core/gcal-event.c @@ -95,6 +95,7 @@ struct _GcalEvent GBinding *color_binding; gboolean all_day; + gboolean excluded; /* A map of GcalAlarmType */ GHashTable *alarms; @@ -138,10 +139,40 @@ static GParamSpec* properties[N_PROPS] = { NULL, }; */ static void +check_if_excluded (GcalEvent *self) +{ + ECalComponentDateTime *date; + GSList *exclusion_dates, *node; + + GCAL_TRACE_MSG ("Checking if event should be excluded"); + + self->excluded = FALSE; + + date = e_cal_component_get_dtstart (self->component); + exclusion_dates = e_cal_component_get_exdates (self->component); + for (node = exclusion_dates; node != NULL; node = node->next) + { + ECalComponentDateTime *exclusion_date = node->data; + + if (i_cal_time_compare (e_cal_component_datetime_get_value (exclusion_date), + e_cal_component_datetime_get_value (date)) == 0) + { + self->excluded = TRUE; + break; + } + } + g_slist_free_full (exclusion_dates, e_cal_component_datetime_free); + + g_clear_pointer (&date, e_cal_component_datetime_free); +} + +static void clear_range (GcalEvent *self) { g_clear_pointer (&self->range, gcal_range_unref); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RANGE]); + + check_if_excluded (self); } static GTimeZone* @@ -392,6 +423,8 @@ setup_component (GcalEvent *self, g_clear_object (&date); } + check_if_excluded (self); + /* Summary */ text = e_cal_component_get_summary (self->component); if (text && e_cal_component_text_get_value (text)) @@ -1002,6 +1035,38 @@ gcal_event_apply_instance (GcalEvent *self, } /** + * gcal_event_remove_instance: + * @self: a #GcalEvent + * + * Marks the given instance as an exception in the main event recurrence list, + * so it essentially gets removed + */ +void +gcal_event_remove_instance (GcalEvent *self, + GcalEvent *instance) +{ + GSList *exceptions; + ECalComponentDateTime *instance_date; + + g_return_if_fail (GCAL_IS_EVENT (self)); + + if (e_cal_component_is_instance (self->component)) + return; + + if (!e_cal_component_is_instance (instance->component)) + return; + + instance_date = e_cal_component_get_dtstart (instance->component); + exceptions = e_cal_component_get_exdates (self->component); + exceptions = g_slist_prepend (exceptions, instance_date); + + e_cal_component_set_exdates (self->component, exceptions); + e_cal_component_commit_sequence (self->component); + + g_slist_free_full (exceptions, e_cal_component_datetime_free); +} + +/** * gcal_event_get_all_day: * @self: a #GcalEvent * @@ -1209,12 +1274,26 @@ gcal_event_get_range (GcalEvent *self) self->range = gcal_range_new (gcal_event_get_date_start (self), gcal_event_get_date_end (self), self->all_day ? GCAL_RANGE_DATE_ONLY : GCAL_RANGE_DEFAULT); + + check_if_excluded (self); } return self->range; } /** + * gcal_event_get_excluded: + * @self: a #GcalEvent + * + * Retrieves whether or not the event has been excluded by an exdate. + */ +gboolean +gcal_event_get_excluded (GcalEvent *self) +{ + return self->excluded; +} + +/** * gcal_event_get_description: * @self a #GcalEvent * @@ -1847,6 +1926,8 @@ gcal_event_set_recurrence (GcalEvent *self, g_clear_object (&rrule); g_clear_object (&prop); + + check_if_excluded (self); } /** diff --git a/src/core/gcal-event.h b/src/core/gcal-event.h index c124bc55..e24e79d6 100644 --- a/src/core/gcal-event.h +++ b/src/core/gcal-event.h @@ -57,8 +57,11 @@ GcalEvent* gcal_event_new_from_event (GcalEvent GcalEvent* gcal_event_new_main_event_from_instance_event (GcalEvent *self); -void gcal_event_apply_instance (GcalEvent *self, - GcalEvent *instance); +void gcal_event_apply_instance (GcalEvent *self, + GcalEvent *instance); + +void gcal_event_remove_instance (GcalEvent *self, + GcalEvent *instance); gboolean gcal_event_get_all_day (GcalEvent *self); @@ -83,6 +86,7 @@ void gcal_event_set_date_start (GcalEvent GDateTime *dt); GcalRange* gcal_event_get_range (GcalEvent *self); +gboolean gcal_event_get_excluded (GcalEvent *self); const gchar* gcal_event_get_description (GcalEvent *self); diff --git a/src/core/gcal-manager.c b/src/core/gcal-manager.c index cf9284d6..3538963e 100644 --- a/src/core/gcal-manager.c +++ b/src/core/gcal-manager.c @@ -1115,6 +1115,24 @@ gcal_manager_remove_event (GcalManager *self, on_event_removed, g_object_ref (event)); + if (mod != GCAL_RECURRENCE_MOD_ALL) + { + g_autoptr (GcalEvent) main_event = NULL; + + main_event = gcal_event_new_main_event_from_instance_event (event); + component = gcal_event_get_component (main_event); + + gcal_event_remove_instance (main_event, event); + + e_cal_client_modify_object (gcal_calendar_get_client (calendar), + e_cal_component_get_icalcomponent (component), + (ECalObjModType) GCAL_RECURRENCE_MOD_ALL, + E_CAL_OPERATION_FLAG_NONE, + NULL, + on_event_updated, + g_object_ref (component)); + } + g_free (rid); GCAL_EXIT; diff --git a/src/core/gcal-timeline.c b/src/core/gcal-timeline.c index dcec4cb3..fbad9fc6 100644 --- a/src/core/gcal-timeline.c +++ b/src/core/gcal-timeline.c @@ -679,7 +679,8 @@ timeline_source_dispatch (GSource *source, if (subscriber) { - add_event_to_subscriber (subscriber, event); + if (!gcal_event_get_excluded (event)) + add_event_to_subscriber (subscriber, event); g_hash_table_remove (self->queued_adds, subscriber_event_id); } break; @@ -703,7 +704,13 @@ timeline_source_dispatch (GSource *source, } if (subscriber) - update_subscriber_event (subscriber, event); + { + + if (!gcal_event_get_excluded (event)) + update_subscriber_event (subscriber, event); + else + remove_event_from_subscriber (subscriber, event); + } } break; |