]> Pileus Git - ~andy/gtk/blob - gtk/gtksearchenginetracker.c
Include "config.h" instead of <config.h> Command used: find -name
[~andy/gtk] / gtk / gtksearchenginetracker.c
1 /*
2  * Copyright (C) 2005 Mr Jamie McCracken
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  *
18  * Author: Jamie McCracken <jamiemcc@gnome.org>
19  *
20  * Based on nautilus-search-engine-tracker.c
21  */
22
23 #include "config.h"
24 #include <gmodule.h>
25 #include "gtksearchenginetracker.h"
26 #if 0
27 #include <tracker.h>
28 #endif
29
30 /* we dlopen() libtracker at runtime */
31
32 typedef struct _TrackerClient TrackerClient;
33
34 typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data);
35
36 static TrackerClient * (*tracker_connect) (gboolean enable_warnings) = NULL;
37 static void            (*tracker_disconnect) (TrackerClient *client) = NULL;
38 static int             (*tracker_get_version) (TrackerClient *client, GError **error) = NULL;
39 static void            (*tracker_cancel_last_call) (TrackerClient *client) = NULL;
40
41 static void (*tracker_search_metadata_by_text_async) (TrackerClient *client, 
42                                                       const char *query, 
43                                                       TrackerArrayReply callback, 
44                                                       gpointer user_data) = NULL;
45 static void (*tracker_search_metadata_by_text_and_location_async) (TrackerClient *client, 
46                                                                    const char *query, 
47                                                                    const char *location, 
48                                                                    TrackerArrayReply callback, 
49                                                                    gpointer user_data) = NULL;
50
51 static struct TrackerDlMapping
52 {
53   const char *fn_name;
54   gpointer *fn_ptr_ref;
55 } tracker_dl_mapping[] =
56 {
57 #define MAP(a) { #a, (gpointer *)&a }
58   MAP (tracker_connect),
59   MAP (tracker_disconnect),
60   MAP (tracker_get_version),
61   MAP (tracker_cancel_last_call),
62   MAP (tracker_search_metadata_by_text_async),
63   MAP (tracker_search_metadata_by_text_and_location_async),
64 #undef MAP
65 };
66
67 static void 
68 open_libtracker (void)
69 {
70   static gboolean done = FALSE;
71
72   if (!done)
73     {
74       int i;
75       GModule *tracker;
76       GModuleFlags flags;
77       
78       done = TRUE;
79       flags = G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL;
80
81       tracker = g_module_open ("libtrackerclient.so.0", flags);
82
83       if (!tracker)
84         tracker = g_module_open ("libtracker.so.0", flags);
85
86       if (!tracker)
87         return;
88       
89       for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++)
90         {
91           if (!g_module_symbol (tracker, tracker_dl_mapping[i].fn_name,
92                                 tracker_dl_mapping[i].fn_ptr_ref))
93             {
94               g_warning ("Missing symbol '%s' in libtracker\n",
95                          tracker_dl_mapping[i].fn_name);
96               g_module_close (tracker);
97
98               for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++)
99                 tracker_dl_mapping[i].fn_ptr_ref = NULL;
100
101               return;
102             }
103         }
104     }
105 }
106
107 struct _GtkSearchEngineTrackerPrivate 
108 {
109   GtkQuery      *query;
110   TrackerClient *client;
111   gboolean       query_pending;
112 };
113
114 G_DEFINE_TYPE (GtkSearchEngineTracker, _gtk_search_engine_tracker, GTK_TYPE_SEARCH_ENGINE);
115
116
117 static void
118 finalize (GObject *object)
119 {
120   GtkSearchEngineTracker *tracker;
121   
122   tracker = GTK_SEARCH_ENGINE_TRACKER (object);
123   
124   if (tracker->priv->query) 
125     {
126       g_object_unref (tracker->priv->query);
127       tracker->priv->query = NULL;
128     }
129
130   tracker_disconnect (tracker->priv->client);
131
132   G_OBJECT_CLASS (_gtk_search_engine_tracker_parent_class)->finalize (object);
133 }
134
135
136 static void
137 search_callback (gchar  **results, 
138                  GError  *error, 
139                  gpointer user_data)
140 {
141   GtkSearchEngineTracker *tracker;
142   gchar **results_p;
143   GList *hit_uris;
144   
145   tracker = GTK_SEARCH_ENGINE_TRACKER (user_data);
146   hit_uris = NULL;
147   
148   tracker->priv->query_pending = FALSE;
149
150   if (error) 
151     {
152       _gtk_search_engine_error ( GTK_SEARCH_ENGINE (tracker), error->message);
153       g_error_free (error);
154       return;
155     }
156
157   if (!results)
158     return;
159         
160   for (results_p = results; *results_p; results_p++) 
161     {
162       gchar *uri;
163
164       uri = g_filename_to_uri (*results_p, NULL, NULL);
165       if (uri)
166         hit_uris = g_list_prepend (hit_uris, uri);
167     }
168
169   _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (tracker), hit_uris);
170   _gtk_search_engine_finished (GTK_SEARCH_ENGINE (tracker));
171
172   g_strfreev  (results);
173   g_list_foreach (hit_uris, (GFunc)g_free, NULL);
174   g_list_free (hit_uris);
175 }
176
177
178 static void
179 gtk_search_engine_tracker_start (GtkSearchEngine *engine)
180 {
181   GtkSearchEngineTracker *tracker;
182   gchar *search_text, *location, *location_uri;
183
184   tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
185
186   if (tracker->priv->query_pending)
187     return;
188
189   if (tracker->priv->query == NULL)
190     return;
191         
192   search_text = _gtk_query_get_text (tracker->priv->query);
193   location_uri = _gtk_query_get_location (tracker->priv->query);
194
195   location = NULL;
196   if (location_uri)
197     {
198       location = g_filename_from_uri (location_uri, NULL, NULL);
199       g_free (location_uri);
200     } 
201
202   if (location) 
203     {
204       tracker_search_metadata_by_text_and_location_async (tracker->priv->client,
205                                                           search_text, 
206                                                           location, 
207                                                           search_callback,
208                                                           tracker);
209       g_free (location);
210     }
211   else 
212     {
213       tracker_search_metadata_by_text_async (tracker->priv->client,
214                                              search_text, 
215                                              search_callback,
216                                              tracker);
217     }
218
219   tracker->priv->query_pending = TRUE;
220   g_free (search_text);
221 }
222
223 static void
224 gtk_search_engine_tracker_stop (GtkSearchEngine *engine)
225 {
226   GtkSearchEngineTracker *tracker;
227   
228   tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
229   
230   if (tracker->priv->query && tracker->priv->query_pending) 
231     {
232       tracker_cancel_last_call (tracker->priv->client);
233       tracker->priv->query_pending = FALSE;
234     }
235 }
236
237 static gboolean
238 gtk_search_engine_tracker_is_indexed (GtkSearchEngine *engine)
239 {
240   return TRUE;
241 }
242
243 static void
244 gtk_search_engine_tracker_set_query (GtkSearchEngine *engine, 
245                                      GtkQuery        *query)
246 {
247   GtkSearchEngineTracker *tracker;
248   
249   tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
250   
251   if (query) 
252     g_object_ref (query);
253
254   if (tracker->priv->query)
255     g_object_unref (tracker->priv->query);
256
257   tracker->priv->query = query;
258 }
259
260 static void
261 _gtk_search_engine_tracker_class_init (GtkSearchEngineTrackerClass *class)
262 {
263   GObjectClass *gobject_class;
264   GtkSearchEngineClass *engine_class;
265   
266   gobject_class = G_OBJECT_CLASS (class);
267   gobject_class->finalize = finalize;
268   
269   engine_class = GTK_SEARCH_ENGINE_CLASS (class);
270   engine_class->set_query = gtk_search_engine_tracker_set_query;
271   engine_class->start = gtk_search_engine_tracker_start;
272   engine_class->stop = gtk_search_engine_tracker_stop;
273   engine_class->is_indexed = gtk_search_engine_tracker_is_indexed;
274
275   g_type_class_add_private (gobject_class, sizeof (GtkSearchEngineTrackerPrivate));
276 }
277
278 static void
279 _gtk_search_engine_tracker_init (GtkSearchEngineTracker *engine)
280 {
281   engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTrackerPrivate);
282 }
283
284
285 GtkSearchEngine *
286 _gtk_search_engine_tracker_new (void)
287 {
288   GtkSearchEngineTracker *engine;
289   TrackerClient *tracker_client;
290   GError *err = NULL;
291
292   open_libtracker ();
293
294   if (!tracker_connect)
295     return NULL;
296
297   tracker_client = tracker_connect (FALSE);
298   
299   if (!tracker_client)
300     return NULL;
301
302   if (!tracker_get_version)
303     return NULL;
304
305   tracker_get_version (tracker_client, &err);
306
307   if (err != NULL)
308     {
309       g_error_free (err);
310       tracker_disconnect (tracker_client);
311       return NULL;
312     }
313
314   engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_TRACKER, NULL);
315
316   engine->priv->client = tracker_client;
317   engine->priv->query_pending = FALSE;
318   
319   return GTK_SEARCH_ENGINE (engine);
320 }