[gnome-calendar/gnome-3-36] timeline: Add filtering API



commit 12431fdbc1dde1469f8a460a848f79d8dcfd2e0a
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Mar 27 10:04:23 2020 -0300

    timeline: Add filtering API
    
    This will be used by the search.

 src/core/gcal-calendar-monitor.c | 50 ++++++++++++++++++++++++++------
 src/core/gcal-calendar-monitor.h |  7 +++--
 src/core/gcal-timeline.c         | 61 ++++++++++++++++++++++++++++++++++++++++
 src/core/gcal-timeline.h         |  5 ++++
 4 files changed, 113 insertions(+), 10 deletions(-)
---
diff --git a/src/core/gcal-calendar-monitor.c b/src/core/gcal-calendar-monitor.c
index 0bf66e2a..e61da075 100644
--- a/src/core/gcal-calendar-monitor.c
+++ b/src/core/gcal-calendar-monitor.c
@@ -41,6 +41,7 @@ typedef enum
   CREATE_VIEW,
   REMOVE_VIEW,
   RANGE_UPDATED,
+  FILTER_UPDATED,
   QUIT,
 } MonitorThreadEvent;
 
@@ -76,6 +77,7 @@ struct _GcalCalendarMonitor
     GMutex            mutex;
     GDateTime        *range_start;
     GDateTime        *range_end;
+    gchar            *filter;
   } shared;
 };
 
@@ -110,14 +112,15 @@ static GParamSpec *properties [N_PROPS] = { NULL, };
  */
 
 static gchar*
-build_subscriber_filter (GDateTime *range_start,
-                         GDateTime *range_end)
+build_subscriber_filter (GDateTime   *range_start,
+                         GDateTime   *range_end,
+                         const gchar *filter)
 {
   g_autoptr (GDateTime) utc_range_start = NULL;
   g_autoptr (GDateTime) utc_range_end = NULL;
   g_autofree gchar *start_str = NULL;
   g_autofree gchar *end_str = NULL;
-  g_autofree gchar *filter = NULL;
+  g_autofree gchar *result = NULL;
 
   /*
    * XXX: E-D-S ISO8601 parser is incomplete and doesn't accept the output of
@@ -130,11 +133,21 @@ build_subscriber_filter (GDateTime *range_start,
   utc_range_end = g_date_time_to_utc (range_end);
   end_str = g_date_time_format (utc_range_end, "%Y%m%dT%H%M%SZ");
 
-  filter = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\") (make-time \"%s\"))",
-                            start_str,
-                            end_str);
+  if (filter)
+    {
+      result = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\") (make-time \"%s\")) %s)",
+                                start_str,
+                                end_str,
+                                filter);
+    }
+  else
+    {
+      result = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\") (make-time \"%s\"))",
+                                start_str,
+                                end_str);
+    }
 
-  return g_steal_pointer (&filter);
+  return g_steal_pointer (&result);
 }
 
 static void
@@ -578,7 +591,7 @@ create_view (GcalCalendarMonitor *self)
   g_assert (self->shared.range_start != NULL);
   g_assert (self->shared.range_end != NULL);
 
-  filter = build_subscriber_filter (self->shared.range_start, self->shared.range_end);
+  filter = build_subscriber_filter (self->shared.range_start, self->shared.range_end, self->shared.filter);
 
   g_mutex_unlock (&self->shared.mutex);
 
@@ -686,6 +699,7 @@ message_queue_source_dispatch (GSource     *source,
 
   switch (event)
     {
+    case FILTER_UPDATED:
     case RANGE_UPDATED:
       remove_view (self);
       create_view (self);
@@ -946,6 +960,7 @@ gcal_calendar_monitor_finalize (GObject *object)
   g_clear_pointer (&self->thread_context, g_main_context_unref);
   g_clear_pointer (&self->main_context, g_main_context_unref);
   g_clear_pointer (&self->messages, g_async_queue_unref);
+  g_clear_pointer (&self->shared.filter, g_free);
   gcal_clear_date_time (&self->shared.range_start);
   gcal_clear_date_time (&self->shared.range_end);
 
@@ -1129,3 +1144,22 @@ gcal_calendar_monitor_get_cached_event (GcalCalendarMonitor *self,
 
   return event ? g_object_ref (event) : NULL;
 }
+
+void
+gcal_calendar_monitor_set_filter (GcalCalendarMonitor *self,
+                                  const gchar         *filter)
+{
+  g_return_if_fail (GCAL_IS_CALENDAR_MONITOR (self));
+
+  g_mutex_lock (&self->shared.mutex);
+
+  g_clear_pointer (&self->shared.filter, g_free);
+  self->shared.filter = g_strdup (filter);
+
+  g_mutex_unlock (&self->shared.mutex);
+
+  remove_all_events (self);
+
+  if (gcal_calendar_get_visible (self->calendar))
+    notify_view_thread (self, FILTER_UPDATED);
+}
diff --git a/src/core/gcal-calendar-monitor.h b/src/core/gcal-calendar-monitor.h
index a6423f16..b2cb94d0 100644
--- a/src/core/gcal-calendar-monitor.h
+++ b/src/core/gcal-calendar-monitor.h
@@ -35,7 +35,10 @@ void                 gcal_calendar_monitor_set_range             (GcalCalendarMo
                                                                   GDateTime           *range_start,
                                                                   GDateTime           *range_end);
 
-GcalEvent*           gcal_calendar_monitor_get_cached_event     (GcalCalendarMonitor  *self,
-                                                                 const gchar          *event_id);
+GcalEvent*           gcal_calendar_monitor_get_cached_event      (GcalCalendarMonitor  *self,
+                                                                  const gchar          *event_id);
+
+void                 gcal_calendar_monitor_set_filter            (GcalCalendarMonitor *self,
+                                                                  const gchar         *filter);
 
 G_END_DECLS
diff --git a/src/core/gcal-timeline.c b/src/core/gcal-timeline.c
index 4ad57102..be0d57f9 100644
--- a/src/core/gcal-timeline.c
+++ b/src/core/gcal-timeline.c
@@ -47,6 +47,7 @@ struct _GcalTimeline
   GDateTime          *range_end;
 
   GcalRangeTree      *events;
+  gchar              *filter;
 
   GHashTable         *calendars; /* GcalCalendar* -> GcalCalendarMonitor* */
   GHashTable         *subscribers; /* GcalTimelineSubscriber* -> SubscriberData* */
@@ -63,6 +64,7 @@ enum
 {
   PROP_0,
   PROP_CONTEXT,
+  PROP_FILTER,
   N_PROPS
 };
 
@@ -349,6 +351,17 @@ update_subscriber_range (GcalTimeline           *self,
   GCAL_EXIT;
 }
 
+static void
+update_calendar_monitor_filters (GcalTimeline *self)
+{
+  GcalCalendarMonitor *monitor;
+  GHashTableIter iter;
+
+  g_hash_table_iter_init (&iter, self->calendars);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &monitor))
+    gcal_calendar_monitor_set_filter (monitor, self->filter);
+}
+
 
 /*
  * Callbacks
@@ -529,6 +542,10 @@ gcal_timeline_get_property (GObject    *object,
       g_value_set_object (value, self->context);
       break;
 
+    case PROP_FILTER:
+      g_value_set_string (value, self->filter);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -549,6 +566,10 @@ gcal_timeline_set_property (GObject      *object,
       self->context = g_value_get_object (value);
       break;
 
+    case PROP_FILTER:
+      gcal_timeline_set_filter (self, g_value_get_string (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -574,6 +595,17 @@ gcal_timeline_class_init (GcalTimelineClass *klass)
                                                   GCAL_TYPE_CONTEXT,
                                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
 
+  /**
+   * GcalTimeline::filter:
+   *
+   * The search filter.
+   */
+  properties[PROP_FILTER] = g_param_spec_string ("filter",
+                                                 "Filter",
+                                                 "Filter",
+                                                 NULL,
+                                                 G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | 
G_PARAM_STATIC_STRINGS);
+
   g_object_class_install_properties (object_class, N_PROPS, properties);
 }
 
