[evolution] I#1527 - Calendar: Implement "Delete this and future occurrences"



commit 51c5063377bfa5d8d7440b236a1e752deccddf71
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jun 8 18:10:12 2021 +0200

    I#1527 - Calendar: Implement "Delete this and future occurrences"
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1527

 data/ui/evolution-calendars.ui                  |  2 ++
 src/calendar/gui/e-calendar-view.c              | 30 ++++++++++++++++++-------
 src/calendar/gui/e-calendar-view.h              |  3 ++-
 src/modules/calendar/e-cal-base-shell-content.h |  3 ++-
 src/modules/calendar/e-cal-shell-content.c      |  6 +++++
 src/modules/calendar/e-cal-shell-view-actions.c | 26 ++++++++++++++++++++-
 src/modules/calendar/e-cal-shell-view-actions.h |  2 ++
 src/modules/calendar/e-cal-shell-view.c         | 11 +++++++++
 8 files changed, 72 insertions(+), 11 deletions(-)
---
diff --git a/data/ui/evolution-calendars.ui b/data/ui/evolution-calendars.ui
index e33af2e726..4349c68e56 100644
--- a/data/ui/evolution-calendars.ui
+++ b/data/ui/evolution-calendars.ui
@@ -14,6 +14,7 @@
       <placeholder name='edit-actions'>
         <menuitem action='event-delete'/>
         <menuitem action='event-delete-occurrence'/>
+        <menuitem action='event-delete-occurrence-this-and-future'/>
         <menuitem action='event-delete-occurrence-all'/>
         <menuitem action='calendar-delete'/>
       </placeholder>
@@ -128,6 +129,7 @@
     <menuitem action='event-popup-occurrence-movable'/>
     <menuitem action='event-popup-delete'/>
     <menuitem action='event-popup-delete-occurrence'/>
+    <menuitem action='event-popup-delete-occurrence-this-and-future'/>
     <menuitem action='event-popup-delete-occurrence-all'/>
     <separator/>
     <placeholder name='event-popup-actions'/>
