[gnome-calendar/gbsneto/timeline: 10/17] Move Shell search to GcalShellSearchProvider
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar/gbsneto/timeline: 10/17] Move Shell search to GcalShellSearchProvider
- Date: Wed, 1 Apr 2020 22:38:39 +0000 (UTC)
commit 6d3ea978f7ac4c19b2f41676c32db27761824a3f
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri Mar 27 12:39:08 2020 -0300
Move Shell search to GcalShellSearchProvider
Add a custom timeline to GcalShellSearchProvier and use
it to gather events.
Do a massive cleanup of unused APIs as well.
src/core/gcal-calendar-monitor.c | 44 +++++
src/core/gcal-manager.c | 304 ----------------------------------
src/core/gcal-manager.h | 24 ---
src/core/gcal-shell-search-provider.c | 194 +++++++++++++++-------
src/core/gcal-timeline.c | 69 ++++++++
src/core/gcal-timeline.h | 2 +
6 files changed, 249 insertions(+), 388 deletions(-)
---
diff --git a/src/core/gcal-calendar-monitor.c b/src/core/gcal-calendar-monitor.c
index e61da075..a84ceaac 100644
--- a/src/core/gcal-calendar-monitor.c
+++ b/src/core/gcal-calendar-monitor.c
@@ -84,6 +84,7 @@ struct _GcalCalendarMonitor
static gboolean add_event_to_timeline_in_idle_cb (gpointer user_data);
static gboolean update_event_in_idle_cb (gpointer user_data);
static gboolean remove_event_from_timeline_in_idle_cb (gpointer user_data);
+static gboolean complete_in_idle_cb (gpointer user_data);
G_DEFINE_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT)
@@ -92,6 +93,7 @@ enum
EVENT_ADDED,
EVENT_UPDATED,
EVENT_REMOVED,
+ COMPLETED,
N_SIGNALS,
};
@@ -241,6 +243,21 @@ remove_event_in_idle (GcalCalendarMonitor *self,
(GDestroyNotify) idle_data_free);
}
+static void
+complete_in_idle (GcalCalendarMonitor *self)
+{
+ IdleData *idle_data;
+
+ idle_data = g_new0 (IdleData, 1);
+ idle_data->monitor = g_object_ref (self);
+
+ g_main_context_invoke_full (self->main_context,
+ G_PRIORITY_DEFAULT_IDLE,
+ complete_in_idle_cb,
+ idle_data,
+ (GDestroyNotify) idle_data_free);
+}
+
typedef struct
{
GcalCalendarMonitor *monitor;
@@ -568,6 +585,8 @@ on_client_view_complete_cb (ECalClientView *view,
self->monitor_thread.populated = TRUE;
+ complete_in_idle (self);
+
g_debug ("Finished initial loading of calendar '%s'", gcal_calendar_get_name (self->calendar));
GCAL_EXIT;
@@ -939,6 +958,24 @@ on_calendar_visible_changed_cb (GcalCalendar *calendar,
}
}
+static gboolean
+complete_in_idle_cb (gpointer user_data)
+{
+ g_autoptr (GcalEvent) event = NULL;
+ GcalCalendarMonitor *self;
+ IdleData *idle_data;
+
+ GCAL_ENTRY;
+
+ idle_data = user_data;
+ self = idle_data->monitor;
+ g_assert (idle_data->event == NULL);
+ g_assert (idle_data->event_id == NULL);
+
+ g_signal_emit (self, signals[COMPLETED], 0, event);
+ GCAL_RETURN (G_SOURCE_REMOVE);
+}
+
/*
* GObject overrides
@@ -1044,6 +1081,13 @@ gcal_calendar_monitor_class_init (GcalCalendarMonitorClass *klass)
1,
GCAL_TYPE_EVENT);
+ signals[COMPLETED] = g_signal_new ("completed",
+ GCAL_TYPE_CALENDAR_MONITOR,
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0);
+
properties[PROP_CALENDAR] = g_param_spec_object ("calendar",
"Calendar",
"Calendar to be monitores",
diff --git a/src/core/gcal-manager.c b/src/core/gcal-manager.c
index 317765a5..e9729c81 100644
--- a/src/core/gcal-manager.c
+++ b/src/core/gcal-manager.c
@@ -45,16 +45,6 @@ typedef struct
GcalManager *manager;
} AsyncOpsData;
-typedef struct
-{
- ECalDataModelSubscriber *subscriber;
- gchar *query;
-
- guint sources_left;
- gboolean passed_start;
- gboolean search_done;
-} ViewStateData;
-
typedef struct
{
gchar *event_uid;
@@ -64,12 +54,6 @@ typedef struct
GcalManager *manager;
} MoveEventData;
-typedef struct
-{
- GcalManager *manager;
- GList *events;
-} GatherEventData;
-
struct _GcalManager
{
GObject parent;
@@ -84,9 +68,6 @@ struct _GcalManager
ESourceRegistry *source_registry;
ECredentialsPrompter *credentials_prompter;
- ECalDataModel *shell_search_data_model;
- ViewStateData *search_view_data;
-
GCancellable *async_ops;
gint clients_synchronizing;
@@ -126,36 +107,6 @@ free_async_ops_data (AsyncOpsData *data)
g_free (data);
}
-static gboolean
-gather_events (ECalDataModel *data_model,
- ECalClient *client,
- const ECalComponentId *id,
- ECalComponent *comp,
- time_t instance_start,
- time_t instance_end,
- gpointer user_data)
-{
- GatherEventData *data = user_data;
- GcalCalendar *calendar;
- GcalEvent *event;
- GError *error;
-
- error = NULL;
- calendar = g_hash_table_lookup (data->manager->clients, e_client_get_source (E_CLIENT (client)));
- event = gcal_event_new (calendar, comp, &error);
-
- if (error)
- {
- g_warning ("Error: %s", error->message);
- g_clear_error (&error);
- return TRUE;
- }
-
- data->events = g_list_append (data->events, event);/* FIXME: add me sorted */
-
- return TRUE;
-}
-
static void
remove_source (GcalManager *self,
ESource *source)
@@ -198,21 +149,6 @@ source_changed (GcalManager *self,
if (!calendar)
GCAL_RETURN ();
- if (gcal_calendar_get_visible (calendar))
- {
- ECalClient *client = gcal_calendar_get_client (calendar);
-
- if (self->shell_search_data_model)
- e_cal_data_model_add_client (self->shell_search_data_model, client);
- }
- else
- {
- const gchar *id = gcal_calendar_get_id (calendar);
-
- if (self->shell_search_data_model)
- e_cal_data_model_remove_client (self->shell_search_data_model, id);
- }
-
g_signal_emit (self, signals[CALENDAR_CHANGED], 0, calendar);
GCAL_EXIT;
@@ -286,12 +222,6 @@ on_calendar_created_cb (GObject *source_object,
gcal_timeline_add_calendar (self->timeline, calendar);
- if (visible)
- {
- if (self->shell_search_data_model != NULL)
- e_cal_data_model_add_client (self->shell_search_data_model, client);
- }
-
/* refresh client when it's added */
if (visible && e_client_check_refresh_supported (E_CLIENT (client)))
{
@@ -464,45 +394,6 @@ on_event_removed (GObject *source_object,
GCAL_EXIT;
}
-static void
-model_state_changed (GcalManager *self,
- ECalClientView *view,
- ECalDataModelViewState state,
- guint percent,
- const gchar *message,
- const GError *error,
- ECalDataModel *data_model)
-{
- gchar *filter;
-
- GCAL_ENTRY;
-
- filter = e_cal_data_model_dup_filter (data_model);
-
- if (state == E_CAL_DATA_MODEL_VIEW_STATE_START &&
- g_strcmp0 (self->search_view_data->query, filter) == 0)
- {
- self->search_view_data->passed_start = TRUE;
- GCAL_GOTO (out);
- }
-
- if (self->search_view_data->passed_start &&
- state == E_CAL_DATA_MODEL_VIEW_STATE_COMPLETE &&
- g_strcmp0 (self->search_view_data->query, filter) == 0)
- {
- self->search_view_data->sources_left--;
- self->search_view_data->search_done = (self->search_view_data->sources_left == 0);
-
- if (self->search_view_data->search_done)
- g_signal_emit (self, signals[QUERY_COMPLETED], 0);
- }
-
-out:
- g_free (filter);
-
- GCAL_EXIT;
-}
-
static void
show_source_error (const gchar *where,
const gchar *what,
@@ -653,7 +544,6 @@ gcal_manager_finalize (GObject *object)
GCAL_ENTRY;
g_clear_object (&self->timeline);
- g_clear_object (&self->shell_search_data_model);
if (self->context)
{
@@ -661,12 +551,6 @@ gcal_manager_finalize (GObject *object)
self->context = NULL;
}
- if (self->search_view_data)
- {
- g_clear_pointer (&self->search_view_data->query, g_free);
- g_clear_pointer (&self->search_view_data, g_free);
- }
-
g_clear_pointer (&self->clients, g_hash_table_destroy);
G_OBJECT_CLASS (gcal_manager_parent_class)->finalize (object);
@@ -903,137 +787,6 @@ gcal_manager_set_default_calendar (GcalManager *self,
gcal_calendar_get_source (calendar));
}
-/**
- * gcal_manager_setup_shell_search:
- * @self: a #GcalManager
- * @subscriber: an #ECalDataModelSubscriber
- *
- * Sets up the GNOME Shell search subscriber.
- */
-void
-gcal_manager_setup_shell_search (GcalManager *self,
- ECalDataModelSubscriber *subscriber)
-{
- GTimeZone *zone;
-
- g_return_if_fail (GCAL_IS_MANAGER (self));
-
- if (self->shell_search_data_model)
- return;
-
- self->shell_search_data_model = e_cal_data_model_new (gcal_thread_submit_job);
- g_signal_connect_object (self->shell_search_data_model,
- "view-state-changed",
- G_CALLBACK (model_state_changed),
- self,
- G_CONNECT_SWAPPED);
-
- e_cal_data_model_set_expand_recurrences (self->shell_search_data_model, TRUE);
-
- zone = gcal_context_get_timezone (self->context);
- e_cal_data_model_set_timezone (self->shell_search_data_model, gcal_timezone_to_icaltimezone (zone));
-
- self->search_view_data = g_new0 (ViewStateData, 1);
- self->search_view_data->subscriber = subscriber;
-}
-
-/**
- * gcal_manager_set_shell_search_query:
- * @self: A #GcalManager instance
- * @query: query string (an s-exp)
- *
- * Set the query terms of the #ECalDataModel used in the shell search
- */
-void
-gcal_manager_set_shell_search_query (GcalManager *self,
- const gchar *query)
-{
- GCAL_ENTRY;
-
- g_return_if_fail (GCAL_IS_MANAGER (self));
-
- self->search_view_data->passed_start = FALSE;
- self->search_view_data->search_done = FALSE;
- self->search_view_data->sources_left = g_hash_table_size (self->clients);
-
- if (self->search_view_data->query != NULL)
- g_free (self->search_view_data->query);
- self->search_view_data->query = g_strdup (query);
-
- e_cal_data_model_set_filter (self->shell_search_data_model, query);
-}
-
-/**
- * gcal_manager_set_shell_search_subscriber:
- * @self: a #GcalManager
- * @subscriber: the #ECalDataModelSubscriber to subscribe
- * @range_start: the start of the range
- * @range_end: the end of the range
- *
- * Subscribe @subscriber to the shell data modal at the given range.
- */
-void
-gcal_manager_set_shell_search_subscriber (GcalManager *self,
- ECalDataModelSubscriber *subscriber,
- time_t range_start,
- time_t range_end)
-{
- GCAL_ENTRY;
-
- e_cal_data_model_subscribe (self->shell_search_data_model, subscriber, range_start, range_end);
-
- GCAL_EXIT;
-}
-
-/**
- * gcal_manager_shell_search_done:
- * @self: a #GcalManager
- *
- * Retrieves whether the search at @self is done or not.
- *
- * Returns: %TRUE if the search is finished.
- */
-gboolean
-gcal_manager_shell_search_done (GcalManager *self)
-{
- g_return_val_if_fail (GCAL_IS_MANAGER (self), FALSE);
-
- return self->search_view_data->search_done;
-}
-
-/**
- * gcal_manager_get_shell_search_events:
- * @self: a #GcalManager
- *
- * Retrieves all the events available for GNOME Shell search.
- *
- * Returns: (nullable)(transfer full)(content-type GcalEvent): a #GList
- */
-GList*
-gcal_manager_get_shell_search_events (GcalManager *self)
-{
- time_t range_start, range_end;
- GatherEventData data = {
- .manager = self,
- .events = NULL,
- };
-
- GCAL_ENTRY;
-
- e_cal_data_model_get_subscriber_range (self->shell_search_data_model,
- self->search_view_data->subscriber,
- &range_start,
- &range_end);
-
- e_cal_data_model_foreach_component (self->shell_search_data_model,
- range_start,
- range_end,
- gather_events,
- &data);
-
- GCAL_RETURN (data.events);
-}
-
/**
* gcal_manager_set_subscriber:
* @self: a #GcalManager
@@ -1469,63 +1222,6 @@ gcal_manager_get_events (GcalManager *self,
GCAL_RETURN (g_steal_pointer (&events_at_range));
}
-/**
- * gcal_manager_get_event_from_shell_search:
- * @self: a #GcalManager
- * @uuid: the unique identier of the event
- *
- * Retrieves the #GcalEvent with @uuid.
- *
- * Returns: (nullable)(transfer full): a #GcalEvent
- */
-GcalEvent*
-gcal_manager_get_event_from_shell_search (GcalManager *self,
- const gchar *uuid)
-{
- GcalEvent *new_event;
- GList *l;
- time_t range_start, range_end;
- GatherEventData data = {
- .manager = self,
- .events = NULL,
- };
-
-
- GCAL_ENTRY;
-
- g_return_val_if_fail (GCAL_IS_MANAGER (self), NULL);
-
- new_event = NULL;
-
- e_cal_data_model_get_subscriber_range (self->shell_search_data_model,
- self->search_view_data->subscriber,
- &range_start,
- &range_end);
-
- e_cal_data_model_foreach_component (self->shell_search_data_model,
- range_start,
- range_end,
- gather_events,
- &data);
-
- for (l = data.events; l != NULL; l = g_list_next (l))
- {
- GcalEvent *event;
-
- event = l->data;
-
- /* Found the event */
- if (g_strcmp0 (gcal_event_get_uid (event), uuid) == 0)
- new_event = event;
- else
- g_object_unref (event);
- }
-
- g_list_free (data.events);
-
- GCAL_RETURN (new_event);
-}
-
/**
* gcal_manager_get_synchronizing:
* @self: a #GcalManager
diff --git a/src/core/gcal-manager.h b/src/core/gcal-manager.h
index e4f91392..f59add2d 100644
--- a/src/core/gcal-manager.h
+++ b/src/core/gcal-manager.h
@@ -48,11 +48,6 @@ void gcal_manager_set_subscriber (GcalManager
time_t range_start,
time_t range_end);
-void gcal_manager_set_search_subscriber (GcalManager *self,
- ECalDataModelSubscriber *subscriber,
- time_t range_start,
- time_t range_end);
-
void gcal_manager_set_query (GcalManager *self,
const gchar *query);
@@ -89,25 +84,6 @@ GPtrArray* gcal_manager_get_events (GcalManager
GDateTime *range_start,
GDateTime *range_end);
-/* GNOME Shell-related functions */
-GcalEvent* gcal_manager_get_event_from_shell_search (GcalManager *self,
- const gchar *uuid);
-
-void gcal_manager_setup_shell_search (GcalManager *self,
- ECalDataModelSubscriber *subscriber);
-
-void gcal_manager_set_shell_search_query (GcalManager *self,
- const gchar *query);
-
-void gcal_manager_set_shell_search_subscriber (GcalManager *self,
- ECalDataModelSubscriber *subscriber,
- time_t range_start,
- time_t range_end);
-
-gboolean gcal_manager_shell_search_done (GcalManager *self);
-
-GList* gcal_manager_get_shell_search_events (GcalManager *self);
-
gboolean gcal_manager_get_synchronizing (GcalManager *self);
void gcal_manager_startup (GcalManager *self);
diff --git a/src/core/gcal-shell-search-provider.c b/src/core/gcal-shell-search-provider.c
index 1ab0390a..a9391f00 100644
--- a/src/core/gcal-shell-search-provider.c
+++ b/src/core/gcal-shell-search-provider.c
@@ -24,6 +24,8 @@
#include "gcal-application.h"
#include "gcal-debug.h"
#include "gcal-event.h"
+#include "gcal-timeline.h"
+#include "gcal-timeline-subscriber.h"
#include "gcal-window.h"
#include "gcal-utils.h"
@@ -42,12 +44,17 @@ struct _GcalShellSearchProvider
PendingSearch *pending_search;
GHashTable *events;
+
+ GDateTime *range_start;
+ GDateTime *range_end;
+ GcalTimeline *timeline;
};
-static void gcal_subscriber_interface_init (ECalDataModelSubscriberInterface *iface);
+static void gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GcalShellSearchProvider, gcal_shell_search_provider, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER,
gcal_subscriber_interface_init));
+ G_IMPLEMENT_INTERFACE (GCAL_TYPE_TIMELINE_SUBSCRIBER,
+ gcal_timeline_subscriber_interface_init));
enum
{
@@ -71,48 +78,65 @@ sort_event_data (GcalEvent *a,
return gcal_event_compare_with_current (a, b, GPOINTER_TO_INT (user_data));
}
-static gboolean
-execute_search (GcalShellSearchProvider *self)
+static void
+maybe_update_range (GcalShellSearchProvider *self)
{
g_autoptr (GDateTime) start = NULL;
g_autoptr (GDateTime) end = NULL;
g_autoptr (GDateTime) now = NULL;
- g_autofree gchar *search_query = NULL;
- GcalManager *manager;
- time_t range_start, range_end;
- guint i;
+ gboolean range_changed = FALSE;
GCAL_ENTRY;
- manager = gcal_context_get_manager (self->context);
-
now = g_date_time_new_now (gcal_context_get_timezone (self->context));
start = g_date_time_add_weeks (now, -1);
- range_start = g_date_time_to_unix (start);
-
end = g_date_time_add_weeks (now, 3);
- range_end = g_date_time_to_unix (end);
- gcal_manager_set_shell_search_subscriber (manager,
- E_CAL_DATA_MODEL_SUBSCRIBER (self),
- range_start, range_end);
+ if (self->range_start && gcal_date_time_compare_date (self->range_start, start) != 0)
+ {
+ gcal_set_date_time (&self->range_start, start);
+ range_changed = TRUE;
+ }
+
+ if (self->range_end && gcal_date_time_compare_date (self->range_end, end) != 0)
+ {
+ gcal_set_date_time (&self->range_end, end);
+ range_changed = TRUE;
+ }
+
+ if (range_changed)
+ gcal_timeline_subscriber_range_changed (GCAL_TIMELINE_SUBSCRIBER (self));
+}
+
+static gboolean
+execute_search (GcalShellSearchProvider *self)
+{
+ g_autofree gchar *search_query = NULL;
+ guint i;
+
+ GCAL_ENTRY;
+
+ maybe_update_range (self);
search_query = g_strdup_printf ("(or (contains? \"summary\" \"%s\") (contains? \"description\" \"%s\"))",
- self->pending_search->terms[0], self->pending_search->terms[0]);
+ self->pending_search->terms[0],
+ self->pending_search->terms[0]);
+
for (i = 1; i < g_strv_length (self->pending_search->terms); i++)
{
g_autofree gchar *complete_query = NULL;
g_autofree gchar *second_query = NULL;
second_query = g_strdup_printf ("(or (contains? \"summary\" \"%s\") (contains? \"description\"
\"%s\"))",
- self->pending_search->terms[0], self->pending_search->terms[0]);
+ self->pending_search->terms[0],
+ self->pending_search->terms[0]);
complete_query = g_strdup_printf ("(and %s %s)", search_query, second_query);
g_clear_pointer (&search_query, g_free);
search_query = g_steal_pointer (&complete_query);
}
- gcal_manager_set_shell_search_query (manager, search_query);
+ gcal_timeline_set_filter (self->timeline, search_query);
g_application_hold (g_application_get_default ());
GCAL_RETURN (FALSE);
@@ -240,15 +264,13 @@ activate_result_cb (GcalShellSearchProvider *self,
{
g_autoptr (GcalEvent) event = NULL;
GApplication *application;
- GcalManager *manager;
GDateTime *dtstart;
GCAL_ENTRY;
application = g_application_get_default ();
- manager = gcal_context_get_manager (self->context);
- event = gcal_manager_get_event_from_shell_search (manager, result);
+ event = g_hash_table_lookup (self->events, result);
dtstart = gcal_event_get_date_start (event);
gcal_application_set_uuid (GCAL_APPLICATION (application), result);
@@ -283,20 +305,23 @@ launch_search_cb (GcalShellSearchProvider *self,
GCAL_RETURN (TRUE);
}
-static gboolean
-query_completed_cb (GcalShellSearchProvider *self,
- GcalManager *manager)
+static void
+on_timeline_completed_cb (GcalTimeline *timeline,
+ GParamSpec *pspec,
+ GcalShellSearchProvider *self)
{
GVariantBuilder builder;
- GList *events, *l;
+ g_autoptr (GList) events = NULL;
+ GList *l;
time_t current_time_t;
GCAL_ENTRY;
- g_hash_table_remove_all (self->events);
+ if (!gcal_timeline_is_complete (timeline))
+ GCAL_RETURN ();
- events = gcal_manager_get_shell_search_events (manager);
- if (events == NULL)
+ events = g_hash_table_get_values (self->events);
+ if (!events)
{
g_dbus_method_invocation_return_value (self->pending_search->invocation, g_variant_new ("(as)", NULL));
GCAL_GOTO (out);
@@ -319,7 +344,6 @@ query_completed_cb (GcalShellSearchProvider *self,
g_hash_table_insert (self->events, g_strdup (uid), l->data);
}
- g_list_free (events);
g_dbus_method_invocation_return_value (self->pending_search->invocation, g_variant_new ("(as)", &builder));
@@ -329,51 +353,95 @@ out:
g_clear_pointer (&self->pending_search, g_free);
g_application_release (g_application_get_default ());
- GCAL_RETURN (FALSE);
+ GCAL_EXIT;
+}
+
+static void
+on_manager_calendar_added_cb (GcalManager *manager,
+ GcalCalendar *calendar,
+ GcalShellSearchProvider *self)
+{
+ GCAL_ENTRY;
+
+ gcal_timeline_add_calendar (self->timeline, calendar);
+
+ GCAL_EXIT;
}
+static void
+on_manager_calendar_removed_cb (GcalManager *manager,
+ GcalCalendar *calendar,
+ GcalShellSearchProvider *self)
+{
+ GCAL_ENTRY;
+
+ gcal_timeline_remove_calendar (self->timeline, calendar);
+
+ GCAL_EXIT;
+}
/*
- * ECalDataModelSubscriber iface
+ * GcalTimelineSubscriber iface
*/
-static void
-gcal_shell_search_provider_component_changed (ECalDataModelSubscriber *subscriber,
- ECalClient *client,
- ECalComponent *comp)
+static GDateTime*
+gcal_shell_search_provider_get_range_start (GcalTimelineSubscriber *subscriber)
{
- ;
+ GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
+
+ return g_date_time_ref (self->range_start);
+}
+
+static GDateTime*
+gcal_shell_search_provider_get_range_end (GcalTimelineSubscriber *subscriber)
+{
+ GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
+
+ return g_date_time_ref (self->range_end);
}
static void
-gcal_shell_search_provider_component_removed (ECalDataModelSubscriber *subscriber,
- ECalClient *client,
- const gchar *uid,
- const gchar *rid)
+gcal_shell_search_provider_add_event (GcalTimelineSubscriber *subscriber,
+ GcalEvent *event)
{
- ;
+ GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
+
+ GCAL_ENTRY;
+
+ g_hash_table_insert (self->events,
+ g_strdup (gcal_event_get_uid (event)),
+ g_object_ref (event));
+
+ GCAL_EXIT;
}
static void
-gcal_shell_search_provider_freeze (ECalDataModelSubscriber *subscriber)
+gcal_shell_search_provider_update_event (GcalTimelineSubscriber *subscriber,
+ GcalEvent *event)
{
- ;
}
static void
-gcal_shell_search_provider_thaw (ECalDataModelSubscriber *subscriber)
+gcal_shell_search_provider_remove_event (GcalTimelineSubscriber *subscriber,
+ GcalEvent *event)
{
- ;
+ GcalShellSearchProvider *self = GCAL_SHELL_SEARCH_PROVIDER (subscriber);
+
+ GCAL_ENTRY;
+
+ g_hash_table_remove (self->events, gcal_event_get_uid (event));
+
+ GCAL_EXIT;
}
static void
-gcal_subscriber_interface_init (ECalDataModelSubscriberInterface *iface)
+gcal_timeline_subscriber_interface_init (GcalTimelineSubscriberInterface *iface)
{
- iface->component_added = gcal_shell_search_provider_component_changed;
- iface->component_modified = gcal_shell_search_provider_component_changed;
- iface->component_removed = gcal_shell_search_provider_component_removed;
- iface->freeze = gcal_shell_search_provider_freeze;
- iface->thaw = gcal_shell_search_provider_thaw;
+ iface->get_range_start = gcal_shell_search_provider_get_range_start;
+ iface->get_range_end = gcal_shell_search_provider_get_range_end;
+ iface->add_event = gcal_shell_search_provider_add_event;
+ iface->update_event = gcal_shell_search_provider_update_event;
+ iface->remove_event = gcal_shell_search_provider_remove_event;
}
@@ -423,15 +491,21 @@ gcal_shell_search_provider_set_property (GObject *object,
switch (property_id)
{
case PROP_CONTEXT:
- if (g_set_object (&self->context, g_value_get_object (value)))
- {
- GcalManager *manager = gcal_context_get_manager (self->context);
+ {
+ GcalManager *manager;
+
+ g_assert (self->context == NULL);
+ self->context = g_value_get_object (value);
+
+ self->timeline = gcal_timeline_new (self->context);
+ g_signal_connect (self->timeline, "notify::complete", G_CALLBACK (on_timeline_completed_cb), self);
- gcal_manager_setup_shell_search (manager, E_CAL_DATA_MODEL_SUBSCRIBER (self));
- g_signal_connect_object (manager, "query-completed", G_CALLBACK (query_completed_cb), self,
G_CONNECT_SWAPPED);
+ manager = gcal_context_get_manager (self->context);
+ g_signal_connect (manager, "calendar-added", G_CALLBACK (on_manager_calendar_added_cb), self);
+ g_signal_connect (manager, "calendar-removed", G_CALLBACK (on_manager_calendar_removed_cb), self);
- g_object_notify_by_pspec (object, properties[PROP_CONTEXT]);
- }
+ g_object_notify_by_pspec (object, properties[PROP_CONTEXT]);
+ }
break;
default:
@@ -452,7 +526,7 @@ gcal_shell_search_provider_class_init (GcalShellSearchProviderClass *klass)
"The context object",
"The context object",
GCAL_TYPE_CONTEXT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
diff --git a/src/core/gcal-timeline.c b/src/core/gcal-timeline.c
index 6cace9e4..8914d503 100644
--- a/src/core/gcal-timeline.c
+++ b/src/core/gcal-timeline.c
@@ -50,6 +50,8 @@ struct _GcalTimeline
gchar *filter;
GHashTable *calendars; /* GcalCalendar* -> GcalCalendarMonitor* */
+ gint completed_calendars;
+
GHashTable *subscribers; /* GcalTimelineSubscriber* -> SubscriberData* */
GcalRangeTree *subscriber_ranges;
@@ -63,6 +65,7 @@ G_DEFINE_TYPE (GcalTimeline, gcal_timeline, G_TYPE_OBJECT)
enum
{
PROP_0,
+ PROP_COMPLETE,
PROP_CONTEXT,
PROP_FILTER,
N_PROPS
@@ -75,6 +78,33 @@ static GParamSpec *properties [N_PROPS] = { NULL, };
* Auxiliary methods
*/
+static inline gboolean
+is_timeline_complete (GcalTimeline *self)
+{
+ return self->completed_calendars == g_hash_table_size (self->calendars);
+}
+
+static void
+reset_completed_calendars (GcalTimeline *self)
+{
+ gboolean was_complete = is_timeline_complete (self);
+
+ self->completed_calendars = 0;
+ if (is_timeline_complete (self) != was_complete)
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMPLETE]);
+}
+
+static void
+increase_completed_calendars (GcalTimeline *self)
+{
+ self->completed_calendars++;
+
+ g_assert (self->completed_calendars <= g_hash_table_size (self->calendars));
+
+ if (is_timeline_complete (self))
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMPLETE]);
+}
+
static SubscriberData*
subscriber_data_new (GcalTimelineSubscriber *subscriber)
{
@@ -226,6 +256,8 @@ update_range (GcalTimeline *self)
{
GcalCalendarMonitor *monitor;
+ reset_completed_calendars (self);
+
g_hash_table_iter_init (&iter, self->calendars);
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &monitor))
gcal_calendar_monitor_set_range (monitor, self->range_start, self->range_end);
@@ -357,6 +389,8 @@ update_calendar_monitor_filters (GcalTimeline *self)
GcalCalendarMonitor *monitor;
GHashTableIter iter;
+ reset_completed_calendars (self);
+
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);
@@ -473,6 +507,17 @@ on_calendar_monitor_event_removed_cb (GcalCalendarMonitor *monitor,
GCAL_EXIT;
}
+static void
+on_calendar_monitor_completed_cb (GcalCalendarMonitor *monitor,
+ GcalTimeline *self)
+{
+ GCAL_ENTRY;
+
+ increase_completed_calendars (self);
+
+ GCAL_EXIT;
+}
+
static gboolean
update_timeline_range_in_idle_cb (gpointer user_data)
{
@@ -538,6 +583,10 @@ gcal_timeline_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_COMPLETE:
+ g_value_set_boolean (value, is_timeline_complete (self));
+ break;
+
case PROP_CONTEXT:
g_value_set_object (value, self->context);
break;
@@ -584,6 +633,17 @@ gcal_timeline_class_init (GcalTimelineClass *klass)
object_class->get_property = gcal_timeline_get_property;
object_class->set_property = gcal_timeline_set_property;
+ /**
+ * GcalTimeline::complete:
+ *
+ * Whether all calendars in this timeline are completed.
+ */
+ properties[PROP_COMPLETE] = g_param_spec_boolean ("complete",
+ "Complete",
+ "Complete",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS);
+
/**
* GcalSearchEngine::context:
*
@@ -664,6 +724,7 @@ gcal_timeline_add_calendar (GcalTimeline *self,
g_signal_connect (monitor, "event-added", G_CALLBACK (on_calendar_monitor_event_added_cb), self);
g_signal_connect (monitor, "event-updated", G_CALLBACK (on_calendar_monitor_event_updated_cb), self);
g_signal_connect (monitor, "event-removed", G_CALLBACK (on_calendar_monitor_event_removed_cb), self);
+ g_signal_connect (monitor, "completed", G_CALLBACK (on_calendar_monitor_completed_cb), self);
g_hash_table_insert (self->calendars, calendar, g_object_ref (monitor));
if (self->range_start && self->range_end)
@@ -789,3 +850,11 @@ gcal_timeline_set_filter (GcalTimeline *self,
GCAL_EXIT;
}
+
+gboolean
+gcal_timeline_is_complete (GcalTimeline *self)
+{
+ g_return_val_if_fail (GCAL_IS_TIMELINE (self), FALSE);
+
+ return is_timeline_complete (self);
+}
diff --git a/src/core/gcal-timeline.h b/src/core/gcal-timeline.h
index 03d037d8..6d088330 100644
--- a/src/core/gcal-timeline.h
+++ b/src/core/gcal-timeline.h
@@ -52,4 +52,6 @@ const gchar* gcal_timeline_get_filter (GcalTimeline
void gcal_timeline_set_filter (GcalTimeline *self,
const gchar *filter);
+gboolean gcal_timeline_is_complete (GcalTimeline *self);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]