[gnome-calendar] views: correctly hide events according to the mod type



commit 53a8278953031962301b80c8d969d57b00c0abd7
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Sep 7 00:00:03 2017 -0300

    views: correctly hide events according to the mod type
    
    When deleting events with recurrence, we want to hide the event
    widgets according to the modification type. So that selecting
    e.g. subsequent in the modification type dialog hides the event,
    and the subsequent ones, truly reflecting the operation that will
    happen.
    
    Currently, however, the views don't do that, and only hide the
    event that was asked to be deleted.
    
    Fix that by passing the object modification type, and adapting the
    views to take that into account.

 src/gcal-edit-dialog.h       |    2 +
 src/gcal-utils.c             |   89 ++++++++++++++++++++++++++++++++++++++++++
 src/gcal-utils.h             |    4 ++
 src/gcal-view.c              |    7 ++-
 src/gcal-view.h              |   10 +++--
 src/gcal-window.c            |   11 ++++-
 src/views/gcal-month-view.c  |   20 ++++++---
 src/views/gcal-week-grid.c   |   26 +++++++------
 src/views/gcal-week-grid.h   |    5 +-
 src/views/gcal-week-header.c |   28 ++++---------
 src/views/gcal-week-header.h |    5 +-
 src/views/gcal-week-view.c   |   13 ++++--
 src/views/gcal-year-view.c   |   25 ++++--------
 13 files changed, 170 insertions(+), 75 deletions(-)
---
diff --git a/src/gcal-edit-dialog.h b/src/gcal-edit-dialog.h
index 17b5253..9bfee76 100644
--- a/src/gcal-edit-dialog.h
+++ b/src/gcal-edit-dialog.h
@@ -57,6 +57,8 @@ GDateTime*           gcal_edit_dialog_get_date_start          (GcalEditDialog *d
 
 gboolean             gcal_edit_dialog_get_recurrence_changed   (GcalEditDialog *self);
 
+GcalRecurrenceModType gcal_edit_dialog_get_recurrence_mod_type (GcalEditDialog *self);
+
 G_END_DECLS
 
 #endif /* __GCAL_EDIT_DIALOG_H__ */
diff --git a/src/gcal-utils.c b/src/gcal-utils.c
index cbe9159..09cd87f 100644
--- a/src/gcal-utils.c
+++ b/src/gcal-utils.c
@@ -1314,3 +1314,92 @@ is_workday (guint day)
 
   return !(no_work_days & 1 << day);
 }
