[gnome-calendar/fix-shifting-events: 2/2] 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: 2/2] core: Handle exceptions in event list
- Date: Fri, 14 Oct 2022 21:12:59 +0000 (UTC)
commit 2b33aa28713a00405ce80514d84648c0ecfda4b5
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..5d8e480f 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 hidden;
/* A map of GcalAlarmType */
GHashTable *alarms;
@@ -137,11 +138,41 @@ static GParamSpec* properties[N_PROPS] = { NULL, };
* Auxiliary methods
*/
+static void
+check_if_hidden (GcalEvent *self)
+{
+ ECalComponentDateTime *date;
+ GSList *exceptions, *node;
+
+ GCAL_TRACE_MSG ("Checking if event should be hidden");
+
+ self->hidden = FALSE;
+
+ date = e_cal_component_get_dtstart (self->component);
+ exceptions = e_cal_component_get_exdates (self->component);
+ for (node = exceptions; node != NULL; node = node->next)
+ {
+ ECalComponentDateTime *exception = node->data;
+
+ if (i_cal_time_compare (e_cal_component_datetime_get_value (exception),
+ e_cal_component_datetime_get_value (date)) == 0)
+ {
+ self->hidden = TRUE;
+ break;
+ }
+ }
+ g_slist_free_full (exceptions, 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_hidden (self);
}
static GTimeZone*
@@ -392,6 +423,8 @@ setup_component (GcalEvent *self,
g_clear_object (&date);
}
+ check_if_hidden (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_hidden (self);
}
return self->range;
}
+/**
+ * gcal_event_get_hidden:
+ * @self: a #GcalEvent
+ *
+ * Retrieves whether or not the event has been hidden by an exdate.
+ */
+gboolean
+gcal_event_get_hidden (GcalEvent *self)
+{
+ return self->hidden;
+}
+
/**
* 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_hidden (self);
}
/**
diff --git a/src/core/gcal-event.h b/src/core/gcal-event.h
index c124bc55..58e83ee8 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_hidden (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..c6e4b4e6 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_hidden (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_hidden (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]