[nautilus/wip/gbsneto/search-popover] search-engines: adapt to the new search model



commit f4a32e0fa39d83524dfe26ac1e5e375afa305375
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Oct 6 07:09:11 2015 -0300

    search-engines: adapt to the new search model
    
    The search engines currently aren't able to perform searches
    against modification or access times. Also, exposes the current
    operation status, i.e. whether it's running or not.
    
    This commit implements it for simple, model & tracker search
    engines.

 libnautilus-private/nautilus-search-directory.c    |   14 +++-
 libnautilus-private/nautilus-search-engine-model.c |   98 +++++++++++++++++++-
 .../nautilus-search-engine-simple.c                |   72 ++++++++++++--
 .../nautilus-search-engine-tracker.c               |   77 +++++++++++++++-
 libnautilus-private/nautilus-search-engine.c       |   55 +++++++++++-
 libnautilus-private/nautilus-search-provider.c     |   65 +++++--------
 libnautilus-private/nautilus-search-provider.h     |   14 ++--
 7 files changed, 328 insertions(+), 67 deletions(-)
---
diff --git a/libnautilus-private/nautilus-search-directory.c b/libnautilus-private/nautilus-search-directory.c
index 10b5525..8f5c25e 100644
--- a/libnautilus-private/nautilus-search-directory.c
+++ b/libnautilus-private/nautilus-search-directory.c
@@ -66,6 +66,8 @@ struct NautilusSearchDirectoryDetails {
        GList *callback_list;
        GList *pending_callback_list;
 
+        GBinding *binding;
+
        NautilusDirectory *base_model;
 };
 