+
+GList*
+filter_event_list_by_uid_and_modtype (GList                 *widgets,
+                                      GcalRecurrenceModType  mod,
+                                      const gchar           *uid)
+{
+  GcalEvent *event;
+  GList *result;
+  GList *l;
+
+  event = NULL;
+  result = NULL;
+
+  g_message ("Checking for %s", uid);
+
+  /* First pass: find the GcalEvent */
+  for (l = widgets; l != NULL; l = l->next)
+    {
+      GcalEventWidget *event_widget;
+      GcalEvent *ev;
+
+      event_widget = l->data;
+
+      /* Safeguard against stray widgets */
+      if (!GCAL_IS_EVENT_WIDGET (event_widget))
+        continue;
+
+      ev = gcal_event_widget_get_event (event_widget);
+
+      /*
+       * We can assume only one event will have the exact uuid. Even among
+       * recurrencies.
+       */
+      if (g_str_equal (uid, gcal_event_get_uid (ev)))
+        {
+          result = g_list_prepend (result, event_widget);
+          event = ev;
+        }
+    }
+
+  /* Second pass: find the other related events */
+  if (event && mod != GCAL_RECURRENCE_MOD_THIS_ONLY)
+    {
+      ECalComponentId *id;
+      ECalComponent *component;
+      ESource *source;
+      g_autofree gchar *id_prefix;
+
+      component = gcal_event_get_component (event);
+      source = gcal_event_get_source (event);
+      id = e_cal_component_get_id (component);
+      id_prefix = g_strdup_printf ("%s:%s", e_source_get_uid (source), id->uid);
+
+      for (l = widgets; l != NULL; l = l->next)
+        {
+          GcalEventWidget *event_widget;
+          GcalEvent *ev;
+
+          event_widget = l->data;
+
+          /* Safeguard against stray widgets */
+          if (!GCAL_IS_EVENT_WIDGET (event_widget))
+            continue;
+
+          ev = gcal_event_widget_get_event (event_widget);
+
+          if (g_str_equal (gcal_event_get_uid (ev), uid))
+            continue;
+
+          if (!g_str_has_prefix (gcal_event_get_uid (ev), id_prefix))
+            continue;
+
+          if (mod == GCAL_RECURRENCE_MOD_ALL)
+            {
+              result = g_list_prepend (result, event_widget);
+            }
+          else if (mod == GCAL_RECURRENCE_MOD_THIS_AND_FUTURE)
+            {
+              if (g_date_time_compare (gcal_event_get_date_start (event), gcal_event_get_date_start (ev)) < 
0)
+                result = g_list_prepend (result, event_widget);
+            }
+
+        }
+
+      e_cal_component_free_id (id);
+    }
+
+  return result;
+}
diff --git a/src/gcal-utils.h b/src/gcal-utils.h
index 3be7577..4499e32 100644
--- a/src/gcal-utils.h
+++ b/src/gcal-utils.h
@@ -157,4 +157,8 @@ gboolean        ask_recurrence_modification_type                (GtkWidget
 
 gboolean        is_workday                                      (guint                 day);
 
+GList*          filter_event_list_by_uid_and_modtype            (GList                 *widgets,
+                                                                 GcalRecurrenceModType  mod,
+                                                                 const gchar           *uid);
+
 #endif // __GCAL_UTILS_H__
diff --git a/src/gcal-view.c b/src/gcal-view.c
index efcbb1f..f6fd54c 100644
--- a/src/gcal-view.c
+++ b/src/gcal-view.c
@@ -134,11 +134,12 @@ gcal_view_clear_marks (GcalView *view)
  * Returns: (transfer full): a {@link GList} instance
  **/
 GList*
-gcal_view_get_children_by_uuid (GcalView    *view,
-                                const gchar *uuid)
+gcal_view_get_children_by_uuid (GcalView              *view,
+                                GcalRecurrenceModType  mod,
+                                const gchar           *uuid)
 {
   g_return_val_if_fail (GCAL_IS_VIEW (view), NULL);
   g_return_val_if_fail (GCAL_VIEW_GET_IFACE (view)->get_children_by_uuid, NULL);
 
-  return GCAL_VIEW_GET_IFACE (view)->get_children_by_uuid (view, uuid);
+  return GCAL_VIEW_GET_IFACE (view)->get_children_by_uuid (view, mod, uuid);
 }
diff --git a/src/gcal-view.h b/src/gcal-view.h
index c38fb86..a746bfd 100644
--- a/src/gcal-view.h
+++ b/src/gcal-view.h
@@ -51,8 +51,9 @@ struct _GcalViewInterface
   /* Marks related API */
   void               (*clear_marks)                              (GcalView           *view);
 
-  GList*             (*get_children_by_uuid)                     (GcalView           *view,
-                                                                  const gchar        *uuid);
+  GList*             (*get_children_by_uuid)                     (GcalView              *view,
+                                                                  GcalRecurrenceModType  mod,
+                                                                  const gchar           *uuid);
 };
 
 void                 gcal_view_set_date                          (GcalView           *view,
@@ -62,8 +63,9 @@ icaltimetype*        gcal_view_get_date                          (GcalView
 
 void                 gcal_view_clear_marks                       (GcalView           *view);
 
-GList*               gcal_view_get_children_by_uuid              (GcalView           *view,
-                                                                  const gchar        *uuid);
+GList*               gcal_view_get_children_by_uuid              (GcalView              *view,
+                                                                  GcalRecurrenceModType  mod,
+                                                                  const gchar           *uuid);
 
 G_END_DECLS
 
diff --git a/src/gcal-window.c b/src/gcal-window.c
index 368cfd4..fea1adc 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -1145,7 +1145,7 @@ edit_dialog_closed (GtkDialog *dialog,
       window->event_to_delete_mod = mod;
 
       /* hide widget of the event */
-      widgets = gcal_view_get_children_by_uuid (view, gcal_event_get_uid (event));
+      widgets = gcal_view_get_children_by_uuid (view, mod, gcal_event_get_uid (event));
 
       g_list_foreach (widgets, (GFunc) gtk_widget_hide, NULL);
       g_list_free (widgets);
@@ -1242,6 +1242,7 @@ undo_remove_action (GtkButton *button,
 
   window = GCAL_WINDOW (user_data);
   widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (window->views[window->active_view]),
+                                            window->event_to_delete_mod,
                                             gcal_event_get_uid (window->event_to_delete));
 
   /* Show the hidden to-be-deleted events */
@@ -1263,7 +1264,9 @@ schedule_open_edit_dialog_by_uuid (OpenEditDialogData *edit_dialog_data)
   GList *widgets;
 
   window = edit_dialog_data->window;
-  widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (window->month_view), edit_dialog_data->uuid);
+  widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (window->month_view),
+                                            GCAL_RECURRENCE_MOD_THIS_ONLY,
+                                            edit_dialog_data->uuid);
   if (widgets != NULL)
     {
       window->open_edit_dialog_timeout_id = 0;
@@ -1798,7 +1801,9 @@ gcal_window_open_event_by_uuid (GcalWindow  *self,
   /* XXX: show events on month view */
   gtk_stack_set_visible_child (GTK_STACK (self->views_stack), self->month_view);
 
-  widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (self->month_view), uuid);
+  widgets = gcal_view_get_children_by_uuid (GCAL_VIEW (self->month_view),
+                                            GCAL_RECURRENCE_MOD_THIS_ONLY,
+                                            uuid);
 
   if (widgets)
     {
diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c
index bb5d064..392c1b4 100644
--- a/src/views/gcal-month-view.c
+++ b/src/views/gcal-month-view.c
@@ -972,17 +972,23 @@ gcal_month_view_clear_marks (GcalView *view)
 }
 
 static GList*
-gcal_month_view_get_children_by_uuid (GcalView    *view,
-                                      const gchar *uuid)
+gcal_month_view_get_children_by_uuid (GcalView              *view,
+                                      GcalRecurrenceModType  mod,
+                                      const gchar           *uuid)
 {
   GcalSubscriberViewPrivate *ppriv = GCAL_SUBSCRIBER_VIEW (view)->priv;
-  GList *l;
+  GHashTableIter iter;
+  GList *children;
+  GList *tmp;
+
+  children = NULL;
+
+  g_hash_table_iter_init (&iter, ppriv->children);
 
-  l = g_hash_table_lookup (ppriv->children, uuid);
-  if (l != NULL)
-    return g_list_reverse (g_list_copy (l));
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &tmp))
+    children = g_list_concat (children, g_list_copy (tmp));
 
-  return NULL;
+  return filter_event_list_by_uid_and_modtype (children, mod, uuid);
 }
 
 static void
diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c
index e33c8c7..a070a3d 100644
--- a/src/views/gcal-week-grid.c
+++ b/src/views/gcal-week-grid.c
@@ -19,6 +19,7 @@
 
 #define G_LOG_DOMAIN "GcalWeekGrid"
 
+#include "gcal-debug.h"
 #include "gcal-week-grid.h"
 #include "gcal-week-view.h"
 #include "gcal-utils.h"
@@ -1238,32 +1239,33 @@ gcal_week_grid_remove_event (GcalWeekGrid *self,
 }
 
 GList*
-gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self,
-                                     const gchar  *uid)
+gcal_week_grid_get_children_by_uuid (GcalWeekGrid          *self,
+                                     GcalRecurrenceModType  mod,
+                                     const gchar           *uid)
 {
   GPtrArray *widgets;
+  GList *events;
   GList *result;
   guint i;
 
+  GCAL_ENTRY;
+
+  events = NULL;
   result = NULL;
   widgets = gcal_range_tree_get_data_at_range (self->events, 0, MAX_MINUTES);
 
   for (i = 0; widgets && i < widgets->len; i++)
     {
-      ChildData *data;
-      GcalEvent *event;
-
-      data = g_ptr_array_index (widgets, i);
-      event = gcal_event_widget_get_event (GCAL_EVENT_WIDGET (data->widget));
-
-      if (g_strcmp0 (gcal_event_get_uid (event), uid) == 0)
-        result = g_list_prepend (result, data->widget);
-
+      ChildData *data = g_ptr_array_index (widgets, i);
+      events = g_list_prepend (events, data->widget);
     }
 
+  result = filter_event_list_by_uid_and_modtype (events, mod, uid);
+
   g_clear_pointer (&widgets, g_ptr_array_unref);
+  g_clear_pointer (&events, g_list_free);
 
-  return result;
+  GCAL_RETURN (result);
 }
 
 void
