[brasero] Add tracker as a backend for search



commit 604fb12f01b4351eacb49b6c3673c1a4faab34bb
Author: Rouquier Philippe <bonfire-app wanadoo fr>
Date:   Sun Nov 15 15:45:44 2009 +0100

    Add tracker as a backend for search

 configure.in                 |   23 ++-
 src/Makefile.am              |   17 ++-
 src/brasero-search-beagle.c  |   61 +------
 src/brasero-search-engine.c  |   77 ++------
 src/brasero-search-engine.h  |   50 ++----
 src/brasero-search-tracker.c |  418 ++++++++++++++++++++++++++++++++++++++++++
 src/brasero-search-tracker.h |   51 +++++
 src/brasero-search.c         |   71 ++++++--
 8 files changed, 602 insertions(+), 166 deletions(-)
---
diff --git a/configure.in b/configure.in
index f2c6646..e0e93f6 100644
--- a/configure.in
+++ b/configure.in
@@ -344,6 +344,7 @@ dnl AM_CONDITIONAL(HAVE_LIBNOTIFY, test x"$build_libnotify" = "xyes")
 
 dnl ****************check for search (optional)**************
 BEAGLE_REQUIRED=0.3.0
+TRACKER_REQUIRED=0.7.0
 
 AC_ARG_ENABLE(search,
 			AS_HELP_STRING([--enable-search],[Build search pane (if a search backend is available) [[default=yes]]]),
@@ -351,18 +352,36 @@ AC_ARG_ENABLE(search,
 			[enable_search="yes"])
 
 if test x"$enable_search" = "xyes"; then
-	PKG_CHECK_MODULES(BRASERO_SEARCH, libbeagle-1.0 >= $BEAGLE_REQUIRED, build_search=yes, build_search=no)
+	PKG_CHECK_MODULES(BRASERO_SEARCH, tracker-client-0.7 >= $TRACKER_REQUIRED, build_search=yes, build_search=no)
 	if test x"$build_search" = "xyes"; then
 		AC_DEFINE(BUILD_SEARCH, 1, [define if you  want to use search pane])
-	
+		AC_DEFINE(BUILD_TRACKER, 1, [define if you  want to use search pane])
+
 		AC_SUBST(BRASERO_SEARCH_CFLAGS)
 		AC_SUBST(BRASERO_SEARCH_LIBS)
+
+		build_beagle="no"
+		build_tracker="yes"
+	else 
+		PKG_CHECK_MODULES(BRASERO_SEARCH, libbeagle-1.0 >= $BEAGLE_REQUIRED, build_search=yes, build_search=no)
+		if test x"$build_search" = "xyes"; then
+			AC_DEFINE(BUILD_SEARCH, 1, [define if you  want to use search pane])
+			AC_DEFINE(BUILD_BEAGLE, 1, [define if you  want to use search pane])
+
+			AC_SUBST(BRASERO_SEARCH_CFLAGS)
+			AC_SUBST(BRASERO_SEARCH_LIBS)
+
+			build_beagle="yes"
+			build_tracker="no"
+		fi
 	fi
 else
 	build_search="no"
 fi
 
 AM_CONDITIONAL(BUILD_SEARCH, test x"$build_search" = "xyes")
+AM_CONDITIONAL(BUILD_BEAGLE, test x"$build_beagle" = "xyes")
+AM_CONDITIONAL(BUILD_TRACKER, test x"$build_tracker" = "xyes")
 
 dnl ****************check for playlist (optional)**************
 TOTEM_REQUIRED=2.22.0
diff --git a/src/Makefile.am b/src/Makefile.am
index b2a9f37..f373062 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -128,16 +128,27 @@ brasero_SOURCES += \
 
 endif
 
+if BUILD_TRACKER
+brasero_SOURCES += \
+		   brasero-search-tracker.h	\
+		   brasero-search-tracker.c
+endif
+
+if BUILD_BEAGLE
+brasero_SOURCES += 				\
+		   brasero-search-beagle.h	\
+		   brasero-search-beagle.c
+endif
+
 if BUILD_SEARCH
+
 brasero_SOURCES += \
 		   brasero-mime-filter.c         \
 		   brasero-mime-filter.h         \
 		   brasero-search-entry.c         \
 		   brasero-search-entry.h         \
 		   brasero-search.h		\
-		   brasero-search.c		\
-		   brasero-search-beagle.h	\
-		   brasero-search-beagle.c
+		   brasero-search.c
 endif
 
 brasero_LDADD =						\
diff --git a/src/brasero-search-beagle.c b/src/brasero-search-beagle.c
index 40d3f43..71bbc5d 100644
--- a/src/brasero-search-beagle.c
+++ b/src/brasero-search-beagle.c
@@ -44,7 +44,7 @@ struct _BraseroSearchBeaglePrivate
 	BeagleClient *client;
 	BeagleQuery *query;
 
-	GSList * hits;
+	GSList *hits;
 };
 
 #define BRASERO_SEARCH_BEAGLE_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_SEARCH_BEAGLE, BraseroSearchBeaglePrivate))