@@ -925,18 +927,26 @@ nautilus_search_directory_set_query (NautilusSearchDirectory *search,
 
         old_query = search->details->query;
 
-       if (g_set_object (&search->details->query, query)) {
+       if (search->details->query != query) {
+               search->details->query = query;
+
+               g_clear_pointer (&search->details->binding, g_binding_unbind);
+
                 /* Disconnect from the previous query changes */
                 if (old_query) {
                         g_signal_handlers_disconnect_by_func (old_query, search_force_reload, search);
                 }
 
                 if (query) {
+                       search->details->binding = g_object_bind_property (search->details->engine, "running",
+                                                                          query, "searching",
+                                                                          G_BINDING_DEFAULT | 
G_BINDING_SYNC_CREATE);
                         g_signal_connect_swapped (query, "notify", G_CALLBACK (search_force_reload), search);
                 }
 
-
                g_object_notify_by_pspec (G_OBJECT (search), properties[PROP_QUERY]);
+
+               g_clear_object (&old_query);
        }
 
        file = nautilus_directory_get_existing_corresponding_file (NAUTILUS_DIRECTORY (search));
diff --git a/libnautilus-private/nautilus-search-engine-model.c 
b/libnautilus-private/nautilus-search-engine-model.c
index 4dfb5eb..a6542af 100644
--- a/libnautilus-private/nautilus-search-engine-model.c
+++ b/libnautilus-private/nautilus-search-engine-model.c
@@ -45,7 +45,13 @@ struct NautilusSearchEngineModelDetails {
        guint finished_id;
 };
 
-static void nautilus_search_provider_init (NautilusSearchProviderIface  *iface);
+enum {
+        PROP_0,
+        PROP_RUNNING,
+        LAST_PROP
+};
+
+static void nautilus_search_provider_init (NautilusSearchProviderInterface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (NautilusSearchEngineModel,
                         nautilus_search_engine_model,
@@ -90,6 +96,9 @@ search_finished (NautilusSearchEngineModel *model)
        }
 
        model->details->query_pending = FALSE;
+
+        g_object_notify (G_OBJECT (model), "running");
+
        DEBUG ("Model engine finished");
        nautilus_search_provider_finished (NAUTILUS_SEARCH_PROVIDER (model),
                                            NAUTILUS_SEARCH_PROVIDER_STATUS_NORMAL);
@@ -120,9 +129,11 @@ model_directory_ready_cb (NautilusDirectory        *directory,
        gdouble match;
        gboolean found;
        NautilusSearchHit *hit;
+        GDateTime *dt;
 
        files = nautilus_directory_get_file_list (directory);
        mime_types = nautilus_query_get_mime_types (model->details->query);
+        dt = nautilus_query_get_date (model->details->query);
        hits = NULL;
 
        for (l = files; l != NULL; l = l->next) {
@@ -143,9 +154,53 @@ model_directory_ready_cb (NautilusDirectory        *directory,
                        }
                }
 
+                if (found && dt != NULL) {
+                        NautilusQuerySearchType type;
+                        guint64 query_time, current_file_time;
+                        const gchar *attrib;
+                        GFileInfo *info;
+                        GError *error;
+                        GFile *location;
+
+                       g_message ("searching for date %s", g_date_time_format (dt, "%X"));
+
+                        type = nautilus_query_get_search_type (model->details->query);
+                        location = nautilus_file_get_location (file);
+                       error = NULL;
+
+                        if (type == NAUTILUS_QUERY_SEARCH_TYPE_LAST_ACCESS) {
+                                attrib = G_FILE_ATTRIBUTE_TIME_ACCESS;
+                        } else {
+                                attrib = G_FILE_ATTRIBUTE_TIME_MODIFIED;
+                        }
+
+                        query_time = g_date_time_to_unix (dt);
+
+                        /* Query current file's attribute */
+                        info = g_file_query_info (location,
+                                                  attrib,
+                                                  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                                  NULL,
+                                                  &error);
+
+                        if (error) {
+                                /* Silently ignore errors */
+                                g_clear_error (&error);
+                                found = FALSE;
+                        } else {
+                                current_file_time = g_file_info_get_attribute_uint64 (info, attrib);
+                                found = (query_time <= current_file_time);
+                        }
+
+                        g_clear_object (&location);
+                }
+
                if (found) {
                        uri = nautilus_file_get_uri (file);
                        hit = nautilus_search_hit_new (uri);
+
+                       g_message ("found in model engine - %s", uri);
+
                        nautilus_search_hit_set_fts_rank (hit, match);
                        hits = g_list_prepend (hits, hit);
                        g_free (uri);
@@ -177,6 +232,8 @@ nautilus_search_engine_model_start (NautilusSearchProvider *provider)
        g_object_ref (model);
        model->details->query_pending = TRUE;
 
+        g_object_notify (G_OBJECT (provider), "running");
+
        if (model->details->directory == NULL) {
                search_finished_idle (model);
                return;
@@ -218,12 +275,41 @@ nautilus_search_engine_model_set_query (NautilusSearchProvider *provider,
        model->details->query = query;
 }
 
+static gboolean
+nautilus_search_engine_model_is_running (NautilusSearchProvider *provider)
+{
+        NautilusSearchEngineModel *model;
+
+        model = NAUTILUS_SEARCH_ENGINE_MODEL (provider);
+
+        return model->details->query_pending;
+}
+
 static void
-nautilus_search_provider_init (NautilusSearchProviderIface *iface)
+nautilus_search_provider_init (NautilusSearchProviderInterface *iface)
 {
        iface->set_query = nautilus_search_engine_model_set_query;
        iface->start = nautilus_search_engine_model_start;
        iface->stop = nautilus_search_engine_model_stop;
+        iface->is_running = nautilus_search_engine_model_is_running;
+}
+
+static void
+nautilus_search_engine_model_get_property (GObject    *object,
+                                           guint       prop_id,
+                                           GValue     *value,
+                                           GParamSpec *pspec)
+{
+        NautilusSearchProvider *self = NAUTILUS_SEARCH_PROVIDER (object);
+
+        switch (prop_id) {
+        case PROP_RUNNING:
+                g_value_set_boolean (value, nautilus_search_engine_model_is_running (self));
+                break;
+
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
 }
 
 static void
@@ -233,6 +319,14 @@ nautilus_search_engine_model_class_init (NautilusSearchEngineModelClass *class)
 
        gobject_class = G_OBJECT_CLASS (class);
        gobject_class->finalize = finalize;
+        gobject_class->get_property = nautilus_search_engine_model_get_property;
+
+        /**
+         * NautilusSearchEngine::running:
+         *
+         * Whether the search engine is running a search.
+         */
+        g_object_class_override_property (gobject_class, PROP_RUNNING, "running");
 
        g_type_class_add_private (class, sizeof (NautilusSearchEngineModelDetails));
 }
diff --git a/libnautilus-private/nautilus-search-engine-simple.c 
b/libnautilus-private/nautilus-search-engine-simple.c
index f3557d6..35912ae 100644
--- a/libnautilus-private/nautilus-search-engine-simple.c
+++ b/libnautilus-private/nautilus-search-engine-simple.c
@@ -36,6 +36,7 @@
 
 enum {
        PROP_RECURSIVE = 1,
+        PROP_RUNNING,
        NUM_PROPERTIES
 };
 
@@ -67,9 +68,7 @@ struct NautilusSearchEngineSimpleDetails {
        gboolean query_finished;
 };
 
-static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
-
-static void nautilus_search_provider_init (NautilusSearchProviderIface  *iface);
+static void nautilus_search_provider_init (NautilusSearchProviderInterface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (NautilusSearchEngineSimple,
                         nautilus_search_engine_simple,
@@ -144,6 +143,8 @@ search_thread_done_idle (gpointer user_data)
        nautilus_search_provider_finished (NAUTILUS_SEARCH_PROVIDER (engine),
                                            NAUTILUS_SEARCH_PROVIDER_STATUS_NORMAL);
 
+        g_object_notify (G_OBJECT (engine), "running");
+
        search_thread_data_free (data);
 
        return FALSE;
@@ -195,6 +196,7 @@ send_batch (SearchThreadData *thread_data)
        G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," \
        G_FILE_ATTRIBUTE_STANDARD_TYPE "," \
        G_FILE_ATTRIBUTE_TIME_MODIFIED "," \
+        G_FILE_ATTRIBUTE_TIME_ACCESS "," \
        G_FILE_ATTRIBUTE_ID_FILE
 
 static void
@@ -250,6 +252,27 @@ visit_directory (GFile *dir, SearchThreadData *data)
                                }
                        }
                }
+
+                if (found && nautilus_query_get_date (data->query) != NULL) {
+                        NautilusQuerySearchType type;
+                        GDateTime *date;
+                        guint64 current_file_time, query_time;
+                        const gchar *attrib;
+
+                        type = nautilus_query_get_search_type (data->query);
+
+                        if (type == NAUTILUS_QUERY_SEARCH_TYPE_LAST_ACCESS) {
+                                attrib = G_FILE_ATTRIBUTE_TIME_ACCESS;
+                        } else {
+                                attrib = G_FILE_ATTRIBUTE_TIME_MODIFIED;
+                        }
+
+                        date = nautilus_query_get_date (data->query);
+                        query_time = g_date_time_to_unix (date);
+                        current_file_time = g_file_info_get_attribute_uint64 (info, attrib);
+
+                        found = (query_time <= current_file_time);
+                }
                
                if (found) {
                        NautilusSearchHit *hit;
@@ -356,6 +379,8 @@ nautilus_search_engine_simple_start (NautilusSearchProvider *provider)
        thread = g_thread_new ("nautilus-search-simple", search_thread_func, data);
        simple->details->active_search = data;
 
+        g_object_notify (G_OBJECT (provider), "running");
+
        g_thread_unref (thread);
 }
 
@@ -385,6 +410,16 @@ nautilus_search_engine_simple_set_query (NautilusSearchProvider *provider,
        simple->details->query = query;
 }
 
+static gboolean
+nautilus_search_engine_simple_is_running (NautilusSearchProvider *provider)
+{
+        NautilusSearchEngineSimple *simple;
+
+        simple = NAUTILUS_SEARCH_ENGINE_SIMPLE (provider);
+
+        return simple->details->active_search != NULL;
+}
+
 static void
 nautilus_search_engine_simple_set_property (GObject *object,
                                            guint arg_id,
@@ -416,6 +451,9 @@ nautilus_search_engine_simple_get_property (GObject *object,
        engine = NAUTILUS_SEARCH_ENGINE_SIMPLE (object);
 
        switch (arg_id) {
+       case PROP_RUNNING:
+                g_value_set_boolean (value, nautilus_search_engine_simple_is_running 
(NAUTILUS_SEARCH_PROVIDER (engine)));
+                break;
        case PROP_RECURSIVE:
                g_value_set_boolean (value, engine->details->recursive);
                break;
@@ -423,11 +461,12 @@ nautilus_search_engine_simple_get_property (GObject *object,
 }
 
 static void
-nautilus_search_provider_init (NautilusSearchProviderIface *iface)
+nautilus_search_provider_init (NautilusSearchProviderInterface *iface)
 {
        iface->set_query = nautilus_search_engine_simple_set_query;
        iface->start = nautilus_search_engine_simple_start;
        iface->stop = nautilus_search_engine_simple_stop;
+        iface->is_running = nautilus_search_engine_simple_is_running;
 }
 
 static void
@@ -440,13 +479,26 @@ nautilus_search_engine_simple_class_init (NautilusSearchEngineSimpleClass *class
        gobject_class->get_property = nautilus_search_engine_simple_get_property;
        gobject_class->set_property = nautilus_search_engine_simple_set_property;
 
-       properties[PROP_RECURSIVE] = g_param_spec_boolean ("recursive",
-                                                          "recursive",
-                                                          "recursive",
-                                                          FALSE,
-                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | 
G_PARAM_STATIC_STRINGS);
+        /**
+        * NautilusSearchEngineSimple::recursive:
+        *
+        * Whether the search is recursive or not.
+        */
+       g_object_class_install_property (gobject_class,
+                                        PROP_RECURSIVE,
+                                        g_param_spec_boolean ("recursive",
+                                                               "recursive",
+                                                               "recursive",
+                                                               FALSE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | 
G_PARAM_STATIC_STRINGS));
+
+        /**
+         * NautilusSearchEngine::running:
+         *
+         * Whether the search engine is running a search.
+         */
+        g_object_class_override_property (gobject_class, PROP_RUNNING, "running");
 
-       g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
        g_type_class_add_private (class, sizeof (NautilusSearchEngineSimpleDetails));
 }
 
diff --git a/libnautilus-private/nautilus-search-engine-tracker.c 
b/libnautilus-private/nautilus-search-engine-tracker.c
index e49a631..ec5ebdf 100644
--- a/libnautilus-private/nautilus-search-engine-tracker.c
+++ b/libnautilus-private/nautilus-search-engine-tracker.c
@@ -45,7 +45,13 @@ struct NautilusSearchEngineTrackerDetails {
        GCancellable  *cancellable;
 };
 
-static void nautilus_search_provider_init (NautilusSearchProviderIface  *iface);
+enum {
+        PROP_0,
+        PROP_RUNNING,
+        LAST_PROP
+};
+
+static void nautilus_search_provider_init (NautilusSearchProviderInterface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (NautilusSearchEngineTracker,
                         nautilus_search_engine_tracker,
@@ -111,6 +117,8 @@ search_finished (NautilusSearchEngineTracker *tracker,
 
        tracker->details->query_pending = FALSE;
 
+        g_object_notify (G_OBJECT (tracker), "running");
+
        if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
                DEBUG ("Tracker engine error %s", error->message);
                nautilus_search_provider_error (NAUTILUS_SEARCH_PROVIDER (tracker), error->message);
@@ -255,6 +263,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
        GList *mimetypes, *l;
        gint mime_count;
        gboolean recursive;
+        GDateTime *dt;
 
        tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (provider);
 
@@ -266,6 +275,8 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
        g_object_ref (tracker);
        tracker->details->query_pending = TRUE;
 
+        g_object_notify (G_OBJECT (provider), "running");
+
        if (tracker->details->connection == NULL) {
                g_idle_add (search_finished_idle, provider);
                return;
@@ -283,10 +294,11 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
         location = nautilus_query_get_location (tracker->details->query);
        location_uri = location ? g_file_get_uri (location) : NULL;
        mimetypes = nautilus_query_get_mime_types (tracker->details->query);
+        dt = nautilus_query_get_date (tracker->details->query);
 
        mime_count = g_list_length (mimetypes);
 
-       sparql = g_string_new ("SELECT DISTINCT nie:url(?urn) fts:rank(?urn) 
tracker:coalesce(nfo:fileLastModified(?urn), nie:contentLastModified(?urn)) 
tracker:coalesce(nfo:fileLastAccessed(?urn), nie:contentAccessed(?urn)) "
+       sparql = g_string_new ("SELECT DISTINCT nie:url(?urn) fts:rank(?urn) 
tracker:coalesce(nfo:fileLastModified(?urn), nie:contentLastModified(?urn)) AS ?mtime 
tracker:coalesce(nfo:fileLastAccessed(?urn), nie:contentAccessed(?urn)) AS ?atime \n"
                               "WHERE {"
                               "  ?urn a nfo:FileDataObject ;"
                               "  tracker:available true ; ");
@@ -305,6 +317,24 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
 
        g_string_append_printf (sparql, "fn:contains(fn:lower-case(nfo:fileName(?urn)), '%s')", search_text);
 
+        if (dt != NULL) {
+                NautilusQuerySearchType type;
+                gchar *dt_format;
+
+                type = nautilus_query_get_search_type (tracker->details->query);
+                dt_format = g_date_time_format (dt, "%Y-%m-%dT%H:%M:%S");
+
+                g_string_append (sparql, " && ");
+
+                if (type == NAUTILUS_QUERY_SEARCH_TYPE_LAST_ACCESS) {
+                        g_string_append_printf (sparql, "?atime <= \"%s\"^^xsd:dateTime", dt_format);
+                } else {
+                        g_string_append_printf (sparql, "?mtime <= \"%s\"^^xsd:dateTime", dt_format);
+                }
+
+                g_free (dt_format);
+        }
+
        if (mime_count > 0) {
                g_string_append (sparql, " && (");
 
@@ -316,7 +346,7 @@ nautilus_search_engine_tracker_start (NautilusSearchProvider *provider)
                        g_string_append_printf (sparql, "fn:contains(?mime, '%s')",
                                                (gchar *) l->data);
                }
-               g_string_append (sparql, ")");
+               g_string_append (sparql, ")\n");
        }
 
        g_string_append (sparql, ")} ORDER BY DESC (fts:rank(?urn))");
@@ -347,6 +377,8 @@ nautilus_search_engine_tracker_stop (NautilusSearchProvider *provider)
                g_cancellable_cancel (tracker->details->cancellable);
                g_clear_object (&tracker->details->cancellable);
                tracker->details->query_pending = FALSE;
+
+               g_object_notify (G_OBJECT (provider), "running");
        }
 }
 
@@ -363,12 +395,41 @@ nautilus_search_engine_tracker_set_query (NautilusSearchProvider *provider,
        tracker->details->query = query;
 }
 
+static gboolean
+nautilus_search_engine_tracker_is_running (NautilusSearchProvider *provider)
+{
+        NautilusSearchEngineTracker *tracker;
+
+        tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (provider);
+
+        return tracker->details->query_pending;
+}
+
 static void
-nautilus_search_provider_init (NautilusSearchProviderIface *iface)
+nautilus_search_provider_init (NautilusSearchProviderInterface *iface)
 {
        iface->set_query = nautilus_search_engine_tracker_set_query;
        iface->start = nautilus_search_engine_tracker_start;
        iface->stop = nautilus_search_engine_tracker_stop;
+        iface->is_running = nautilus_search_engine_tracker_is_running;
+}
+
+static void
+nautilus_search_engine_tracker_get_property (GObject    *object,
+                                             guint       prop_id,
+                                             GValue     *value,
+                                             GParamSpec *pspec)
+{
+        NautilusSearchProvider *self = NAUTILUS_SEARCH_PROVIDER (object);
+
+        switch (prop_id) {
+        case PROP_RUNNING:
+                g_value_set_boolean (value, nautilus_search_engine_tracker_is_running (self));
+                break;
+
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
 }
 
 static void
@@ -378,6 +439,14 @@ nautilus_search_engine_tracker_class_init (NautilusSearchEngineTrackerClass *cla
 
        gobject_class = G_OBJECT_CLASS (class);
        gobject_class->finalize = finalize;
+        gobject_class->get_property = nautilus_search_engine_tracker_get_property;
+
+        /**
+         * NautilusSearchEngine::running:
+         *
+         * Whether the search engine is running a search.
+         */
+        g_object_class_override_property (gobject_class, PROP_RUNNING, "running");
 
        g_type_class_add_private (class, sizeof (NautilusSearchEngineTrackerDetails));
 }
diff --git a/libnautilus-private/nautilus-search-engine.c b/libnautilus-private/nautilus-search-engine.c
index 0ae369a..1526b86 100644
--- a/libnautilus-private/nautilus-search-engine.c
+++ b/libnautilus-private/nautilus-search-engine.c
@@ -51,7 +51,15 @@ struct NautilusSearchEngineDetails
        gboolean restart;
 };
 
-static void nautilus_search_provider_init (NautilusSearchProviderIface  *iface);
+enum {
+        PROP_0,
+        PROP_RUNNING,
+        LAST_PROP
+};
+
+static void nautilus_search_provider_init (NautilusSearchProviderInterface *iface);
+
+static gboolean nautilus_search_engine_is_running (NautilusSearchProvider *provider);
 
 G_DEFINE_TYPE_WITH_CODE (NautilusSearchEngine,
                         nautilus_search_engine,
@@ -118,6 +126,8 @@ nautilus_search_engine_start (NautilusSearchProvider *provider)
 
        engine->details->running = TRUE;
 
+        g_object_notify (G_OBJECT (provider), "running");
+
        if (num_finished < engine->details->providers_running) {
                engine->details->restart = TRUE;
        } else {
@@ -140,6 +150,8 @@ nautilus_search_engine_stop (NautilusSearchProvider *provider)
 
        engine->details->running = FALSE;
        engine->details->restart = FALSE;
+
+        g_object_notify (G_OBJECT (provider), "running");
 }
 
 static void
@@ -199,6 +211,8 @@ check_providers_status (NautilusSearchEngine *engine)
        }
 
        engine->details->running = FALSE;
+        g_object_notify (G_OBJECT (engine), "running");
+
        g_hash_table_remove_all (engine->details->uris);
 
        if (engine->details->restart) {
@@ -247,12 +261,23 @@ connect_provider_signals (NautilusSearchEngine   *engine,
                          engine);
 }
 
+static gboolean
+nautilus_search_engine_is_running (NautilusSearchProvider *provider)
+{
+        NautilusSearchEngine *engine;
+
+        engine = NAUTILUS_SEARCH_ENGINE (provider);
+
+        return engine->details->running;
+}
+
 static void
-nautilus_search_provider_init (NautilusSearchProviderIface *iface)
+nautilus_search_provider_init (NautilusSearchProviderInterface *iface)
 {
        iface->set_query = nautilus_search_engine_set_query;
        iface->start = nautilus_search_engine_start;
        iface->stop = nautilus_search_engine_stop;
+        iface->is_running = nautilus_search_engine_is_running;
 }
 
 static void
@@ -272,6 +297,24 @@ nautilus_search_engine_finalize (GObject *object)
 }
 
 static void
+nautilus_search_engine_get_property (GObject    *object,
+                                     guint       prop_id,
+                                     GValue     *value,
+                                     GParamSpec *pspec)
+{
+        NautilusSearchProvider *self = NAUTILUS_SEARCH_PROVIDER (object);
+
+        switch (prop_id) {
+        case PROP_RUNNING:
+                g_value_set_boolean (value, nautilus_search_engine_is_running (self));
+                break;
+
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
+}
+
+static void
 nautilus_search_engine_class_init (NautilusSearchEngineClass *class)
 {
        GObjectClass *object_class;
@@ -279,6 +322,14 @@ nautilus_search_engine_class_init (NautilusSearchEngineClass *class)
        object_class = (GObjectClass *) class;
 
        object_class->finalize = nautilus_search_engine_finalize;
+        object_class->get_property = nautilus_search_engine_get_property;
+
+        /**
+         * NautilusSearchEngine::running:
+         *
+         * Whether the search engine is running a search.
+         */
+        g_object_class_override_property (object_class, PROP_RUNNING, "running");
 
        g_type_class_add_private (class, sizeof (NautilusSearchEngineDetails));
 }
diff --git a/libnautilus-private/nautilus-search-provider.c b/libnautilus-private/nautilus-search-provider.c
index 10aca20..67404fb 100644
--- a/libnautilus-private/nautilus-search-provider.c
+++ b/libnautilus-private/nautilus-search-provider.c
@@ -32,50 +32,28 @@ enum {
 
 static guint signals[LAST_SIGNAL];
 
-static void nautilus_search_provider_base_init (gpointer g_iface);
-
-GType
-nautilus_search_provider_get_type (void)
-{
-       static GType search_provider_type = 0;
-
-       if (!search_provider_type) {
-               const GTypeInfo search_provider_info = {
-                       sizeof (NautilusSearchProviderIface), /* class_size */
-                       nautilus_search_provider_base_init,   /* base_init */
-                       NULL,           /* base_finalize */
-                       NULL,
-                       NULL,           /* class_finalize */
-                       NULL,           /* class_data */
-                       0,
-                       0,              /* n_preallocs */
-                       NULL
-               };
-
-               search_provider_type = g_type_register_static (G_TYPE_INTERFACE,
-                                                              "NautilusSearchProvider",
-                                                              &search_provider_info,
-                                                              0);
-
-               g_type_interface_add_prerequisite (search_provider_type, G_TYPE_OBJECT);
-       }
-
-       return search_provider_type;
-}
+G_DEFINE_INTERFACE (NautilusSearchProvider, nautilus_search_provider, G_TYPE_OBJECT)
 
 static void
-nautilus_search_provider_base_init (gpointer g_iface)
+nautilus_search_provider_default_init (NautilusSearchProviderInterface *iface)
 {
-       static gboolean initialized = FALSE;
 
-       if (initialized) {
-               return;
-       }
+        /**
+         * NautilusSearchProvider::running:
+         *
+         * Whether the provider is running a search.
+         */
+        g_object_interface_install_property (iface,
+                                             g_param_spec_boolean ("running",
+                                                                   "Whether the provider is running",
+                                                                   "Whether the provider is running a 
search",
+                                                                   FALSE,
+                                                                   G_PARAM_READABLE));
 
        signals[HITS_ADDED] = g_signal_new ("hits-added",
                                            NAUTILUS_TYPE_SEARCH_PROVIDER,
                                            G_SIGNAL_RUN_LAST,
-                                           G_STRUCT_OFFSET (NautilusSearchProviderIface, hits_added),
+                                           G_STRUCT_OFFSET (NautilusSearchProviderInterface, hits_added),
                                            NULL, NULL,
                                            g_cclosure_marshal_VOID__POINTER,
                                            G_TYPE_NONE, 1,
@@ -84,7 +62,7 @@ nautilus_search_provider_base_init (gpointer g_iface)
        signals[FINISHED] = g_signal_new ("finished",
                                          NAUTILUS_TYPE_SEARCH_PROVIDER,
                                          G_SIGNAL_RUN_LAST,
-                                         G_STRUCT_OFFSET (NautilusSearchProviderIface, finished),
+                                         G_STRUCT_OFFSET (NautilusSearchProviderInterface, finished),
                                          NULL, NULL,
                                          g_cclosure_marshal_VOID__ENUM,
                                          G_TYPE_NONE, 1,
@@ -93,13 +71,11 @@ nautilus_search_provider_base_init (gpointer g_iface)
        signals[ERROR] = g_signal_new ("error",
                                       NAUTILUS_TYPE_SEARCH_PROVIDER,
                                       G_SIGNAL_RUN_LAST,
-                                      G_STRUCT_OFFSET (NautilusSearchProviderIface, error),
+                                      G_STRUCT_OFFSET (NautilusSearchProviderInterface, error),
                                       NULL, NULL,
                                       g_cclosure_marshal_VOID__STRING,
                                       G_TYPE_NONE, 1,
                                       G_TYPE_STRING);
-
-       initialized = TRUE;
 }
 
 void
@@ -156,3 +132,12 @@ nautilus_search_provider_error (NautilusSearchProvider *provider, const char *er
                   G_OBJECT_TYPE_NAME (provider), error_message);
        g_signal_emit (provider, signals[ERROR], 0, error_message);
 }
+
+gboolean
+nautilus_search_provider_is_running (NautilusSearchProvider *provider)
+{
+        g_return_val_if_fail (NAUTILUS_IS_SEARCH_PROVIDER (provider), FALSE);
+        g_return_val_if_fail (NAUTILUS_SEARCH_PROVIDER_GET_IFACE (provider)->is_running, FALSE);
+
+        return NAUTILUS_SEARCH_PROVIDER_GET_IFACE (provider)->is_running (provider);
+}
diff --git a/libnautilus-private/nautilus-search-provider.h b/libnautilus-private/nautilus-search-provider.h
index b3be651..96b4cf4 100644
--- a/libnautilus-private/nautilus-search-provider.h
+++ b/libnautilus-private/nautilus-search-provider.h
@@ -29,15 +29,12 @@ typedef enum {
   NAUTILUS_SEARCH_PROVIDER_STATUS_RESTARTING
 } NautilusSearchProviderStatus;
 
-#define NAUTILUS_TYPE_SEARCH_PROVIDER           (nautilus_search_provider_get_type ())
-#define NAUTILUS_SEARCH_PROVIDER(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
NAUTILUS_TYPE_SEARCH_PROVIDER, NautilusSearchProvider))
-#define NAUTILUS_IS_SEARCH_PROVIDER(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
NAUTILUS_TYPE_SEARCH_PROVIDER))
-#define NAUTILUS_SEARCH_PROVIDER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), 
NAUTILUS_TYPE_SEARCH_PROVIDER, NautilusSearchProviderIface))
 
-typedef struct _NautilusSearchProvider       NautilusSearchProvider;
-typedef struct _NautilusSearchProviderIface  NautilusSearchProviderIface;
+#define NAUTILUS_TYPE_SEARCH_PROVIDER (nautilus_search_provider_get_type ())
 
-struct _NautilusSearchProviderIface {
+G_DECLARE_INTERFACE (NautilusSearchProvider, nautilus_search_provider, NAUTILUS, SEARCH_PROVIDER, GObject)
+
+struct _NautilusSearchProviderInterface {
         GTypeInterface g_iface;
 
         /* VTable */
@@ -75,6 +72,7 @@ struct _NautilusSearchProviderIface {
         void (*finished) (NautilusSearchProvider       *provider,
                           NautilusSearchProviderStatus  status);
         void (*error) (NautilusSearchProvider *provider, const char *error_message);
+        gboolean (*is_running) (NautilusSearchProvider *provider);
 };
 
 GType          nautilus_search_provider_get_type        (void) G_GNUC_CONST;
@@ -92,6 +90,8 @@ void           nautilus_search_provider_finished        (NautilusSearchProvider
 void           nautilus_search_provider_error           (NautilusSearchProvider *provider,
                                                          const char *error_message);
 
+gboolean       nautilus_search_provider_is_running      (NautilusSearchProvider *provider);
+
 G_END_DECLS
 
 #endif


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