summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2022-10-17 16:34:40 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2022-10-17 23:37:13 -0300
commit502b381975181407f6b1b4ee60a95be139e34784 (patch)
tree7318ffe65f3a332814472c801a6ce6f62a954084
parent102346534a0454a3985632d6ddbf71f4602bb1c1 (diff)
downloadgnome-calendar-502b381975181407f6b1b4ee60a95be139e34784.tar.gz
event-editor/dialog: Properly handle editing recurrent events
When a recurrent event is edited, we now are able to only offer the MOD_ALL option when it actually will work. However, we're still left with the problem that we end up applying the instance-specific data onto the main event, through an old hack. The views already aren't able to offer the MOD_ALL property, since they all change the dates of events, but GcalEventEditorDialog can, and it must handle that properly. For now, do the simplest possible approach, which is: retrive the template event and apply all properties that can be applied to it, without letting the start and end days leak into it. We already only allow passing MOD_ALL on situations where the dates aren't really modified, so it should be safe. Fixes https://gitlab.gnome.org/GNOME/gnome-calendar/-/issues/882
-rw-r--r--src/gui/event-editor/gcal-event-editor-dialog.c119
1 files changed, 116 insertions, 3 deletions
diff --git a/src/gui/event-editor/gcal-event-editor-dialog.c b/src/gui/event-editor/gcal-event-editor-dialog.c
index 6c3527db..40b1d16e 100644
--- a/src/gui/event-editor/gcal-event-editor-dialog.c
+++ b/src/gui/event-editor/gcal-event-editor-dialog.c
@@ -207,6 +207,64 @@ clear_and_hide_dialog (GcalEventEditorDialog *self)
gtk_widget_hide (GTK_WIDGET (self));
}
+static void
+apply_event_properties_to_template_event (GcalEvent *template_event,
+ GcalEvent *event)
+{
+ g_autoptr (GDateTime) start_date = NULL;
+ g_autoptr (GDateTime) end_date = NULL;
+ GDateTime *template_start_date;
+ GDateTime *event_start_date;
+ GDateTime *template_end_date;
+ GDateTime *event_end_date;
+ gboolean was_all_day;
+ gboolean is_all_day;
+
+ is_all_day = gcal_event_get_all_day (event);
+ was_all_day = gcal_event_get_all_day (template_event);
+
+ template_start_date = gcal_event_get_date_start (template_event);
+ template_end_date = gcal_event_get_date_end (template_event);
+ event_start_date = gcal_event_get_date_start (event);
+ event_end_date = gcal_event_get_date_end (event);
+
+ start_date = g_date_time_new (g_date_time_get_timezone (event_start_date),
+ g_date_time_get_year (template_start_date),
+ g_date_time_get_month (template_start_date),
+ g_date_time_get_day_of_month (template_start_date),
+ g_date_time_get_hour (event_start_date),
+ g_date_time_get_minute (event_start_date),
+ g_date_time_get_second (event_start_date));
+
+ end_date = g_date_time_new (g_date_time_get_timezone (event_end_date),
+ g_date_time_get_year (template_end_date),
+ g_date_time_get_month (template_end_date),
+ g_date_time_get_day_of_month (template_end_date),
+ g_date_time_get_hour (event_end_date),
+ g_date_time_get_minute (event_end_date),
+ g_date_time_get_second (event_end_date));
+
+ if (was_all_day != is_all_day)
+ {
+ g_autoptr (GDateTime) fake_end_date = NULL;
+
+ if (is_all_day)
+ fake_end_date = g_date_time_add_days (end_date, -1);
+ else
+ fake_end_date = g_date_time_add_days (end_date, 1);
+
+ gcal_set_date_time (&end_date, fake_end_date);
+ }
+
+ gcal_event_set_summary (template_event, gcal_event_get_summary (event));
+ gcal_event_set_location (template_event, gcal_event_get_location (event));
+ gcal_event_set_description (template_event, gcal_event_get_description (event));
+ gcal_event_set_recurrence (template_event, gcal_event_get_recurrence (event));
+ gcal_event_set_all_day (template_event, gcal_event_get_all_day (event));
+ gcal_event_set_date_start (template_event, start_date);
+ gcal_event_set_date_end (template_event, end_date);
+}
+
/*
* Callbacks
@@ -315,13 +373,68 @@ on_ask_recurrence_response_save_cb (GcalEvent *event,
GcalEventEditorDialog *self = GCAL_EVENT_EDITOR_DIALOG (user_data);
GcalManager *manager;
- if (mod_type == GCAL_RECURRENCE_MOD_NONE)
- return;
+ GCAL_ENTRY;
manager = gcal_context_get_manager (self->context);
- gcal_manager_update_event (manager, self->event, mod_type);
+ switch (mod_type)
+ {
+ case GCAL_RECURRENCE_MOD_NONE:
+ GCAL_RETURN ();
+
+ case GCAL_RECURRENCE_MOD_ALL:
+ {
+ g_autoptr (GcalEvent) template_event = NULL;
+ g_autoptr (GError) error = NULL;
+ ECalComponentId *component_id;
+ ICalComponent *template_icomponent;
+ ECalComponent *template_ecomponent;
+ ECalComponent *component;
+ GcalCalendar *calendar;
+ ECalClient *client;
+
+ calendar = gcal_event_get_calendar (event);
+ client = gcal_calendar_get_client (calendar);
+ component = gcal_event_get_component (event);
+ component_id = e_cal_component_get_id (component);
+
+ e_cal_client_get_object_sync (client,
+ e_cal_component_id_get_uid (component_id),
+ NULL,
+ &template_icomponent,
+ NULL,
+ &error);
+
+ g_clear_pointer (&component_id, e_cal_component_id_free);
+
+ if (error)
+ {
+ g_warning ("Error updating event: %s", error->message);
+ break;
+ }
+
+ template_ecomponent = e_cal_component_new_from_icalcomponent (template_icomponent);
+ template_event = gcal_event_new (calendar, template_ecomponent, &error);
+ if (error)
+ {
+ g_warning ("Error updating event: %s", error->message);
+ break;
+ }
+
+ apply_event_properties_to_template_event (template_event, event);
+ gcal_manager_update_event (manager, template_event, mod_type);
+ }
+ break;
+
+ case GCAL_RECURRENCE_MOD_THIS_AND_FUTURE:
+ case GCAL_RECURRENCE_MOD_THIS_ONLY:
+ gcal_manager_update_event (manager, self->event, mod_type);
+ break;
+ }
+
clear_and_hide_dialog (self);
+
+ GCAL_EXIT;
}
static void