@@ -86,31 +86,6 @@ brasero_search_beagle_uri_from_hit (BraseroSearchEngine *engine,
 	return beagle_hit_get_uri (BEAGLE_HIT (hit));
 }
 
-static gchar *
-brasero_search_beagle_name_from_hit (BraseroSearchEngine *engine,
-                                     gpointer hit)
-{
-	gchar *name;
-	const gchar *uri;
-	gchar *unescaped_uri;
-
-	uri = beagle_hit_get_uri (BEAGLE_HIT (hit));
-
-	/* beagle return badly formed uri not
-	 * encoded in UTF-8 locale charset so we
-	 * check them just in case */
-	unescaped_uri = g_uri_unescape_string (uri, NULL);
-	if (!g_utf8_validate (unescaped_uri, -1, NULL)) {
-		g_free (unescaped_uri);
-		return NULL;
-	}
-
-	name = g_path_get_basename (unescaped_uri);
-	g_free (unescaped_uri);
-
-	return name;
-}
-
 static const gchar *
 brasero_search_beagle_mime_from_hit (BraseroSearchEngine *engine,
                                      gpointer hit)
@@ -118,19 +93,6 @@ brasero_search_beagle_mime_from_hit (BraseroSearchEngine *engine,
 	return beagle_hit_get_mime_type (BEAGLE_HIT (hit));
 }
 
-static const gchar *
-brasero_search_beagle_description_from_hit (BraseroSearchEngine *engine,
-                                            gpointer hit)
-{
-	const gchar *mime;
-
-	mime = beagle_hit_get_mime_type (BEAGLE_HIT (hit));
-	if (!mime)
-		return NULL;
-
-	return g_content_type_get_description (mime);
-}
-
 static int
 brasero_search_beagle_score_from_hit (BraseroSearchEngine *engine,
                                       gpointer hit)
@@ -138,22 +100,6 @@ brasero_search_beagle_score_from_hit (BraseroSearchEngine *engine,
 	return (int) (beagle_hit_get_score (BEAGLE_HIT (hit)) * 100);
 }
 
