From 2d46e673caa0b576a502cd0d5b68003231a43d94 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Fri, 27 Mar 2020 10:04:23 -0300 Subject: [PATCH] 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