From 25fd4ab5a936bae394c52acf60d6d95d2ea0380b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erick=20P=C3=A9rez=20Castellanos?= Date: Wed, 4 Feb 2015 12:52:18 -0500 Subject: [PATCH] manager: add shell search provider helpers Added: + :query-completed signal. This would allow to know when the search has completed and the shell search provider will be able to sort and rank the results Added API to: + set the query for the shell provider model + set the subscription of the view on the shell provider model + know when the querying of the views completed on the model and all the events are available for retrieving --- src/gcal-manager.c | 123 +++++++++++++++++++++++++++++++++++++++++---- src/gcal-manager.h | 15 +++++- 2 files changed, 125 insertions(+), 13 deletions(-) diff --git a/src/gcal-manager.c b/src/gcal-manager.c index d09e0552..831d54c3 100644 --- a/src/gcal-manager.c +++ b/src/gcal-manager.c @@ -27,6 +27,16 @@ typedef struct GcalManager *manager; } AsyncOpsData; +typedef struct +{ + ECalDataModelSubscriber *subscriber; + gchar *query; + + guint sources_left; + gboolean passed_start; + gboolean search_done; +} ViewStateData; + typedef struct { ECalClient *client; @@ -48,7 +58,9 @@ typedef struct ECalDataModel *e_data_model; ECalDataModel *search_data_model; + ECalDataModel *shell_search_data_model; + ViewStateData *search_view_data; GCancellable *async_ops; @@ -86,6 +98,7 @@ enum SOURCE_ADDED, SOURCE_REMOVED, LOAD_COMPLETED, + QUERY_COMPLETED, NUM_SIGNALS }; @@ -338,6 +351,8 @@ on_client_connected (GObject *source_object, e_cal_data_model_add_client (priv->e_data_model, client); e_cal_data_model_add_client (priv->search_data_model, client); + if (priv->shell_search_data_model != NULL) + e_cal_data_model_add_client (priv->shell_search_data_model, client); } /* refresh client when it's added */ @@ -508,6 +523,37 @@ remove_source (GcalManager *manager, g_signal_emit (manager, signals[SOURCE_REMOVED], 0, source); } +static void +model_state_changed (GcalManager *manager, + ECalClientView *view, + ECalDataModelViewState state, + guint percent, + const gchar *message, + const GError *error, + ECalDataModel *data_model) +{ + GcalManagerPrivate *priv = gcal_manager_get_instance_private (manager); + gchar *filter = e_cal_data_model_dup_filter (data_model); + if (state == E_CAL_DATA_MODEL_VIEW_STATE_START && g_strcmp0 (priv->search_view_data->query, filter) == 0) + { + priv->search_view_data->passed_start = TRUE; + goto out; + } + + if (priv->search_view_data->passed_start && state == E_CAL_DATA_MODEL_VIEW_STATE_COMPLETE && + g_strcmp0 (priv->search_view_data->query, filter) == 0) + { + priv->search_view_data->sources_left--; + priv->search_view_data->search_done = (priv->search_view_data->sources_left == 0); + if (priv->search_view_data->search_done) + g_signal_emit (manager, signals[QUERY_COMPLETED], 0); + } + +out: + g_free (filter); + return; +} + static void gcal_manager_class_init (GcalManagerClass *klass) { @@ -544,6 +590,11 @@ gcal_manager_class_init (GcalManagerClass *klass) G_STRUCT_OFFSET (GcalManagerClass, load_completed), NULL, NULL, NULL, G_TYPE_NONE, 0); + + signals[QUERY_COMPLETED] = g_signal_new ("query-completed", GCAL_TYPE_MANAGER, G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GcalManagerClass, query_completed), + NULL, NULL, NULL, + G_TYPE_NONE, 0); } static void @@ -591,8 +642,6 @@ gcal_manager_constructed (GObject *object) e_cal_data_model_set_expand_recurrences (priv->search_data_model, TRUE); e_cal_data_model_set_timezone (priv->search_data_model, priv->system_timezone); - g_signal_connect_swapped (priv->search_data_model, "view-state-changed", G_CALLBACK (model_state_changed), object); - sources = e_source_registry_list_enabled (priv->source_registry, E_SOURCE_EXTENSION_CALENDAR); priv->sources_at_launch = g_list_length (sources); @@ -617,6 +666,14 @@ gcal_manager_finalize (GObject *object) if (priv->search_data_model != NULL) g_object_unref (priv->search_data_model); + if (priv->search_view_data != NULL) + { + g_free (priv->search_view_data->query); + g_free (priv->search_view_data); + } + if (priv->shell_search_data_model != NULL) + g_object_unref (priv->shell_search_data_model); + g_hash_table_destroy (priv->clients); } @@ -749,7 +806,8 @@ gcal_manager_get_system_timezone (GcalManager *manager) } void -gcal_manager_set_shell_search (GcalManager *manager) +gcal_manager_setup_shell_search (GcalManager *manager, + ECalDataModelSubscriber *subscriber) { GcalManagerPrivate *priv; priv = gcal_manager_get_instance_private (manager); @@ -757,29 +815,72 @@ gcal_manager_set_shell_search (GcalManager *manager) if (priv->shell_search_data_model == NULL) { priv->shell_search_data_model = e_cal_data_model_new (submit_thread_job); + g_signal_connect_swapped (priv->shell_search_data_model, "view-state-changed", G_CALLBACK (model_state_changed), manager); e_cal_data_model_set_expand_recurrences (priv->shell_search_data_model, TRUE); e_cal_data_model_set_timezone (priv->shell_search_data_model, priv->system_timezone); + + priv->search_view_data = g_new0 (ViewStateData, 1); + priv->search_view_data->subscriber = subscriber; } } /** - * gcal_manager_set_shell_query: + * gcal_manager_set_shell_search_query: * @manager: A #GcalManager instance - * @query: (nullable): query terms or %NULL - * - * Set the query terms of the #ECalDataModel or clear it if %NULL is - * passed + * @query: query string (an s-exp) * + * Set the query terms of the #ECalDataModel used in the shell search **/ void -gcal_manager_set_shell_query (GcalManager *manager, - const gchar *query) +gcal_manager_set_shell_search_query (GcalManager *manager, + const gchar *query) +{ + GcalManagerPrivate *priv = gcal_manager_get_instance_private (manager); + + priv->search_view_data->passed_start = FALSE; + priv->search_view_data->search_done = FALSE; + priv->search_view_data->sources_left = g_hash_table_size (priv->clients) - g_strv_length (priv->disabled_sources); + + if (priv->search_view_data->query != NULL) + g_free (priv->search_view_data->query); + priv->search_view_data->query = g_strdup (query); + + e_cal_data_model_set_filter (priv->shell_search_data_model, query); +} + +void +gcal_manager_set_shell_search_subscriber (GcalManager *manager, + ECalDataModelSubscriber *subscriber, + time_t range_start, + time_t range_end) { GcalManagerPrivate *priv; priv = gcal_manager_get_instance_private (manager); - e_cal_data_model_set_filter (priv->shell_search_data_model, query); + e_cal_data_model_subscribe (priv->shell_search_data_model, subscriber, range_start, range_end); +} + +gboolean +gcal_manager_shell_search_done (GcalManager *manager) +{ + GcalManagerPrivate *priv = gcal_manager_get_instance_private (manager); + return priv->search_view_data->search_done; +} + +GList* +gcal_manager_get_shell_search_events (GcalManager *manager) +{ + GcalManagerPrivate *priv; + time_t range_start, range_end; + GList *list = NULL; + + priv = gcal_manager_get_instance_private (manager); + + e_cal_data_model_get_subscriber_range (priv->shell_search_data_model, priv->search_view_data->subscriber, + &range_start, &range_end); + e_cal_data_model_foreach_component (priv->shell_search_data_model, range_start, range_end, gather_components, &list); + return list; } void diff --git a/src/gcal-manager.h b/src/gcal-manager.h index b9d5f4e4..43578a11 100644 --- a/src/gcal-manager.h +++ b/src/gcal-manager.h @@ -50,6 +50,7 @@ struct _GcalManagerClass void (*source_added) (GcalManager *manager, ESource *source, gboolean enabled); void (*source_removed) (GcalManager *manager, ESource *source); void (*load_completed) (GcalManager *manager); + void (*query_completed) (GcalManager *manager); }; typedef struct @@ -70,11 +71,21 @@ ESource* gcal_manager_get_default_source (GcalManager *manager icaltimezone* gcal_manager_get_system_timezone (GcalManager *manager); -void gcal_manager_set_shell_search (GcalManager *manager); +void gcal_manager_setup_shell_search (GcalManager *manager, + ECalDataModelSubscriber *subscriber); -void gcal_manager_set_shell_query (GcalManager *manager, +void gcal_manager_set_shell_search_query (GcalManager *manager, const gchar *query); +void gcal_manager_set_shell_search_subscriber (GcalManager *manager, + ECalDataModelSubscriber *subscriber, + time_t range_start, + time_t range_end); + +gboolean gcal_manager_shell_search_done (GcalManager *manager); + +GList* gcal_manager_get_shell_search_events (GcalManager *manager); + void gcal_manager_set_subscriber (GcalManager *manager, ECalDataModelSubscriber *subscriber, time_t range_start,