-static GIcon *
-brasero_search_beagle_icon_from_hit (BraseroSearchEngine *engine,
-                                     gpointer hit)
-{
-	const gchar *mime;
-
-	mime = beagle_hit_get_mime_type (BEAGLE_HIT (hit));
-	if (!mime)
-		return NULL;
-
-	if (!strcmp (mime, "inode/directory"))
-		mime = "x-directory/normal";
-
-	return g_content_type_get_icon (mime);
-}
-
 static gboolean
 brasero_search_beagle_add_hit_to_tree (BraseroSearchEngine *search,
                                        GtkTreeModel *model,
@@ -326,7 +272,7 @@ brasero_search_beagle_clean (BraseroSearchBeagle *beagle)
 
 static gboolean
 brasero_search_beagle_query_new (BraseroSearchEngine *search,
-                                  const gchar *keywords)
+				 const gchar *keywords)
 {
 	BraseroSearchBeaglePrivate *priv;
 	BeagleQueryPartHuman *text;
@@ -459,11 +405,8 @@ brasero_search_beagle_init_engine (BraseroSearchEngineIface *iface)
 {
 	iface->is_available = brasero_search_beagle_is_available;
 	iface->uri_from_hit = brasero_search_beagle_uri_from_hit;
-	iface->name_from_hit = brasero_search_beagle_name_from_hit;
-	iface->icon_from_hit = brasero_search_beagle_icon_from_hit;
 	iface->score_from_hit = brasero_search_beagle_score_from_hit;
 	iface->mime_from_hit = brasero_search_beagle_mime_from_hit;
-	iface->description_from_hit = brasero_search_beagle_description_from_hit;
 	iface->query_new = brasero_search_beagle_query_new;
 	iface->query_set_scope = brasero_search_beagle_query_set_scope;
 	iface->query_set_mime = brasero_search_beagle_set_query_mime;
diff --git a/src/brasero-search-engine.c b/src/brasero-search-engine.c
index 2f49b57..dd6e5e2 100644
--- a/src/brasero-search-engine.c
+++ b/src/brasero-search-engine.c
@@ -131,42 +131,6 @@ brasero_search_engine_add_hits (BraseroSearchEngine *search,
 	return iface->add_hits (search, model, range_start, range_end);
 }
 
-GIcon *
-brasero_search_engine_icon_from_hit (BraseroSearchEngine *search,
-                                     gpointer hit)
-{
-	BraseroSearchEngineIface *iface;
-
-	g_return_val_if_fail (BRASERO_IS_SEARCH_ENGINE (search), NULL);
-
-	if (!hit)
-		return NULL;
-
-	iface = BRASERO_SEARCH_ENGINE_GET_IFACE (search);
-	if (!iface->icon_from_hit)
-		return FALSE;
-
-	return (* iface->icon_from_hit) (search, hit);
-}
-
-gchar *
-brasero_search_engine_name_from_hit (BraseroSearchEngine *search,
-                                     gpointer hit)
-{
-	BraseroSearchEngineIface *iface;
-
-	g_return_val_if_fail (BRASERO_IS_SEARCH_ENGINE (search), NULL);
-
-	if (!hit)
-		return NULL;
-
-	iface = BRASERO_SEARCH_ENGINE_GET_IFACE (search);
-	if (!iface->name_from_hit)
-		return FALSE;
-
-	return (* iface->name_from_hit) (search, hit);
-}
-
 const gchar *
 brasero_search_engine_uri_from_hit (BraseroSearchEngine *search,
                                      gpointer hit)
@@ -203,24 +167,6 @@ brasero_search_engine_mime_from_hit (BraseroSearchEngine *search,
 	return (* iface->mime_from_hit) (search, hit);
 }
 
-const gchar *
-brasero_search_engine_description_from_hit (BraseroSearchEngine *search,
-                                            gpointer hit)
-{
-	BraseroSearchEngineIface *iface;
-
-	g_return_val_if_fail (BRASERO_IS_SEARCH_ENGINE (search), NULL);
-
-	if (!hit)
-		return NULL;
-
-	iface = BRASERO_SEARCH_ENGINE_GET_IFACE (search);
-	if (!iface->description_from_hit)
-		return FALSE;
-
-	return (* iface->description_from_hit) (search, hit);
-}
-
 gint
 brasero_search_engine_score_from_hit (BraseroSearchEngine *search,
                                       gpointer hit)
@@ -335,9 +281,10 @@ brasero_search_engine_base_init (gpointer g_class)
 			  G_STRUCT_OFFSET (BraseroSearchEngineIface, search_error),
 			  NULL,
 			  NULL,
-			  g_cclosure_marshal_VOID__VOID,
+			  g_cclosure_marshal_VOID__POINTER,
 			  G_TYPE_NONE,
-			  0);
+			  1,
+			  G_TYPE_POINTER);
 	brasero_search_engine_signals [SEARCH_FINISHED] =
 	    g_signal_new ("search_finished",
 			  BRASERO_TYPE_SEARCH_ENGINE,
@@ -375,9 +322,21 @@ brasero_search_engine_base_init (gpointer g_class)
 
 #ifdef BUILD_SEARCH
 
-#include "brasero-search-beagle.h"
+#ifdef BUILD_TRACKER
+
+#include "brasero-search-tracker.h"
+
+BraseroSearchEngine *
+brasero_search_engine_new_default (void)
+{
+	return g_object_new (BRASERO_TYPE_SEARCH_TRACKER, NULL);
+}
+
+#endif
 
-BraseroSearchEngine *search_engine = NULL;
+#ifdef BUILD_BEAGLE
+
+#include "brasero-search-beagle.h"
 
 BraseroSearchEngine *
 brasero_search_engine_new_default (void)
@@ -385,6 +344,8 @@ brasero_search_engine_new_default (void)
 	return g_object_new (BRASERO_TYPE_SEARCH_BEAGLE, NULL);
 }
 
+#endif
+
 #else
 
 BraseroSearchEngine *
