[nautilus] Pass the current directory model down to the search engine



commit 64f8be2d739cf6d8a65f1945d467af215176ee60
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Thu Sep 6 00:51:30 2012 -0400

    Pass the current directory model down to the search engine
    
    Before the view removes the directory monitor, causing caches to be
    dropped; the search directory installs its own monitor before passing it
    down to the engine.

 libnautilus-private/nautilus-search-directory.c    |  123 ++++++++++++++++++--
 libnautilus-private/nautilus-search-directory.h    |    5 +
 libnautilus-private/nautilus-search-engine-model.c |   55 +++++----
 libnautilus-private/nautilus-search-engine-model.h |    5 +-
 libnautilus-private/nautilus-search-engine.c       |    8 ++
 libnautilus-private/nautilus-search-engine.h       |    9 +-
 src/nautilus-view.c                                |    8 +-
 7 files changed, 176 insertions(+), 37 deletions(-)
---
diff --git a/libnautilus-private/nautilus-search-directory.c b/libnautilus-private/nautilus-search-directory.c
index a5733b4..30da376 100644
--- a/libnautilus-private/nautilus-search-directory.c
+++ b/libnautilus-private/nautilus-search-directory.c
@@ -30,6 +30,8 @@
 #include "nautilus-file-utilities.h"
 #include "nautilus-search-provider.h"
 #include "nautilus-search-engine.h"
+#include "nautilus-search-engine-model.h"
+
 #include <eel/eel-glib-extensions.h>
 #include <gtk/gtk.h>
 #include <gio/gio.h>
@@ -52,6 +54,8 @@ struct NautilusSearchDirectoryDetails {
 	GList *monitor_list;
 	GList *callback_list;
 	GList *pending_callback_list;
+
+	NautilusDirectory *base_model;
 };
 
 typedef struct {
@@ -73,9 +77,17 @@ typedef struct {
 	GHashTable *non_ready_hash;
 } SearchCallback;
 
+enum {
+	PROP_0,
+	PROP_BASE_MODEL,
+	NUM_PROPERTIES
+};
+
 G_DEFINE_TYPE (NautilusSearchDirectory, nautilus_search_directory,
 	       NAUTILUS_TYPE_DIRECTORY);
 
+static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
+
 static void search_engine_hits_added (NautilusSearchEngine *engine, GList *hits, NautilusSearchDirectory *search);
 static void search_engine_hits_subtracted (NautilusSearchEngine *engine, GList *hits, NautilusSearchDirectory *search);
 static void search_engine_finished (NautilusSearchEngine *engine, NautilusSearchDirectory *search);
@@ -136,11 +148,17 @@ start_or_stop_search_engine (NautilusSearchDirectory *search, gboolean adding)
 	    search->details->pending_callback_list) &&
 	    search->details->query &&
 	    !search->details->search_running) {
+		NautilusSearchEngineModel *model_provider;
+
 		/* We need to start the search engine */
 		search->details->search_running = TRUE;
 		search->details->search_finished = FALSE;
 		ensure_search_engine (search);
-		nautilus_search_provider_set_query (NAUTILUS_SEARCH_PROVIDER (search->details->engine), search->details->query);
+		nautilus_search_provider_set_query (NAUTILUS_SEARCH_PROVIDER (search->details->engine),
+						    search->details->query);
+
+		model_provider = nautilus_search_engine_get_model_provider (search->details->engine);
+		nautilus_search_engine_model_set_model (model_provider, search->details->base_model);
 
 		reset_file_list (search);
 
@@ -656,13 +674,61 @@ search_is_editable (NautilusDirectory *directory)
 }
 
 static void