@@ -711,3 +743,32 @@ gcal_timeline_remove_subscriber (GcalTimeline           *self,
 
   GCAL_EXIT;
 }
+
+const gchar*
+gcal_timeline_get_filter (GcalTimeline *self)
+{
+  g_return_val_if_fail (GCAL_IS_TIMELINE (self), NULL);
+
+  return self->filter;
+}
+
+void
+gcal_timeline_set_filter (GcalTimeline *self,
+                          const gchar  *filter)
+{
+  g_return_if_fail (GCAL_IS_TIMELINE (self));
+
+  GCAL_ENTRY;
+
+  if (g_strcmp0 (self->filter, filter) == 0)
+    GCAL_RETURN ();
+
+  g_debug ("Setting timeline filter to \"%s\"", filter);
+
+  g_clear_pointer (&self->filter, g_free);
+  self->filter = g_strdup (filter);
+
+  update_calendar_monitor_filters (self);
+
+  GCAL_EXIT;
+}
diff --git a/src/core/gcal-timeline.h b/src/core/gcal-timeline.h
index ccaa2e73..c18d297c 100644
--- a/src/core/gcal-timeline.h
+++ b/src/core/gcal-timeline.h
@@ -43,4 +43,9 @@ void                 gcal_timeline_add_subscriber                (GcalTimeline
 void                 gcal_timeline_remove_subscriber             (GcalTimeline           *self,
                                                                   GcalTimelineSubscriber *subscriber);
 
+const gchar*         gcal_timeline_get_filter                    (GcalTimeline       *self);
+
+void                 gcal_timeline_set_filter                    (GcalTimeline       *self,
+                                                                  const gchar        *filter);
+
 G_END_DECLS


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