diff --git a/src/brasero-search-engine.h b/src/brasero-search-engine.h
index 27a3145..2d1c5fe 100644
--- a/src/brasero-search-engine.h
+++ b/src/brasero-search-engine.h
@@ -55,42 +55,37 @@ struct _BraseroSearchEngineIface {
 	GTypeInterface g_iface;
 
 	/* <Signals> */
-	void	(*search_error)			(BraseroSearchEngine *search);
+	void	(*search_error)				(BraseroSearchEngine *search,
+							 GError *error);
 	void	(*search_finished)			(BraseroSearchEngine *search);
-	void	(*hit_removed)			(BraseroSearchEngine *search,
-					                   gpointer hit);
+	void	(*hit_removed)				(BraseroSearchEngine *search,
+					                 gpointer hit);
 	void	(*hit_added)				(BraseroSearchEngine *search,
-						                 gpointer hit);
+						         gpointer hit);
 
 	/* <Virtual functions> */
 	gboolean	(*is_available)			(BraseroSearchEngine *search);
 	gboolean	(*query_new)			(BraseroSearchEngine *search,
-					                     const gchar *keywords);
-	gboolean	(*query_set_scope)	(BraseroSearchEngine *search,
-					                     BraseroSearchScope scope);
+					                 const gchar *keywords);
+	gboolean	(*query_set_scope)		(BraseroSearchEngine *search,
+					                 BraseroSearchScope scope);
 	gboolean	(*query_set_mime)		(BraseroSearchEngine *search,
-					                     const gchar **mimes);
-	gboolean	(*query_start)		(BraseroSearchEngine *search);
+					                 const gchar **mimes);
+	gboolean	(*query_start)			(BraseroSearchEngine *search);
 
 	gboolean	(*add_hits)			(BraseroSearchEngine *search,
-					                    GtkTreeModel *model,
-					                    gint range_start,
-					                    gint range_end);
+	    GtkTreeModel *model,
+					                 gint range_start,
+					                 gint range_end);
 
-	gint			(*num_hits)			(BraseroSearchEngine *engine);
+	gint		(*num_hits)			(BraseroSearchEngine *engine);
 
-	const gchar*	(*uri_from_hit)		(BraseroSearchEngine *engine,
-				                        gpointer hit);
-	gchar*		(*name_from_hit)		(BraseroSearchEngine *engine,
-				                        gpointer hit);
-	GIcon*		(*icon_from_hit)		(BraseroSearchEngine *engine,
+	const gchar*	(*uri_from_hit)			(BraseroSearchEngine *engine,
 				                         gpointer hit);
-	gint			(*score_from_hit)		(BraseroSearchEngine *engine,
-						                      gpointer hit);
 	const gchar *	(*mime_from_hit)		(BraseroSearchEngine *engine,
-				                              gpointer hit);
-	const gchar *	(*description_from_hit)	(BraseroSearchEngine *engine,
-				                               gpointer hit);
+				                	 gpointer hit);
+	gint		(*score_from_hit)		(BraseroSearchEngine *engine,
+							 gpointer hit);
 };
 
 GType brasero_search_engine_get_type (void);
@@ -133,21 +128,12 @@ void
 brasero_search_engine_hit_added (BraseroSearchEngine *search,
                                  gpointer hit);
 
-GIcon *
-brasero_search_engine_icon_from_hit (BraseroSearchEngine *search,
-                                     gpointer hit);
-gchar *
-brasero_search_engine_name_from_hit (BraseroSearchEngine *search,
-                                     gpointer hit);
 const gchar *
 brasero_search_engine_uri_from_hit (BraseroSearchEngine *search,
                                      gpointer hit);
 const gchar *
 brasero_search_engine_mime_from_hit (BraseroSearchEngine *search,
                                      gpointer hit);
-const gchar *
-brasero_search_engine_description_from_hit (BraseroSearchEngine *search,
-                                            gpointer hit);
 gint
 brasero_search_engine_score_from_hit (BraseroSearchEngine *search,
                                       gpointer hit);
