[gnome-calendar/gbsneto/recurring-event-editing-fixes: 17/18] event-editor/dialog: Properly handle editing recurrent events
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar/gbsneto/recurring-event-editing-fixes: 17/18] event-editor/dialog: Properly handle editing recurrent events
- Date: Mon, 17 Oct 2022 19:43:04 +0000 (UTC)
commit 92cb50a6f21378f04abe07504db7b92bc6ef5ed4
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Mon Oct 17 16:34:40 2022 -0300
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
src/gui/event-editor/gcal-event-editor-dialog.c | 119 +++++++++++++++++++++++-
1 file 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]