[gnome-calendar/fix-shifting-events] core: Handle exceptions in event list
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar/fix-shifting-events] core: Handle exceptions in event list
- Date: Sat, 15 Oct 2022 14:09:34 +0000 (UTC)
commit 7d7c27d0750279a1ac2560358187f20951c7a505
Author: Ray Strode <rstrode redhat com>
Date: Fri Oct 14 17:09:28 2022 -0400
core: Handle exceptions in event list
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.
src/core/gcal-event.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
src/core/gcal-event.h | 8 +++--
src/core/gcal-manager.c | 18 +++++++++++
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;
@@ -137,11 +138,41 @@ static GParamSpec* properties[N_PROPS] = { NULL, };
* Auxiliary methods
*/
+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))
@@ -1001,6 +1034,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,11 +1274,25 @@ 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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]