diff --git a/src/brasero-search-tracker.c b/src/brasero-search-tracker.c
new file mode 100644
index 0000000..76265bd
--- /dev/null
+++ b/src/brasero-search-tracker.c
@@ -0,0 +1,418 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero
+ * Copyright (C) Rouquier Philippe 2009 <bonfire-app wanadoo fr>
+ * 
+ * brasero is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include <libtracker-client/tracker.h>
+
+#include "brasero-search-tracker.h"
+#include "brasero-search-engine.h"
+
+typedef struct _BraseroSearchTrackerPrivate BraseroSearchTrackerPrivate;
+struct _BraseroSearchTrackerPrivate
+{
+	TrackerClient *client;
+	GPtrArray *results;
+
+	BraseroSearchScope scope;
+
+	gchar **mimes;
+	gchar *keywords;
+};
+
+#define BRASERO_SEARCH_TRACKER_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_SEARCH_TRACKER, BraseroSearchTrackerPrivate))
+
+static void brasero_search_tracker_init_engine (BraseroSearchEngineIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (BraseroSearchTracker,
+			 brasero_search_tracker,
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (BRASERO_TYPE_SEARCH_ENGINE,
+					        brasero_search_tracker_init_engine));
+
+static gboolean
+brasero_search_tracker_is_available (BraseroSearchEngine *engine)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (engine);
+	if (priv->client)
+		return TRUE;
+
+	priv->client = tracker_connect (TRUE, 30000);
+	return (priv->client != NULL);
+}
+
+static gint
+brasero_search_tracker_num_hits (BraseroSearchEngine *engine)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (engine);
+	if (!priv->results)
+		return 0;
+
+	return priv->results->len;
+}
+
+static gboolean
+brasero_search_tracker_add_hit_to_tree (BraseroSearchEngine *search,
+                                        GtkTreeModel *model,
+                                        gint range_start,
+                                        gint range_end)
+{
+	BraseroSearchTrackerPrivate *priv;
+	gint i;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (search);
+
+	if (!priv->results)
+		return FALSE;
+
+	for (i = range_start; g_ptr_array_index (priv->results, i) && i < range_end; i ++) {
+		gchar **hit;
+		GtkTreeIter row;
+
+		hit = g_ptr_array_index (priv->results, i);
+		gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &row, -1,
+		                                   BRASERO_SEARCH_TREE_HIT_COL, hit,
+		                                   -1);
+	}
+
+	return TRUE;
+}
+
+static const gchar *
+brasero_search_tracker_uri_from_hit (BraseroSearchEngine *engine,
+                                     gpointer hit)
+{
+	gchar **tracker_hit;
+
+	tracker_hit = hit;
+
+	if (!tracker_hit)
+		return NULL;
+
+	if (g_strv_length (tracker_hit) >= 1)
+		return tracker_hit [0];
+
+	return NULL;
+}
+
+static const gchar *
+brasero_search_tracker_mime_from_hit (BraseroSearchEngine *engine,
+                                      gpointer hit)
+{
+	gchar **tracker_hit;
+
+	tracker_hit = hit;
+
+	if (!tracker_hit)
+		return NULL;
+
+	if (g_strv_length (tracker_hit) >= 2)
+		return tracker_hit [1];
+
+	return NULL;
+}
+
+static int
+brasero_search_tracker_score_from_hit (BraseroSearchEngine *engine,
+                                       gpointer hit)
+{
+	gchar **tracker_hit;
+
+	tracker_hit = hit;
+
+	if (!tracker_hit)
+		return 0;
+
+	if (g_strv_length (tracker_hit) >= 3)
+		return (int) strtof (tracker_hit [2], NULL);
+
+	return 0;
+}
+
+static void
+brasero_search_tracker_reply (GPtrArray *results,
+			      GError *error,
+			      gpointer user_data)
+{
+	BraseroSearchEngine *search = BRASERO_SEARCH_ENGINE (user_data);
+	BraseroSearchTrackerPrivate *priv;
+	int i;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (search);
+
+	if (error) {
+		brasero_search_engine_query_error (search, error);
+		return;
+	}
+
+	if (!results) {
+		brasero_search_engine_query_finished (search);
+		return;
+	}
+
+	priv->results = results;
+	for (i = 0; i < results->len; i ++)
+		brasero_search_engine_hit_added (search, g_ptr_array_index (results, i));
+
+	brasero_search_engine_query_finished (search);
+}
+
+static gboolean
+brasero_search_tracker_query_start (BraseroSearchEngine *search)
+{
+	BraseroSearchTrackerPrivate *priv;
+	gboolean res = FALSE;
+	GString *query = NULL;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (search);
+
+	if (!priv->mimes && !priv->scope) {
+		if (!priv->keywords)
+			return FALSE;
+
+		query = g_string_new ("SELECT ?file ?mime "			/* Which variables should be returned */
+				      "WHERE {"					/* Start defining the search and its scope */
+				      "  ?file a nfo:FileDataObject . ");	/* File must be a file (not a stream, ...) */
+
+		g_string_append_printf(query,
+				      "  ?file fts:match \"%s\" . "		/* File must match keywords */
+				      "OPTIONAL {  ?file nie:mimeType ?mime } "	/* Get its mime */
+				      "} "
+				      "ORDER BY ASC(?file) "
+				      "OFFSET 0 "
+				      "LIMIT 10000",
+				      priv->keywords);
+	}
+	else if (priv->mimes) {
+		int i;
+
+		query = g_string_new ("SELECT ?file ?mime "			/* Which variables should be returned */
+				      "WHERE {"					/* Start defining the search and its scope */
+				      "  ?file a nfo:FileDataObject . ");       /* File must be a file (not a stream, ...) */
+
+		if (priv->keywords)
+			g_string_append_printf (query,
+						"  ?file fts:match \"%s\" . ",  /* File must match possible keywords */
+						priv->keywords);
+
+		g_string_append (query,
+				 "  ?file nie:mimeType ?mime "			/* Get its mime */
+				 " FILTER ( ");
+
+		for (i = 0; priv->mimes [i]; i ++) {				/* And filter files according to their mime type */
+			if (i > 0)
+				g_string_append (query, " || ");
+			g_string_append_printf (query,
+						"?mime = \"%s\"",
+						priv->mimes [i]);
+		}
+		g_string_append (query,						/* Finish the query */
+				 ") } "
+				 "ORDER BY ASC(?file) "
+				 "OFFSET 0 "
+				 "LIMIT 10000");
+	}
+	else if (priv->scope) {
+		gboolean param_added = FALSE;
+
+		query = g_string_new ("SELECT ?file ?mime fts:rank(?file) "
+				      "WHERE { "
+				      "  ?file a nfo:FileDataObject . "
+				      "  ?file a ?type . "
+				      "  FILTER ( ");
+
+		if (priv->scope & BRASERO_SEARCH_SCOPE_MUSIC) {
+			query = g_string_append (query, "?type = nmm:MusicPiece");
+			param_added = TRUE;
+		}
+
+		if (priv->scope & BRASERO_SEARCH_SCOPE_VIDEO) {
+			if (param_added)
+				g_string_append (query, " || ");
+			query = g_string_append (query, "?type = nfo:Video");
+
+			param_added = TRUE;
+		}
+	
+		if (priv->scope & BRASERO_SEARCH_SCOPE_PICTURES) {
+			if (param_added)
+				g_string_append (query, " || ");
+			query = g_string_append (query, "?type = nfo:Image");
+
+			param_added = TRUE;
+		}
+
+		if (priv->scope & BRASERO_SEARCH_SCOPE_DOCUMENTS) {
+			if (param_added)
+				g_string_append (query, " || ");
+			query = g_string_append (query, "?type = nfo:Document");
+		}
+
+		g_string_append (query,
+				 " ) ");
+
+		if (priv->keywords)
+			g_string_append_printf (query,
+						"  ?file fts:match \"%s\" ",
+						priv->keywords);
+
+		g_string_append (query,
+				 "OPTIONAL {  ?file nie:mimeType ?mime } "
+				 "} "
+				 "ORDER BY ASC(fts:rank(?file)) "
+				 "OFFSET 0 "
+				 "LIMIT 10000");
+	}
+
+	if (!query)
+		return FALSE;
+
+	res = tracker_resources_sparql_query_async (priv->client,
+						    query->str,
+						    brasero_search_tracker_reply,
+						    search);
+	g_string_free (query, TRUE);
+
+	return res;
+}
+
+static gboolean
+brasero_search_tracker_query_set_scope (BraseroSearchEngine *search,
+                                        BraseroSearchScope scope)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (search);
+	priv->scope = scope;
+	return TRUE;
+}
+
+static gboolean
+brasero_search_tracker_set_query_mime (BraseroSearchEngine *search,
+				       const gchar **mimes)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (search);
+
+	if (priv->mimes) {
+		g_strfreev (priv->mimes);
+		priv->mimes = NULL;
+	}
+
+	priv->mimes = g_strdupv ((gchar **) mimes);
+	return TRUE;
+}
+
+static void
+brasero_search_tracker_clean (BraseroSearchTracker *search)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (search);
+
+	if (priv->results) {
+		g_ptr_array_foreach (priv->results, (GFunc) g_free, NULL);
+		g_ptr_array_free (priv->results, TRUE);
+		priv->results = NULL;
+	}
+
+	if (priv->keywords) {
+		g_free (priv->keywords);
+		priv->keywords = NULL;
+	}
+
+	if (priv->mimes) {
+		g_strfreev (priv->mimes);
+		priv->mimes = NULL;
+	}
+}
+
+static gboolean
+brasero_search_tracker_query_new (BraseroSearchEngine *search,
+				  const gchar *keywords)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (search);
+
+	brasero_search_tracker_clean (BRASERO_SEARCH_TRACKER (search));
+	priv->keywords = g_strdup (keywords);
+
+	return TRUE;
+}
+
+static void
+brasero_search_tracker_init_engine (BraseroSearchEngineIface *iface)
+{
+	iface->is_available = brasero_search_tracker_is_available;
+	iface->query_new = brasero_search_tracker_query_new;
+	iface->query_set_mime = brasero_search_tracker_set_query_mime;
+	iface->query_set_scope = brasero_search_tracker_query_set_scope;
+	iface->query_start = brasero_search_tracker_query_start;
+
+	iface->uri_from_hit = brasero_search_tracker_uri_from_hit;
+	iface->mime_from_hit = brasero_search_tracker_mime_from_hit;
+	iface->score_from_hit = brasero_search_tracker_score_from_hit;
+
+	iface->add_hits = brasero_search_tracker_add_hit_to_tree;
+	iface->num_hits = brasero_search_tracker_num_hits;
+}
+
+static void
+brasero_search_tracker_init (BraseroSearchTracker *object)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (object);
+	priv->client = tracker_connect (TRUE, 30000);
+}
+
+static void
+brasero_search_tracker_finalize (GObject *object)
+{
+	BraseroSearchTrackerPrivate *priv;
+
+	priv = BRASERO_SEARCH_TRACKER_PRIVATE (object);
+
+	brasero_search_tracker_clean (BRASERO_SEARCH_TRACKER (object));
+
+	if (priv->client) {
+		tracker_disconnect (priv->client);
+		priv->client = NULL;
+	}
+
+	G_OBJECT_CLASS (brasero_search_tracker_parent_class)->finalize (object);
+}
+
+static void
+brasero_search_tracker_class_init (BraseroSearchTrackerClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+
+	g_type_class_add_private (klass, sizeof (BraseroSearchTrackerPrivate));
+
+	object_class->finalize = brasero_search_tracker_finalize;
+}
+
diff --git a/src/brasero-search-tracker.h b/src/brasero-search-tracker.h
new file mode 100644
index 0000000..bc1098a
--- /dev/null
+++ b/src/brasero-search-tracker.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero
+ * Copyright (C) Rouquier Philippe 2009 <bonfire-app wanadoo fr>
+ * 
+ * brasero is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BRASERO_SEARCH_TRACKER_H_
+#define _BRASERO_SEARCH_TRACKER_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_SEARCH_TRACKER             (brasero_search_tracker_get_type ())
+#define BRASERO_SEARCH_TRACKER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_SEARCH_TRACKER, BraseroSearchTracker))
+#define BRASERO_SEARCH_TRACKER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_SEARCH_TRACKER, BraseroSearchTrackerClass))
+#define BRASERO_IS_SEARCH_TRACKER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_SEARCH_TRACKER))
+#define BRASERO_IS_SEARCH_TRACKER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_SEARCH_TRACKER))
+#define BRASERO_SEARCH_TRACKER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_SEARCH_TRACKER, BraseroSearchTrackerClass))
+
+typedef struct _BraseroSearchTrackerClass BraseroSearchTrackerClass;
+typedef struct _BraseroSearchTracker BraseroSearchTracker;
+
+struct _BraseroSearchTrackerClass
+{
+	GObjectClass parent_class;
+};
+
+struct _BraseroSearchTracker
+{
+	GObject parent_instance;
+};
+
+GType brasero_search_tracker_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* _BRASERO_SEARCH_TRACKER_H_ */
diff --git a/src/brasero-search.c b/src/brasero-search.c
index 655f43b..5579140 100644
--- a/src/brasero-search.c
+++ b/src/brasero-search.c
@@ -108,19 +108,51 @@ brasero_search_column_icon_cb (GtkTreeViewColumn *tree_column,
                                gpointer data)
 {
 	GIcon *icon;
+	const gchar *mime;
 	gpointer hit = NULL;
 
 	gtk_tree_model_get (model, iter,
 	                    BRASERO_SEARCH_TREE_HIT_COL, &hit,
 	                    -1);
 
-	icon = brasero_search_engine_icon_from_hit (BRASERO_SEARCH (data)->priv->engine, hit);
+	mime = brasero_search_engine_mime_from_hit (BRASERO_SEARCH (data)->priv->engine, hit);
+	if (!mime)
+		return;
+	
+	if (!strcmp (mime, "inode/directory"))
+		mime = "x-directory/normal";
+
+	icon = g_content_type_get_icon (mime);
 	g_object_set (G_OBJECT (cell),
 		      "gicon", icon,
 		      NULL);
 	g_object_unref (icon);
 }
 