diff --git a/src/calendar/gui/e-calendar-view.c b/src/calendar/gui/e-calendar-view.c
index 540a73f4f7..867e77c426 100644
--- a/src/calendar/gui/e-calendar-view.c
+++ b/src/calendar/gui/e-calendar-view.c
@@ -113,6 +113,8 @@ calendar_view_add_retract_data (ECalComponent *comp,
 
        if (mod == E_CAL_OBJ_MOD_ALL)
                prop = i_cal_property_new_x ("All");
+       else if (mod == E_CAL_OBJ_MOD_THIS_AND_FUTURE)
+               prop = i_cal_property_new_x ("ThisAndFuture");
        else
                prop = i_cal_property_new_x ("This");
        i_cal_property_set_x_name (prop, "X-EVOLUTION-RECUR-MOD");
@@ -154,7 +156,8 @@ calendar_view_check_for_retract (ECalComponent *comp,
 static void
 calendar_view_delete_event (ECalendarView *cal_view,
                             ECalendarViewEvent *event,
-                           gboolean only_occurrence)
+                           gboolean only_occurrence,
+                           ECalObjModType mod)
 {
        ECalModel *model;
        ECalComponent *comp;
@@ -193,7 +196,7 @@ calendar_view_delete_event (ECalendarView *cal_view,
                if (retract) {
                        ICalComponent *icomp;
 
-                       calendar_view_add_retract_data (comp, retract_comment, E_CAL_OBJ_MOD_ALL);
+                       calendar_view_add_retract_data (comp, retract_comment, mod);
                        icomp = e_cal_component_get_icalcomponent (comp);
                        i_cal_component_set_method (icomp, I_CAL_METHOD_CANCEL);
 
@@ -223,9 +226,17 @@ calendar_view_delete_event (ECalendarView *cal_view,
                                i_cal_time_set_is_date (e_cal_component_datetime_get_value (dtstart), 1);
 
                                /* set the recurrence ID of the object we send */
-                               range = e_cal_component_range_new_take (E_CAL_COMPONENT_RANGE_SINGLE, 
dtstart);
+                               range = e_cal_component_range_new_take (mod == E_CAL_OBJ_MOD_THIS_AND_FUTURE ?
+                                       E_CAL_COMPONENT_RANGE_THISFUTURE : E_CAL_COMPONENT_RANGE_SINGLE, 
dtstart);
                                e_cal_component_set_recurid (comp, range);
 
+                               e_cal_component_range_free (range);
+                       } else if (only_occurrence && mod == E_CAL_OBJ_MOD_THIS_AND_FUTURE) {
+                               ECalComponentRange *range;
+
+                               range = e_cal_component_get_recurid (comp);
+                               e_cal_component_range_set_kind (range, E_CAL_COMPONENT_RANGE_THISFUTURE);
+                               e_cal_component_set_recurid (comp, range);
                                e_cal_component_range_free (range);
                        }
 
@@ -243,7 +254,7 @@ calendar_view_delete_event (ECalendarView *cal_view,
 
                if (only_occurrence) {
                        if (e_cal_component_is_instance (comp)) {
-                               e_cal_ops_remove_component (model, client, uid, rid, E_CAL_OBJ_MOD_THIS, 
FALSE);
+                               e_cal_ops_remove_component (model, client, uid, rid, mod, FALSE);
                        } else {
                                ICalTime *instance_rid;
                                ICalTimezone *zone = NULL;
@@ -271,7 +282,7 @@ calendar_view_delete_event (ECalendarView *cal_view,
                                instance_rid = i_cal_time_new_from_timet_with_zone (
                                        instance_start,
                                        TRUE, zone ? zone : i_cal_timezone_get_utc_timezone ());
-                               e_cal_util_remove_instances_ex (icalcomp, instance_rid, E_CAL_OBJ_MOD_THIS,
+                               e_cal_util_remove_instances_ex (icalcomp, instance_rid, mod,
                                        e_cal_client_tzlookup_cb, client);
                                e_cal_ops_modify_component (model, client, icalcomp,
                                        E_CAL_OBJ_MOD_THIS, E_CAL_OPS_SEND_FLAG_DONT_SEND);
@@ -1114,7 +1125,7 @@ calendar_view_delete_selection (ESelectable *selectable)
                if (event == NULL)
                        continue;
 
-               calendar_view_delete_event (cal_view, event, FALSE);
+               calendar_view_delete_event (cal_view, event, FALSE, E_CAL_OBJ_MOD_ALL);
        }
 
        g_list_free (selected);
@@ -1567,18 +1578,21 @@ e_calendar_view_update_query (ECalendarView *cal_view)
 }
 
 void
-e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view)
+e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view,
+                                           ECalObjModType mod)
 {
        ECalendarViewEvent *event;
        GList *selected;
 
+       g_return_if_fail (mod == E_CAL_OBJ_MOD_THIS || mod == E_CAL_OBJ_MOD_THIS_AND_FUTURE);
+
        selected = e_calendar_view_get_selected_events (cal_view);
        if (!selected)
                return;
 
        event = (ECalendarViewEvent *) selected->data;
        if (is_comp_data_valid (event)) {
-               calendar_view_delete_event (cal_view, event, TRUE);
+               calendar_view_delete_event (cal_view, event, TRUE, mod);
        }
 
        g_list_free (selected);
diff --git a/src/calendar/gui/e-calendar-view.h b/src/calendar/gui/e-calendar-view.h
index 3ec133d1ed..ba9cfaac53 100644
--- a/src/calendar/gui/e-calendar-view.h
+++ b/src/calendar/gui/e-calendar-view.h
@@ -226,7 +226,8 @@ void                e_calendar_view_precalc_visible_time_range
 void           e_calendar_view_update_query    (ECalendarView *cal_view);
 
 void           e_calendar_view_delete_selected_occurrence
-                                               (ECalendarView *cal_view);
+                                               (ECalendarView *cal_view,
+                                                ECalObjModType mod);
 ECompEditor *  e_calendar_view_open_event_with_flags
                                                (ECalendarView *cal_view,
                                                 ECalClient *client,
diff --git a/src/modules/calendar/e-cal-base-shell-content.h b/src/modules/calendar/e-cal-base-shell-content.h
index 541f77d000..d27f4b8ff2 100644
--- a/src/modules/calendar/e-cal-base-shell-content.h
+++ b/src/modules/calendar/e-cal-base-shell-content.h
@@ -64,7 +64,8 @@ enum {
        E_CAL_BASE_SHELL_CONTENT_SELECTION_HAS_COMPLETE   = 1 << 9,
        E_CAL_BASE_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE = 1 << 10,
        E_CAL_BASE_SHELL_CONTENT_SELECTION_HAS_URL        = 1 << 11,
-       E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_ATTENDEE    = 1 << 12
+       E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_ATTENDEE    = 1 << 12,
+       E_CAL_BASE_SHELL_CONTENT_SELECTION_THIS_AND_FUTURE_SUPPORTED = 1 << 13
 };
 
 struct _ECalBaseShellContent {
diff --git a/src/modules/calendar/e-cal-shell-content.c b/src/modules/calendar/e-cal-shell-content.c
index ee926390d2..80f699741e 100644
--- a/src/modules/calendar/e-cal-shell-content.c
+++ b/src/modules/calendar/e-cal-shell-content.c
@@ -968,6 +968,7 @@ cal_shell_content_check_state (EShellContent *shell_content)
        gboolean selection_is_attendee = FALSE;
        gboolean selection_is_recurring = FALSE;
        gboolean selection_can_delegate = FALSE;
+       gboolean this_and_future_supported = FALSE;
        guint32 state = 0;
        GList *selected;
        GList *link;
@@ -1048,6 +1049,9 @@ cal_shell_content_check_state (EShellContent *shell_content)
                        e_client_check_capability (
                        E_CLIENT (client), capability);
 
+               this_and_future_supported = !e_client_check_capability (
+                       E_CLIENT (client), E_CAL_STATIC_CAPABILITY_NO_THISANDFUTURE);
+
                icomp_is_delegated = user_email != NULL &&
                        cal_shell_content_icomp_is_delegated (icomp, user_email);
 
@@ -1086,6 +1090,8 @@ cal_shell_content_check_state (EShellContent *shell_content)
                state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_RECURRING;
        if (selection_can_delegate)
                state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_CAN_DELEGATE;
+       if (this_and_future_supported)
+               state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_THIS_AND_FUTURE_SUPPORTED;
 
        return state;
 }
diff --git a/src/modules/calendar/e-cal-shell-view-actions.c b/src/modules/calendar/e-cal-shell-view-actions.c
index 4e7a0b94ba..f433abb04a 100644
--- a/src/modules/calendar/e-cal-shell-view-actions.c
+++ b/src/modules/calendar/e-cal-shell-view-actions.c
@@ -722,7 +722,20 @@ action_event_delete_occurrence_cb (GtkAction *action,
        cal_shell_content = cal_shell_view->priv->cal_shell_content;
        calendar_view = e_cal_shell_content_get_current_calendar_view (cal_shell_content);
 
-       e_calendar_view_delete_selected_occurrence (calendar_view);
+       e_calendar_view_delete_selected_occurrence (calendar_view, E_CAL_OBJ_MOD_THIS);
+}
+
+static void
+action_event_delete_occurrence_this_and_future_cb (GtkAction *action,
+                                                  ECalShellView *cal_shell_view)
+{
+       ECalShellContent *cal_shell_content;
+       ECalendarView *calendar_view;
+
+       cal_shell_content = cal_shell_view->priv->cal_shell_content;
+       calendar_view = e_cal_shell_content_get_current_calendar_view (cal_shell_content);
+
+       e_calendar_view_delete_selected_occurrence (calendar_view, E_CAL_OBJ_MOD_THIS_AND_FUTURE);
 }
 
 static void
@@ -1426,6 +1439,13 @@ static GtkActionEntry calendar_entries[] = {
          N_("Delete this occurrence"),
          G_CALLBACK (action_event_delete_occurrence_cb) },
 
+       { "event-delete-occurrence-this-and-future",
+         "edit-delete",
+         N_("Delete This and F_uture Occurrences"),
+         NULL,
+         N_("Delete this and any future occurrences"),
+         G_CALLBACK (action_event_delete_occurrence_this_and_future_cb) },
+
        { "event-delete-occurrence-all",
          "edit-delete",
          N_("Delete All Occ_urrences"),
@@ -1649,6 +1669,10 @@ static EPopupActionEntry calendar_popup_entries[] = {
          NULL,
          "event-delete-occurrence" },
 
+       { "event-popup-delete-occurrence-this-and-future",
+         NULL,
+         "event-delete-occurrence-this-and-future" },
+
        { "event-popup-delete-occurrence-all",
          NULL,
          "event-delete-occurrence-all" },
diff --git a/src/modules/calendar/e-cal-shell-view-actions.h b/src/modules/calendar/e-cal-shell-view-actions.h
index ea47a0ce02..a8374b211d 100644
--- a/src/modules/calendar/e-cal-shell-view-actions.h
+++ b/src/modules/calendar/e-cal-shell-view-actions.h
@@ -80,6 +80,8 @@
        E_SHELL_WINDOW_ACTION ((window), "event-delete")
 #define E_SHELL_WINDOW_ACTION_EVENT_DELETE_OCCURRENCE(window) \
        E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence")
+#define E_SHELL_WINDOW_ACTION_EVENT_DELETE_OCCURRENCE_THIS_AND_FUTURE(window) \
+       E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence-this-and-future")
 #define E_SHELL_WINDOW_ACTION_EVENT_DELETE_OCCURRENCE_ALL(window) \
        E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence-all")
 #define E_SHELL_WINDOW_ACTION_EVENT_EDIT_AS_NEW(window) \
diff --git a/src/modules/calendar/e-cal-shell-view.c b/src/modules/calendar/e-cal-shell-view.c
index 1c8bb6ed9d..5684f1fc14 100644
--- a/src/modules/calendar/e-cal-shell-view.c
+++ b/src/modules/calendar/e-cal-shell-view.c
@@ -283,6 +283,7 @@ cal_shell_view_update_actions (EShellView *shell_view)
        gboolean all_sources_selected;
        gboolean clicked_source_is_primary;
        gboolean clicked_source_is_collection;
+       gboolean this_and_future_supported;
 
        /* Chain up to parent's update_actions() method. */
        E_SHELL_VIEW_CLASS (e_cal_shell_view_parent_class)->
@@ -335,6 +336,8 @@ cal_shell_view_update_actions (EShellView *shell_view)
                (state & E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_RECURRING);
        selection_can_delegate =
                (state & E_CAL_BASE_SHELL_CONTENT_SELECTION_CAN_DELEGATE);
+       this_and_future_supported =
+               (state & E_CAL_BASE_SHELL_CONTENT_SELECTION_THIS_AND_FUTURE_SUPPORTED);
 
        shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
        state = e_shell_sidebar_check_state (shell_sidebar);
@@ -436,6 +439,14 @@ cal_shell_view_update_actions (EShellView *shell_view)
                selection_is_recurring;
        gtk_action_set_sensitive (action, sensitive);
 
+       action = ACTION (EVENT_DELETE_OCCURRENCE_THIS_AND_FUTURE);
+       sensitive =
+               single_event_selected &&
+               selection_is_editable &&
+               selection_is_recurring &&
+               this_and_future_supported;
+       gtk_action_set_sensitive (action, sensitive);
+
        action = ACTION (EVENT_DELETE_OCCURRENCE_ALL);
        sensitive =
                any_events_selected &&


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]