+search_set_property (GObject *object,
+		     guint property_id,
+		     const GValue *value,
+		     GParamSpec *pspec)
+{
+	NautilusSearchDirectory *search = NAUTILUS_SEARCH_DIRECTORY (object);
+
+	switch (property_id) {
+	case PROP_BASE_MODEL:
+		nautilus_search_directory_set_base_model (search, g_value_get_object (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+search_get_property (GObject *object,
+		     guint property_id,
+		     GValue *value,
+		     GParamSpec *pspec)
+{
+	NautilusSearchDirectory *search = NAUTILUS_SEARCH_DIRECTORY (object);
+
+	switch (property_id) {
+	case PROP_BASE_MODEL:
+		g_value_set_object (value, nautilus_search_directory_get_base_model (search));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+clear_base_model (NautilusSearchDirectory *search)
+{
+	if (search->details->base_model != NULL) {
+		nautilus_directory_file_monitor_remove (search->details->base_model,
+							&search->details->base_model);
+		g_clear_object (&search->details->base_model);
+	}
+}
+
+static void
 search_dispose (GObject *object)
 {
 	NautilusSearchDirectory *search;
 	GList *list;
 
 	search = NAUTILUS_SEARCH_DIRECTORY (object);
-	
+
+	clear_base_model (search);
+
 	/* Remove search monitors */
 	if (search->details->monitor_list) {
 		for (list = search->details->monitor_list; list != NULL; list = list->next) {
@@ -713,10 +779,7 @@ search_finalize (GObject *object)
 	NautilusSearchDirectory *search;
 
 	search = NAUTILUS_SEARCH_DIRECTORY (object);
-
 	g_free (search->details->saved_search_uri);
-	
-	g_free (search->details);
 
 	G_OBJECT_CLASS (nautilus_search_directory_parent_class)->finalize (object);
 }
@@ -724,18 +787,20 @@ search_finalize (GObject *object)
 static void
 nautilus_search_directory_init (NautilusSearchDirectory *search)
 {
-	search->details = g_new0 (NautilusSearchDirectoryDetails, 1);
+	search->details = G_TYPE_INSTANCE_GET_PRIVATE (search, NAUTILUS_TYPE_SEARCH_DIRECTORY,
+						       NautilusSearchDirectoryDetails);
 }
 
 static void
 nautilus_search_directory_class_init (NautilusSearchDirectoryClass *class)
 {
-	NautilusDirectoryClass *directory_class;
+	NautilusDirectoryClass *directory_class = NAUTILUS_DIRECTORY_CLASS (class);
+	GObjectClass *oclass = G_OBJECT_CLASS (class);
 
-	G_OBJECT_CLASS (class)->dispose = search_dispose;
-	G_OBJECT_CLASS (class)->finalize = search_finalize;
-
-	directory_class = NAUTILUS_DIRECTORY_CLASS (class);
+	oclass->dispose = search_dispose;
+	oclass->finalize = search_finalize;
+	oclass->get_property = search_get_property;
+	oclass->set_property = search_set_property;
 
  	directory_class->are_all_files_seen = search_are_all_files_seen;
 	directory_class->contains_file = search_contains_file;
@@ -748,6 +813,42 @@ nautilus_search_directory_class_init (NautilusSearchDirectoryClass *class)
 	
 	directory_class->get_file_list = search_get_file_list;
 	directory_class->is_editable = search_is_editable;
+
+	properties[PROP_BASE_MODEL] =
+		g_param_spec_object ("base-model",
+				     "The base model",
+				     "The base directory model for this directory",
+				     NAUTILUS_TYPE_DIRECTORY,
+				     G_PARAM_READWRITE);
+
+	g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
+	g_type_class_add_private (class, sizeof (NautilusSearchDirectoryDetails));
+}
+
+void
+nautilus_search_directory_set_base_model (NautilusSearchDirectory *search,
+					  NautilusDirectory *base_model)
+{
+	if (search->details->base_model == base_model) {
+		return;
+	}
+
+	clear_base_model (search);
+	search->details->base_model = nautilus_directory_ref (base_model);
+
+	if (search->details->base_model != NULL) {
+		nautilus_directory_file_monitor_add (base_model, &search->details->base_model,
+						     TRUE, NAUTILUS_FILE_ATTRIBUTE_INFO,
+						     NULL, NULL);
+	}
+
+	g_object_notify_by_pspec (G_OBJECT (search), properties[PROP_BASE_MODEL]);
+}
+
+NautilusDirectory *
+nautilus_search_directory_get_base_model (NautilusSearchDirectory *search)
+{
+	return search->details->base_model;
 }
 
 char *
diff --git a/libnautilus-private/nautilus-search-directory.h b/libnautilus-private/nautilus-search-directory.h
index de4ebe0..9f734d1 100644
--- a/libnautilus-private/nautilus-search-directory.h
+++ b/libnautilus-private/nautilus-search-directory.h
@@ -67,4 +67,9 @@ NautilusQuery *nautilus_search_directory_get_query       (NautilusSearchDirector
 void           nautilus_search_directory_set_query       (NautilusSearchDirectory *search,
 							  NautilusQuery           *query);
 
+NautilusDirectory *
+               nautilus_search_directory_get_base_model (NautilusSearchDirectory  *search);
+void           nautilus_search_directory_set_base_model (NautilusSearchDirectory  *search,
+							 NautilusDirectory        *base_model);
+
 #endif /* NAUTILUS_SEARCH_DIRECTORY_H */
diff --git a/libnautilus-private/nautilus-search-engine-model.c b/libnautilus-private/nautilus-search-engine-model.c
index ad06396..973f7d0 100644
--- a/libnautilus-private/nautilus-search-engine-model.c
+++ b/libnautilus-private/nautilus-search-engine-model.c
@@ -38,6 +38,8 @@ struct NautilusSearchEngineModelDetails {
 
 	GList *hits;
 	NautilusDirectory *directory;
+
+	gboolean query_pending;
 };
 
 static void nautilus_search_provider_init (NautilusSearchProviderIface  *iface);
@@ -79,8 +81,7 @@ emit_finished_idle_cb (gpointer user_data)
 	}
 
 	nautilus_search_provider_finished (NAUTILUS_SEARCH_PROVIDER (model));
-
-	g_clear_object (&model->details->directory);
+	model->details->query_pending = FALSE;
 	g_object_unref (model);
 
 	return FALSE;
@@ -143,44 +144,40 @@ static void
 nautilus_search_engine_model_start (NautilusSearchProvider *provider)
 {
 	NautilusSearchEngineModel *model;
-	GFile *location;
-	NautilusDirectory *directory;
-	gchar *uri;
 
 	model = NAUTILUS_SEARCH_ENGINE_MODEL (provider);
-
-	if (model->details->query == NULL) {
-		return;
-	}
-
 	g_object_ref (model);
 
-	uri = nautilus_query_get_location (model->details->query);
-	if (uri == NULL) {
-		g_idle_add (emit_finished_idle_cb, model);
+	if (model->details->query_pending) {
 		return;
 	}
 
-	location = g_file_new_for_uri (uri);
-	directory = nautilus_directory_get_existing (location);
-	g_object_unref (location);
-	g_free (uri);
-
-	if (directory == NULL) {
+	if (model->details->query == NULL ||
+	    model->details->directory == NULL) {
 		g_idle_add (emit_finished_idle_cb, model);
 		return;
 	}
 
-	model->details->directory = directory;
+	model->details->query_pending = TRUE;
 	nautilus_directory_call_when_ready (model->details->directory,
-					    NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT,
+					    NAUTILUS_FILE_ATTRIBUTE_INFO,
 					    TRUE, model_directory_ready_cb, model);
 }
 
 static void
 nautilus_search_engine_model_stop (NautilusSearchProvider *provider)
 {
-	/* do nothing */
+	NautilusSearchEngineModel *model;
+
+	model = NAUTILUS_SEARCH_ENGINE_MODEL (provider);
+
+	if (model->details->query_pending) {
+		nautilus_directory_cancel_callback (model->details->directory,
+						    model_directory_ready_cb, model);
+		model->details->query_pending = FALSE;
+	}
+
+	g_clear_object (&model->details->directory);
 }
 
 static void
@@ -237,3 +234,17 @@ nautilus_search_engine_model_new (void)
 
 	return engine;
 }
+
+void
+nautilus_search_engine_model_set_model (NautilusSearchEngineModel *model,
+					NautilusDirectory         *directory)
+{
+	g_clear_object (&model->details->directory);
+	model->details->directory = nautilus_directory_ref (directory);
+}
+
+NautilusDirectory *
+nautilus_search_engine_model_get_model (NautilusSearchEngineModel *model)
+{
+	return model->details->directory;
+}
diff --git a/libnautilus-private/nautilus-search-engine-model.h b/libnautilus-private/nautilus-search-engine-model.h
index 1a2d0ae..1b9b3c4 100644
--- a/libnautilus-private/nautilus-search-engine-model.h
+++ b/libnautilus-private/nautilus-search-engine-model.h
@@ -24,7 +24,7 @@
 #ifndef NAUTILUS_SEARCH_ENGINE_MODEL_H
 #define NAUTILUS_SEARCH_ENGINE_MODEL_H
 
-#include <libnautilus-private/nautilus-search-engine.h>
+#include <libnautilus-private/nautilus-directory.h>
 
 #define NAUTILUS_TYPE_SEARCH_ENGINE_MODEL		(nautilus_search_engine_model_get_type ())
 #define NAUTILUS_SEARCH_ENGINE_MODEL(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_SEARCH_ENGINE_MODEL, NautilusSearchEngineModel))
@@ -47,5 +47,8 @@ typedef struct {
 GType          nautilus_search_engine_model_get_type  (void);
 
 NautilusSearchEngineModel* nautilus_search_engine_model_new       (void);
+void                       nautilus_search_engine_model_set_model (NautilusSearchEngineModel *model,
+								   NautilusDirectory         *directory);
+NautilusDirectory *        nautilus_search_engine_model_get_model (NautilusSearchEngineModel *model);
 
 #endif /* NAUTILUS_SEARCH_ENGINE_MODEL_H */
diff --git a/libnautilus-private/nautilus-search-engine.c b/libnautilus-private/nautilus-search-engine.c
index 0f1d38d..459cc0c 100644
--- a/libnautilus-private/nautilus-search-engine.c
+++ b/libnautilus-private/nautilus-search-engine.c
@@ -47,6 +47,8 @@ struct NautilusSearchEngineDetails
 #ifdef ENABLE_TRACKER
 	NautilusSearchEngineTracker *tracker;
 #endif
+	NautilusDirectory *base_model;
+
 	GHashTable *uris;
 	guint num_providers;
 	guint providers_finished;
@@ -283,3 +285,9 @@ nautilus_search_engine_new (void)
 
 	return engine;
 }
+
+NautilusSearchEngineModel *
+nautilus_search_engine_get_model_provider (NautilusSearchEngine *engine)
+{
+	return engine->details->model;
+}
diff --git a/libnautilus-private/nautilus-search-engine.h b/libnautilus-private/nautilus-search-engine.h
index 2e802d1..b9cefad 100644
--- a/libnautilus-private/nautilus-search-engine.h
+++ b/libnautilus-private/nautilus-search-engine.h
@@ -26,6 +26,9 @@
 
 #include <glib-object.h>
 
+#include <libnautilus-private/nautilus-directory.h>
+#include <libnautilus-private/nautilus-search-engine-model.h>
+
 #define NAUTILUS_TYPE_SEARCH_ENGINE		(nautilus_search_engine_get_type ())
 #define NAUTILUS_SEARCH_ENGINE(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_SEARCH_ENGINE, NautilusSearchEngine))
 #define NAUTILUS_SEARCH_ENGINE_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_SEARCH_ENGINE, NautilusSearchEngineClass))
@@ -44,8 +47,10 @@ typedef struct {
 	GObjectClass parent_class;
 } NautilusSearchEngineClass;
 
-GType          nautilus_search_engine_get_type  (void);
+GType                 nautilus_search_engine_get_type           (void);
 
-NautilusSearchEngine* nautilus_search_engine_new       (void);
+NautilusSearchEngine *nautilus_search_engine_new                (void);
+NautilusSearchEngineModel *
+                      nautilus_search_engine_get_model_provider (NautilusSearchEngine *engine);
 
 #endif /* NAUTILUS_SEARCH_ENGINE_H */
diff --git a/src/nautilus-view.c b/src/nautilus-view.c
index 13b289f..06637aa 100644
--- a/src/nautilus-view.c
+++ b/src/nautilus-view.c
@@ -9125,9 +9125,15 @@ load_directory (NautilusView *view,
 						   view->details->subdirectory_list->data);
 	}
 
+	old_directory = view->details->model;
+
+	if (NAUTILUS_IS_SEARCH_DIRECTORY (directory) &&
+	    !NAUTILUS_IS_SEARCH_DIRECTORY (old_directory)) {
+		nautilus_search_directory_set_base_model (NAUTILUS_SEARCH_DIRECTORY (directory), old_directory);
+	}
+
 	disconnect_model_handlers (view);
 
-	old_directory = view->details->model;
 	nautilus_directory_ref (directory);
 	view->details->model = directory;
 	nautilus_directory_unref (old_directory);



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