+static gchar *
+brasero_search_name_from_hit (BraseroSearch *search,
+			      gpointer hit)
+{
+	gchar *name;
+	const gchar *uri;
+	gchar *unescaped_uri;
+
+	uri = brasero_search_engine_uri_from_hit (search->priv->engine, hit);
+
+	/* beagle can return badly formed uri not
+	 * encoded in UTF-8 locale charset so we
+	 * check them just in case */
+	unescaped_uri = g_uri_unescape_string (uri, NULL);
+	if (!g_utf8_validate (unescaped_uri, -1, NULL)) {
+		g_free (unescaped_uri);
+		return NULL;
+	}
+
+	name = g_path_get_basename (unescaped_uri);
+	g_free (unescaped_uri);
+	return name;
+}
+
 static void
 brasero_search_column_name_cb (GtkTreeViewColumn *tree_column,
                                GtkCellRenderer *cell,
@@ -135,13 +167,26 @@ brasero_search_column_name_cb (GtkTreeViewColumn *tree_column,
 	                    BRASERO_SEARCH_TREE_HIT_COL, &hit,
 	                    -1);
 
-	name = brasero_search_engine_name_from_hit (BRASERO_SEARCH (data)->priv->engine, hit);
+	name = brasero_search_name_from_hit (data, hit);
 	g_object_set (G_OBJECT (cell),
 		      "text", name,
 		      NULL);
 	g_free (name);
 }
 