diff --git a/src/views/gcal-week-grid.h b/src/views/gcal-week-grid.h
index 2d519b3..ca6692f 100644
--- a/src/views/gcal-week-grid.h
+++ b/src/views/gcal-week-grid.h
@@ -46,8 +46,9 @@ void                 gcal_week_grid_add_event                    (GcalWeekGrid
 void                 gcal_week_grid_remove_event                 (GcalWeekGrid       *self,
                                                                   const gchar        *uid);
 
-GList*               gcal_week_grid_get_children_by_uuid         (GcalWeekGrid       *self,
-                                                                  const gchar        *uid);
+GList*               gcal_week_grid_get_children_by_uuid         (GcalWeekGrid          *self,
+                                                                  GcalRecurrenceModType  mod,
+                                                                  const gchar           *uid);
 
 void                 gcal_week_grid_clear_marks                  (GcalWeekGrid       *self);
 
diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c
index b59f554..1ac9548 100644
--- a/src/views/gcal-week-header.c
+++ b/src/views/gcal-week-header.c
@@ -1677,32 +1677,20 @@ gcal_week_header_remove_event (GcalWeekHeader *self,
 }
 
 GList*
-gcal_week_header_get_children_by_uuid (GcalWeekHeader *self,
-                                       const gchar    *uuid)
+gcal_week_header_get_children_by_uuid (GcalWeekHeader        *self,
+                                       GcalRecurrenceModType  mod,
+                                       const gchar           *uuid)
 {
-  GList *children, *l, *result;
+  GList *children, *result;
 
-  result = NULL;
-  children = gtk_container_get_children (GTK_CONTAINER (self->grid));
-
-  for (l = children; l != NULL; l = l->next)
-    {
-      GcalEventWidget *child_widget;
-      GcalEvent *event;
-
-      if (!GCAL_IS_EVENT_WIDGET (l->data))
-        continue;
-
-      child_widget = GCAL_EVENT_WIDGET (l->data);
-      event = gcal_event_widget_get_event (child_widget);
+  GCAL_ENTRY;
 
-      if (g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
-        result = g_list_prepend (result, l->data);
-    }
+  children = gtk_container_get_children (GTK_CONTAINER (self->grid));
+  result = filter_event_list_by_uid_and_modtype (children, mod, uuid);
 
   g_list_free (children);
 
-  return result;
+  GCAL_RETURN (result);
 }
 
 GtkSizeGroup*
diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h
index 8c9d904..da0289d 100644
--- a/src/views/gcal-week-header.h
+++ b/src/views/gcal-week-header.h
@@ -46,8 +46,9 @@ void                 gcal_week_header_add_event                  (GcalWeekHeader
 void                 gcal_week_header_remove_event               (GcalWeekHeader     *self,
                                                                   const gchar        *uuid);
 
-GList*               gcal_week_header_get_children_by_uuid       (GcalWeekHeader     *self,
-                                                                  const gchar        *uuid);
+GList*               gcal_week_header_get_children_by_uuid       (GcalWeekHeader        *self,
+                                                                  GcalRecurrenceModType  mod,
+                                                                  const gchar           *uuid);
 
 GtkSizeGroup*        gcal_week_header_get_sidebar_size_group     (GcalWeekHeader     *self);
 
diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c
index ebbbcd8..9e92faf 100644
--- a/src/views/gcal-week-view.c
+++ b/src/views/gcal-week-view.c
@@ -220,17 +220,20 @@ gcal_week_view_set_date (GcalView     *view,
 }
 
 static GList*
-gcal_week_view_get_children_by_uuid (GcalView    *view,
-                                     const gchar *uuid)
+gcal_week_view_get_children_by_uuid (GcalView              *view,
+                                     GcalRecurrenceModType  mod,
+                                     const gchar           *uuid)
 {
   GcalWeekView *self;
   GList *grid, *header;
 
+  GCAL_ENTRY;
+
   self = GCAL_WEEK_VIEW (view);
-  grid = gcal_week_grid_get_children_by_uuid (GCAL_WEEK_GRID (self->week_grid), uuid);
-  header = gcal_week_header_get_children_by_uuid (GCAL_WEEK_HEADER (self->header), uuid);
+  grid = gcal_week_grid_get_children_by_uuid (GCAL_WEEK_GRID (self->week_grid), mod, uuid);
+  header = gcal_week_header_get_children_by_uuid (GCAL_WEEK_HEADER (self->header), mod, uuid);
 
-  return g_list_concat (grid, header);
+  GCAL_RETURN (g_list_concat (grid, header));
 }
 
 static void
diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c
index 4780af8..a7b13a3 100644
--- a/src/views/gcal-year-view.c
+++ b/src/views/gcal-year-view.c
@@ -1589,26 +1589,17 @@ gcal_year_view_set_date (GcalView     *view,
 }
 
 static GList*
-gcal_year_view_get_children_by_uuid (GcalView    *view,
-                                     const gchar *uuid)
+gcal_year_view_get_children_by_uuid (GcalView              *view,
+                                     GcalRecurrenceModType  mod,
+                                     const gchar           *uuid)
 {
-  GcalYearView *year_view = GCAL_YEAR_VIEW (view);
-  GList *children, *l, *result = NULL;
-
-  children = gtk_container_get_children (GTK_CONTAINER (year_view->events_sidebar));
-
-  for (l = children; l != NULL; l = g_list_next (l))
-    {
-      GcalEventWidget *child_widget;
-      GcalEvent *event;
-
-      child_widget = GCAL_EVENT_WIDGET (gtk_bin_get_child (GTK_BIN (l->data)));
-      event = gcal_event_widget_get_event (child_widget);
+  GcalYearView *self = GCAL_YEAR_VIEW (view);
+  GList *result, *children;
 
+  result = NULL;
 
-      if (child_widget != NULL && g_strcmp0 (uuid, gcal_event_get_uid (event)) == 0)
-        result = g_list_append (result, child_widget);
-    }
+  children = gtk_container_get_children (GTK_CONTAINER (self->sidebar));
+  result = filter_event_list_by_uid_and_modtype (children, mod, uuid);
 
   g_list_free (children);
 


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