diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2007-05-02 22:51:43 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@src.gnome.org> | 2007-05-02 22:51:43 +0000 |
commit | d3aeccf774fd13c4efdbdb873bb2258e1b94f853 (patch) | |
tree | 4ce2f324a2518663451f7e82cb0d9da97b7ee5b2 /gtk/gtksearchenginetracker.c | |
parent | e82e337ee915d0cb1f07640be53a76854684b181 (diff) | |
download | gtk+-d3aeccf774fd13c4efdbdb873bb2258e1b94f853.tar.gz |
Add search file support in the GtkFileChooser. Original patch by Federico
2007-05-02 Emmanuele Bassi <ebassi@gnome.org>
Add search file support in the GtkFileChooser. Original patch
by Federico Mena Quintero; patch updated by Matthias Clasen.
See bug #344785.
* gtk/gtksearchengine.[ch]: Private search engine abstraction
object.
* gtk/gtksearchenginebeagle.[ch]: Private search engine
implementation using libbeagle (via g_module_open()).
* gtk/gtksearchenginesimple.[ch]: Private search engine
implementation using file tree walking.
* gtk/gtksearchenginetracker.[ch]: Private earch engine
implementation using libtracker (via g_module_open()).
* gtk/gtkquery.[ch]: Private query object for the search
engines.
* gtk/gtkfilechooserprivate.h:
* gtk/gtkfilechooserdefault.c: Use the GtkSearchEngine to
query a search engine backend using GtkQuery; create a new
operating mode, OPERATION_MODE_SEARCH, and call the common
operating mode OPERATION_MODE_BROWSE; add support for virtual
shortcuts inside the shortcuts model and create a new "Search"
virtual shortcut.
* gtk/Makefile.am: Update the build with the new files
svn path=/trunk/; revision=17783
Diffstat (limited to 'gtk/gtksearchenginetracker.c')
-rw-r--r-- | gtk/gtksearchenginetracker.c | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/gtk/gtksearchenginetracker.c b/gtk/gtksearchenginetracker.c new file mode 100644 index 0000000000..7d63461369 --- /dev/null +++ b/gtk/gtksearchenginetracker.c @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2005 Mr Jamie McCracken + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * + * Author: Jamie McCracken <jamiemcc@gnome.org> + * + * Based on nautilus-search-engine-tracker.c + */ + +#include <config.h> +#include <gmodule.h> +#include "gtksearchenginetracker.h" +#if 0 +#include <tracker.h> +#endif + +typedef struct _TrackerClient TrackerClient; + +typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data); + +static TrackerClient * (*tracker_connect) (gboolean enable_warnings) = NULL; +static void (*tracker_disconnect) (TrackerClient *client) = NULL; +static void (*tracker_cancel_last_call) (TrackerClient *client) = NULL; + +static void (*tracker_search_metadata_by_text_async) (TrackerClient *client, + const char *query, + TrackerArrayReply callback, + gpointer user_data) = NULL; +static void (*tracker_search_metadata_by_text_and_mime_async) (TrackerClient *client, + const char *query, + const char **mimes, + TrackerArrayReply callback, + gpointer user_data) = NULL; +static void (*tracker_search_metadata_by_text_and_location_async) (TrackerClient *client, + const char *query, + const char *location, + TrackerArrayReply callback, + gpointer user_data) = NULL; +static void (*tracker_search_metadata_by_text_and_mime_and_location_async) (TrackerClient *client, + const char *query, + const char **mimes, + const char *location, + TrackerArrayReply callback, + gpointer user_data) = NULL; + +static struct TrackerDlMapping +{ + const char *fn_name; + gpointer *fn_ptr_ref; +} tracker_dl_mapping[] = +{ +#define MAP(a) { #a, (gpointer *)&a } + MAP (tracker_connect), + MAP (tracker_disconnect), + MAP (tracker_cancel_last_call), + MAP (tracker_search_metadata_by_text_async), + MAP (tracker_search_metadata_by_text_and_mime_async), + MAP (tracker_search_metadata_by_text_and_location_async), + MAP (tracker_search_metadata_by_text_and_mime_and_location_async) +#undef MAP +}; + +static void +open_libtracker (void) +{ + static gboolean done = FALSE; + + if (!done) + { + int i; + GModule *tracker; + + done = TRUE; + + tracker = g_module_open ("libtracker.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (!tracker) + return; + + for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++) + { + if (!g_module_symbol (tracker, tracker_dl_mapping[i].fn_name, + tracker_dl_mapping[i].fn_ptr_ref)) + { + g_warning ("Missing symbol '%s' in libtracker\n", + tracker_dl_mapping[i].fn_name); + g_module_close (tracker); + + for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++) + tracker_dl_mapping[i].fn_ptr_ref = NULL; + + return; + } + } + } +} + +struct _GtkSearchEngineTrackerPrivate +{ + GtkQuery *query; + TrackerClient *client; + gboolean query_pending; +}; + +G_DEFINE_TYPE (GtkSearchEngineTracker, _gtk_search_engine_tracker, GTK_TYPE_SEARCH_ENGINE); + + +static void +finalize (GObject *object) +{ + GtkSearchEngineTracker *tracker; + + tracker = GTK_SEARCH_ENGINE_TRACKER (object); + + if (tracker->priv->query) + { + g_object_unref (tracker->priv->query); + tracker->priv->query = NULL; + } + + tracker_disconnect (tracker->priv->client); + + G_OBJECT_CLASS (_gtk_search_engine_tracker_parent_class)->finalize (object); +} + + +static void +search_callback (gchar **results, + GError *error, + gpointer user_data) +{ + GtkSearchEngineTracker *tracker; + gchar **results_p; + GList *hit_uris; + + tracker = GTK_SEARCH_ENGINE_TRACKER (user_data); + hit_uris = NULL; + + tracker->priv->query_pending = FALSE; + + if (error) + { + _gtk_search_engine_error ( GTK_SEARCH_ENGINE (tracker), error->message); + g_error_free (error); + return; + } + + if (!results) + return; + + for (results_p = results; *results_p; results_p++) + { + gchar *uri; + + uri = g_filename_to_uri ((char *)*results_p, NULL, NULL); + if (uri) + hit_uris = g_list_prepend (hit_uris, (char *)uri); + } + + _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (tracker), hit_uris); + _gtk_search_engine_finished (GTK_SEARCH_ENGINE (tracker)); + + g_strfreev (results); + g_list_foreach (hit_uris, (GFunc)g_free, NULL); + g_list_free (hit_uris); +} + + +static void +gtk_search_engine_tracker_start (GtkSearchEngine *engine) +{ + GtkSearchEngineTracker *tracker; + GList *mimetypes, *l; + gchar *search_text, *location, *location_uri; + gchar **mimes; + gint i, mime_count; + + tracker = GTK_SEARCH_ENGINE_TRACKER (engine); + + if (tracker->priv->query_pending) + return; + + if (tracker->priv->query == NULL) + return; + + search_text = _gtk_query_get_text (tracker->priv->query); + + mimetypes = _gtk_query_get_mime_types (tracker->priv->query); + + location_uri = _gtk_query_get_location (tracker->priv->query); + + if (location_uri) + { + location = g_filename_from_uri (location_uri, NULL, NULL); + g_free (location_uri); + } + else + { + location = NULL; + } + + mime_count = g_list_length (mimetypes); + + i = 0; + + /* convert list into array */ + if (mime_count > 0) + { + mimes = g_new (gchar *, (mime_count + 1)); + + for (l = mimetypes; l != NULL; l = l->next) + { + mimes[i] = g_strdup (l->data); + i++; + } + + mimes[mime_count] = NULL; + + if (location) + { + tracker_search_metadata_by_text_and_mime_and_location_async (tracker->priv->client, + search_text, (const char **)mimes, location, + search_callback, + tracker); + g_free (location); + } + else + { + tracker_search_metadata_by_text_and_mime_async (tracker->priv->client, + search_text, (const char**)mimes, + search_callback, + tracker); + } + + g_strfreev (mimes); + + + } + else + { + if (location) + { + tracker_search_metadata_by_text_and_location_async (tracker->priv->client, + search_text, + location, + search_callback, + tracker); + g_free (location); + } + else + { + tracker_search_metadata_by_text_async (tracker->priv->client, + search_text, + search_callback, + tracker); + } + } + + tracker->priv->query_pending = TRUE; + g_free (search_text); + g_list_foreach (mimetypes, (GFunc)g_free, NULL); + g_list_free (mimetypes); +} + +static void +gtk_search_engine_tracker_stop (GtkSearchEngine *engine) +{ + GtkSearchEngineTracker *tracker; + + tracker = GTK_SEARCH_ENGINE_TRACKER (engine); + + if (tracker->priv->query && tracker->priv->query_pending) + { + tracker_cancel_last_call (tracker->priv->client); + tracker->priv->query_pending = FALSE; + } +} + +static gboolean +gtk_search_engine_tracker_is_indexed (GtkSearchEngine *engine) +{ + return TRUE; +} + +static void +gtk_search_engine_tracker_set_query (GtkSearchEngine *engine, + GtkQuery *query) +{ + GtkSearchEngineTracker *tracker; + + tracker = GTK_SEARCH_ENGINE_TRACKER (engine); + + if (query) + g_object_ref (query); + + if (tracker->priv->query) + g_object_unref (tracker->priv->query); + + tracker->priv->query = query; +} + +static void +_gtk_search_engine_tracker_class_init (GtkSearchEngineTrackerClass *class) +{ + GObjectClass *gobject_class; + GtkSearchEngineClass *engine_class; + + gobject_class = G_OBJECT_CLASS (class); + gobject_class->finalize = finalize; + + engine_class = GTK_SEARCH_ENGINE_CLASS (class); + engine_class->set_query = gtk_search_engine_tracker_set_query; + engine_class->start = gtk_search_engine_tracker_start; + engine_class->stop = gtk_search_engine_tracker_stop; + engine_class->is_indexed = gtk_search_engine_tracker_is_indexed; + + g_type_class_add_private (gobject_class, sizeof (GtkSearchEngineTrackerPrivate)); +} + +static void +_gtk_search_engine_tracker_init (GtkSearchEngineTracker *engine) +{ + engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTrackerPrivate); +} + + +GtkSearchEngine * +_gtk_search_engine_tracker_new (void) +{ + GtkSearchEngineTracker *engine; + TrackerClient *tracker_client; + + open_libtracker (); + + if (!tracker_connect) + return NULL; + + tracker_client = tracker_connect (FALSE); + + if (!tracker_client) + return NULL; + + engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_TRACKER, NULL); + + engine->priv->client = tracker_client; + + engine->priv->query_pending = FALSE; + + return GTK_SEARCH_ENGINE (engine); +} |