+static const gchar*
+brasero_search_description_from_hit (BraseroSearch *search,
+				     gpointer hit)
+{
+	const gchar *mime;
+
+	mime = brasero_search_engine_mime_from_hit (search->priv->engine, hit);
+	if (!mime)
+		return NULL;
+
+	return g_content_type_get_description (mime);
+}
+
 static void
 brasero_search_column_description_cb (GtkTreeViewColumn *tree_column,
                                       GtkCellRenderer *cell,
@@ -156,7 +201,7 @@ brasero_search_column_description_cb (GtkTreeViewColumn *tree_column,
 	                    BRASERO_SEARCH_TREE_HIT_COL, &hit,
 	                    -1);
 
-	description = brasero_search_engine_description_from_hit (BRASERO_SEARCH (data)->priv->engine, hit);
+	description = brasero_search_description_from_hit (data, hit);
 	g_object_set (G_OBJECT (cell),
 		      "text", description,
 		      NULL);
@@ -266,8 +311,10 @@ brasero_search_row_inserted (GtkTreeModel *model,
 
 	mime = brasero_search_engine_mime_from_hit (search->priv->engine, hit);
 
-	/* add the mime type to the filter combo */
-	brasero_mime_filter_add_mime (BRASERO_MIME_FILTER (search->priv->filter), mime);
+	if (mime) {
+		/* add the mime type to the filter combo */
+		brasero_mime_filter_add_mime (BRASERO_MIME_FILTER (search->priv->filter), mime);
+	}
 }
 
 static gboolean
@@ -486,7 +533,7 @@ brasero_search_is_visible_cb (GtkTreeModel *model,
 	                    BRASERO_SEARCH_TREE_HIT_COL, &hit,
 	                    -1);
 
-	name = brasero_search_engine_name_from_hit (search->priv->engine, hit);
+	name = brasero_search_name_from_hit (search, hit);
 	uri = brasero_search_engine_uri_from_hit (search->priv->engine, hit);
 	mime = brasero_search_engine_mime_from_hit (search->priv->engine, hit);
 	result = brasero_mime_filter_filter (BRASERO_MIME_FILTER (search->priv->filter),
@@ -640,8 +687,8 @@ brasero_search_sort_name (GtkTreeModel *model,
 	                    BRASERO_SEARCH_TREE_HIT_COL, &hit2,
 	                    -1);
 
-	name1 = brasero_search_engine_name_from_hit (search->priv->engine, hit1);
-	name2 = brasero_search_engine_name_from_hit (search->priv->engine, hit2);
+	name1 = brasero_search_name_from_hit (search, hit1);
+	name2 = brasero_search_name_from_hit (search, hit2);
 
 	res = g_strcmp0 (name1, name2);
 	g_free (name1);
@@ -666,8 +713,8 @@ brasero_search_sort_description (GtkTreeModel *model,
 	                    BRASERO_SEARCH_TREE_HIT_COL, &hit2,
 	                    -1);
 
-	return g_strcmp0 (brasero_search_engine_description_from_hit (search->priv->engine, hit1),
-	                  brasero_search_engine_description_from_hit (search->priv->engine, hit2));
+	return g_strcmp0 (brasero_search_description_from_hit (search, hit1),
+	                  brasero_search_description_from_hit (search, hit2));
 }
 
 static gint
@@ -686,8 +733,8 @@ brasero_search_sort_score (GtkTreeModel *model,
 	                    BRASERO_SEARCH_TREE_HIT_COL, &hit2,
 	                    -1);
 
-	return brasero_search_engine_score_from_hit (search->priv->engine, hit1) -
-		    brasero_search_engine_score_from_hit (search->priv->engine, hit2);
+	return brasero_search_engine_score_from_hit (search->priv->engine, hit2) -
+	       brasero_search_engine_score_from_hit (search->priv->engine, hit1);
 }
 
 static void



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