forked from AuroraMiddleware/gtk
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
This commit is contained in:
parent
e82e337ee9
commit
d3aeccf774
31
ChangeLog
31
ChangeLog
@ -1,3 +1,34 @@
|
||||
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
|
||||
|
||||
2007-05-02 Armin Burgmeier <armin@openismus.com>
|
||||
|
||||
* gtk/gtkcombobox.c: Destroy the menu in dispose instead of
|
||||
|
@ -335,6 +335,11 @@ gtk_semi_private_h_sources = \
|
||||
|
||||
# GTK+ header files that don't get installed
|
||||
gtk_private_h_sources = \
|
||||
gtkquery.h \
|
||||
gtksearchengine.h \
|
||||
gtksearchenginebeagle.h \
|
||||
gtksearchenginetracker.h\
|
||||
gtksearchenginesimple.h \
|
||||
gtkdndcursors.h \
|
||||
gtkentryprivate.h \
|
||||
gtkfilechooserdefault.h \
|
||||
@ -376,6 +381,11 @@ gtk_private_h_sources = \
|
||||
|
||||
# GTK+ C sources to build the library from
|
||||
gtk_base_c_sources = \
|
||||
gtkquery.c \
|
||||
gtksearchengine.c \
|
||||
gtksearchenginebeagle.c \
|
||||
gtksearchenginetracker.c\
|
||||
gtksearchenginesimple.c \
|
||||
fnmatch.c \
|
||||
gtkaboutdialog.c \
|
||||
gtkaccelgroup.c \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,8 @@
|
||||
#include "gtkfilesystem.h"
|
||||
#include "gtkfilesystemmodel.h"
|
||||
#include "gtkliststore.h"
|
||||
#include "gtksearchengine.h"
|
||||
#include "gtkquery.h"
|
||||
#include "gtktooltips.h"
|
||||
#include "gtktreemodelsort.h"
|
||||
#include "gtktreestore.h"
|
||||
@ -147,6 +149,11 @@ typedef enum {
|
||||
LOCATION_MODE_FILENAME_ENTRY
|
||||
} LocationMode;
|
||||
|
||||
typedef enum {
|
||||
OPERATION_MODE_BROWSE,
|
||||
OPERATION_MODE_SEARCH
|
||||
} OperationMode;
|
||||
|
||||
struct _GtkFileChooserDefault
|
||||
{
|
||||
GtkVBox parent_instance;
|
||||
@ -175,11 +182,19 @@ struct _GtkFileChooserDefault
|
||||
GtkWidget *browse_files_popup_menu_add_shortcut_item;
|
||||
GtkWidget *browse_files_popup_menu_hidden_files_item;
|
||||
GtkWidget *browse_new_folder_button;
|
||||
GtkWidget *browse_path_bar_hbox;
|
||||
GtkWidget *browse_path_bar;
|
||||
|
||||
GtkFileSystemModel *browse_files_model;
|
||||
char *browse_files_last_selected_name;
|
||||
|
||||
/* Widgets for searching */
|
||||
GtkWidget *search_hbox;
|
||||
GtkWidget *search_entry;
|
||||
GtkSearchEngine *search_engine;
|
||||
GtkQuery *search_query;
|
||||
GtkListStore *search_model;
|
||||
|
||||
GtkWidget *filter_combo_hbox;
|
||||
GtkWidget *filter_combo;
|
||||
GtkWidget *preview_box;
|
||||
@ -195,7 +210,16 @@ struct _GtkFileChooserDefault
|
||||
LocationMode location_mode;
|
||||
|
||||
GtkListStore *shortcuts_model;
|
||||
GtkTreeModel *shortcuts_filter_model;
|
||||
|
||||
/* Filter for the shortcuts pane. We filter out the "current folder" row and
|
||||
* the separator that we use for the "Save in folder" combo.
|
||||
*/
|
||||
GtkTreeModel *shortcuts_pane_filter_model;
|
||||
|
||||
/* Filter for the "Save in folder" combo. We filter out the Search row and
|
||||
* its separator.
|
||||
*/
|
||||
GtkTreeModel *shortcuts_combo_filter_model;
|
||||
|
||||
GtkTreeModelSort *sort_model;
|
||||
|
||||
@ -215,6 +239,8 @@ struct _GtkFileChooserDefault
|
||||
ReloadState reload_state;
|
||||
guint load_timeout_id;
|
||||
|
||||
OperationMode operation_mode;
|
||||
|
||||
GSList *pending_select_paths;
|
||||
|
||||
GtkFileFilter *current_filter;
|
||||
@ -222,9 +248,6 @@ struct _GtkFileChooserDefault
|
||||
|
||||
GtkTooltips *tooltips;
|
||||
|
||||
gboolean has_home;
|
||||
gboolean has_desktop;
|
||||
|
||||
int num_volumes;
|
||||
int num_shortcuts;
|
||||
int num_bookmarks;
|
||||
@ -239,6 +262,7 @@ struct _GtkFileChooserDefault
|
||||
|
||||
GtkTreeViewColumn *list_name_column;
|
||||
GtkCellRenderer *list_name_renderer;
|
||||
GtkTreeViewColumn *list_mtime_column;
|
||||
|
||||
GSource *edited_idle;
|
||||
char *edited_new_text;
|
||||
@ -266,6 +290,9 @@ struct _GtkFileChooserDefault
|
||||
guint changing_folder : 1;
|
||||
guint shortcuts_current_folder_active : 1;
|
||||
guint expand_folders : 1;
|
||||
guint has_home : 1;
|
||||
guint has_desktop : 1;
|
||||
guint has_search : 1;
|
||||
|
||||
#if 0
|
||||
guint shortcuts_drag_outside : 1;
|
||||
|
142
gtk/gtkquery.c
Normal file
142
gtk/gtkquery.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Novell, Inc.
|
||||
*
|
||||
* 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: Anders Carlsson <andersca@imendio.com>
|
||||
*
|
||||
* Based on nautilus-query.c
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gtkquery.h"
|
||||
|
||||
struct _GtkQueryPrivate
|
||||
{
|
||||
gchar *text;
|
||||
gchar *location_uri;
|
||||
GList *mime_types;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkQuery, _gtk_query, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
GtkQuery *query;
|
||||
|
||||
query = GTK_QUERY (object);
|
||||
|
||||
g_free (query->priv->text);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_query_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_query_class_init (GtkQueryClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
gobject_class->finalize = finalize;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (GtkQueryPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_query_init (GtkQuery *query)
|
||||
{
|
||||
query->priv = G_TYPE_INSTANCE_GET_PRIVATE (query, GTK_TYPE_QUERY, GtkQueryPrivate);
|
||||
}
|
||||
|
||||
GtkQuery *
|
||||
_gtk_query_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_QUERY, NULL);
|
||||
}
|
||||
|
||||
|
||||
gchar *
|
||||
_gtk_query_get_text (GtkQuery *query)
|
||||
{
|
||||
return g_strdup (query->priv->text);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_query_set_text (GtkQuery *query,
|
||||
const gchar *text)
|
||||
{
|
||||
g_free (query->priv->text);
|
||||
query->priv->text = g_strdup (text);
|
||||
}
|
||||
|
||||
gchar *
|
||||
_gtk_query_get_location (GtkQuery *query)
|
||||
{
|
||||
return g_strdup (query->priv->location_uri);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_query_set_location (GtkQuery *query,
|
||||
const gchar *uri)
|
||||
{
|
||||
g_free (query->priv->location_uri);
|
||||
query->priv->location_uri = g_strdup (uri);
|
||||
}
|
||||
|
||||
GList *
|
||||
_gtk_query_get_mime_types (GtkQuery *query)
|
||||
{
|
||||
GList *list, *l;
|
||||
gchar *mime_type;
|
||||
|
||||
list = NULL;
|
||||
for (l = query->priv->mime_types; l; l = l->next)
|
||||
{
|
||||
mime_type = (gchar*)l->data;
|
||||
list = g_list_prepend (list, g_strdup (mime_type));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_query_set_mime_types (GtkQuery *query,
|
||||
GList *mime_types)
|
||||
{
|
||||
GList *l;
|
||||
gchar *mime_type;
|
||||
|
||||
g_list_foreach (query->priv->mime_types, (GFunc)g_free, NULL);
|
||||
g_list_free (query->priv->mime_types);
|
||||
query->priv->mime_types = NULL;
|
||||
|
||||
for (l = mime_types; l; l = l->next)
|
||||
{
|
||||
mime_type = (gchar*)l->data;
|
||||
query->priv->mime_types = g_list_prepend (query->priv->mime_types, g_strdup (mime_type));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_query_add_mime_type (GtkQuery *query,
|
||||
const gchar *mime_type)
|
||||
{
|
||||
query->priv->mime_types = g_list_prepend (query->priv->mime_types,
|
||||
g_strdup (mime_type));
|
||||
}
|
||||
|
74
gtk/gtkquery.h
Normal file
74
gtk/gtkquery.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Novell, Inc.
|
||||
*
|
||||
* 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: Anders Carlsson <andersca@imendio.com>
|
||||
*
|
||||
* Based on nautilus-query.h
|
||||
*/
|
||||
|
||||
#ifndef __GTK_QUERY_H__
|
||||
#define __GTK_QUERY_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_QUERY (_gtk_query_get_type ())
|
||||
#define GTK_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_QUERY, GtkQuery))
|
||||
#define GTK_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_QUERY, GtkQueryClass))
|
||||
#define GTK_IS_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_QUERY))
|
||||
#define GTK_IS_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_QUERY))
|
||||
#define GTK_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_QUERY, GtkQueryClass))
|
||||
|
||||
typedef struct _GtkQuery GtkQuery;
|
||||
typedef struct _GtkQueryClass GtkQueryClass;
|
||||
typedef struct _GtkQueryPrivate GtkQueryPrivate;
|
||||
|
||||
struct _GtkQuery
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GtkQueryPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkQueryClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_query_get_type (void);
|
||||
gboolean _gtk_query_enabled (void);
|
||||
|
||||
GtkQuery* _gtk_query_new (void);
|
||||
|
||||
gchar* _gtk_query_get_text (GtkQuery *query);
|
||||
void _gtk_query_set_text (GtkQuery *query,
|
||||
const gchar *text);
|
||||
|
||||
gchar* _gtk_query_get_location (GtkQuery *query);
|
||||
void _gtk_query_set_location (GtkQuery *query,
|
||||
const gchar *uri);
|
||||
|
||||
GList* _gtk_query_get_mime_types (GtkQuery *query);
|
||||
void _gtk_query_set_mime_types (GtkQuery *query,
|
||||
GList *mime_types);
|
||||
void _gtk_query_add_mime_type (GtkQuery *query,
|
||||
const gchar *mime_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_QUERY_H__ */
|
197
gtk/gtksearchengine.c
Normal file
197
gtk/gtksearchengine.c
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Novell, Inc.
|
||||
*
|
||||
* 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: Anders Carlsson <andersca@imendio.com>
|
||||
*
|
||||
* Based on nautilus-search-engine.c
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "gtksearchengine.h"
|
||||
#include "gtksearchenginebeagle.h"
|
||||
#include "gtksearchenginesimple.h"
|
||||
#include "gtksearchenginetracker.h"
|
||||
|
||||
#define HAVE_BEAGLE 1
|
||||
#define HAVE_TRACKER 1
|
||||
|
||||
enum
|
||||
{
|
||||
HITS_ADDED,
|
||||
HITS_SUBTRACTED,
|
||||
FINISHED,
|
||||
ERROR,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkSearchEngine, _gtk_search_engine, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (_gtk_search_engine_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_search_engine_class_init (GtkSearchEngineClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
gobject_class->finalize = finalize;
|
||||
|
||||
signals[HITS_ADDED] =
|
||||
g_signal_new ("hits-added",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkSearchEngineClass, hits_added),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
signals[HITS_SUBTRACTED] =
|
||||
g_signal_new ("hits-subtracted",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkSearchEngineClass, hits_subtracted),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
signals[FINISHED] =
|
||||
g_signal_new ("finished",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkSearchEngineClass, finished),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[ERROR] =
|
||||
g_signal_new ("error",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkSearchEngineClass, error),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING);
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_search_engine_init (GtkSearchEngine *engine)
|
||||
{
|
||||
}
|
||||
|
||||
GtkSearchEngine *
|
||||
_gtk_search_engine_new (void)
|
||||
{
|
||||
GtkSearchEngine *engine;
|
||||
|
||||
#ifdef HAVE_TRACKER
|
||||
engine = _gtk_search_engine_tracker_new ();
|
||||
if (engine)
|
||||
return engine;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BEAGLE
|
||||
engine = _gtk_search_engine_beagle_new ();
|
||||
if (engine)
|
||||
return engine;
|
||||
#endif
|
||||
|
||||
engine = _gtk_search_engine_simple_new ();
|
||||
return engine;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_search_engine_set_query (GtkSearchEngine *engine,
|
||||
GtkQuery *query)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
||||
g_return_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->set_query != NULL);
|
||||
|
||||
GTK_SEARCH_ENGINE_GET_CLASS (engine)->set_query (engine, query);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_search_engine_start (GtkSearchEngine *engine)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
||||
g_return_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->start != NULL);
|
||||
|
||||
GTK_SEARCH_ENGINE_GET_CLASS (engine)->start (engine);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_search_engine_stop (GtkSearchEngine *engine)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
||||
g_return_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->stop != NULL);
|
||||
|
||||
GTK_SEARCH_ENGINE_GET_CLASS (engine)->stop (engine);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_search_engine_is_indexed (GtkSearchEngine *engine)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_SEARCH_ENGINE (engine), FALSE);
|
||||
g_return_val_if_fail (GTK_SEARCH_ENGINE_GET_CLASS (engine)->is_indexed != NULL, FALSE);
|
||||
|
||||
return GTK_SEARCH_ENGINE_GET_CLASS (engine)->is_indexed (engine);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_search_engine_hits_added (GtkSearchEngine *engine,
|
||||
GList *hits)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
||||
|
||||
g_signal_emit (engine, signals[HITS_ADDED], 0, hits);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gtk_search_engine_hits_subtracted (GtkSearchEngine *engine,
|
||||
GList *hits)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
||||
|
||||
g_signal_emit (engine, signals[HITS_SUBTRACTED], 0, hits);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gtk_search_engine_finished (GtkSearchEngine *engine)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
||||
|
||||
g_signal_emit (engine, signals[FINISHED], 0);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_search_engine_error (GtkSearchEngine *engine,
|
||||
const gchar *error_message)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_SEARCH_ENGINE (engine));
|
||||
|
||||
g_signal_emit (engine, signals[ERROR], 0, error_message);
|
||||
}
|
91
gtk/gtksearchengine.h
Normal file
91
gtk/gtksearchengine.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Novell, Inc.
|
||||
*
|
||||
* 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: Anders Carlsson <andersca@imendio.com>
|
||||
*
|
||||
* Based on nautilus-search-engine.h
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SEARCH_ENGINE_H__
|
||||
#define __GTK_SEARCH_ENGINE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "gtkquery.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SEARCH_ENGINE (_gtk_search_engine_get_type ())
|
||||
#define GTK_SEARCH_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE, GtkSearchEngine))
|
||||
#define GTK_SEARCH_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE, GtkSearchEngineClass))
|
||||
#define GTK_IS_SEARCH_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE))
|
||||
#define GTK_IS_SEARCH_ENGINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE))
|
||||
#define GTK_SEARCH_ENGINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE, GtkSearchEngineClass))
|
||||
|
||||
typedef struct _GtkSearchEngine GtkSearchEngine;
|
||||
typedef struct _GtkSearchEngineClass GtkSearchEngineClass;
|
||||
typedef struct _GtkSearchEnginePrivate GtkSearchEnginePrivate;
|
||||
|
||||
struct _GtkSearchEngine
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GtkSearchEnginePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkSearchEngineClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* VTable */
|
||||
void (*set_query) (GtkSearchEngine *engine,
|
||||
GtkQuery *query);
|
||||
void (*start) (GtkSearchEngine *engine);
|
||||
void (*stop) (GtkSearchEngine *engine);
|
||||
gboolean (*is_indexed) (GtkSearchEngine *engine);
|
||||
|
||||
/* Signals */
|
||||
void (*hits_added) (GtkSearchEngine *engine,
|
||||
GList *hits);
|
||||
void (*hits_subtracted) (GtkSearchEngine *engine,
|
||||
GList *hits);
|
||||
void (*finished) (GtkSearchEngine *engine);
|
||||
void (*error) (GtkSearchEngine *engine,
|
||||
const gchar *error_message);
|
||||
};
|
||||
|
||||
GType _gtk_search_engine_get_type (void);
|
||||
gboolean _gtk_search_engine_enabled (void);
|
||||
|
||||
GtkSearchEngine* _gtk_search_engine_new (void);
|
||||
|
||||
void _gtk_search_engine_set_query (GtkSearchEngine *engine,
|
||||
GtkQuery *query);
|
||||
void _gtk_search_engine_start (GtkSearchEngine *engine);
|
||||
void _gtk_search_engine_stop (GtkSearchEngine *engine);
|
||||
gboolean _gtk_search_engine_is_indexed (GtkSearchEngine *engine);
|
||||
|
||||
void _gtk_search_engine_hits_added (GtkSearchEngine *engine,
|
||||
GList *hits);
|
||||
void _gtk_search_engine_hits_subtracted (GtkSearchEngine *engine,
|
||||
GList *hits);
|
||||
void _gtk_search_engine_finished (GtkSearchEngine *engine);
|
||||
void _gtk_search_engine_error (GtkSearchEngine *engine,
|
||||
const gchar *error_message);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SEARCH_ENGINE_H__ */
|
422
gtk/gtksearchenginebeagle.c
Normal file
422
gtk/gtksearchenginebeagle.c
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Novell, Inc.
|
||||
*
|
||||
* 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: Anders Carlsson <andersca@imendio.com>
|
||||
*
|
||||
* Based on nautilus-search-engine-beagle.c
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <gmodule.h>
|
||||
#include "gtksearchenginebeagle.h"
|
||||
#if 0
|
||||
#include <beagle/beagle.h>
|
||||
#endif
|
||||
|
||||
/* We dlopen() all the following from libbeagle at runtime */
|
||||
|
||||
typedef struct _BeagleHit BeagleHit;
|
||||
typedef struct _BeagleQuery BeagleQuery;
|
||||
typedef struct _BeagleClient BeagleClient;
|
||||
typedef struct _BeagleRequest BeagleRequest;
|
||||
typedef struct _BeagleFinishedResponse BeagleFinishedResponse;
|
||||
typedef struct _BeagleHitsAddedResponse BeagleHitsAddedResponse;
|
||||
typedef struct _BeagleHitsSubtractedResponse BeagleHitsSubtractedResponse;
|
||||
typedef struct _BeagleQueryPartProperty BeagleQueryPartProperty;
|
||||
typedef struct _BeagleQueryPart BeagleQueryPart;
|
||||
|
||||
#define BEAGLE_HIT(x) ((BeagleHit *)(x))
|
||||
#define BEAGLE_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_request_get_type(), BeagleRequest))
|
||||
#define BEAGLE_QUERY_PART(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_query_part_get_type(), BeagleQueryPart))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BEAGLE_QUERY_PART_LOGIC_REQUIRED = 1,
|
||||
BEAGLE_QUERY_PART_LOGIC_PROHIBITED = 2
|
||||
} BeagleQueryPartLogic;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BEAGLE_PROPERTY_TYPE_UNKNOWN = 0,
|
||||
BEAGLE_PROPERTY_TYPE_TEXT = 1,
|
||||
BEAGLE_PROPERTY_TYPE_KEYWORD = 2,
|
||||
BEAGLE_PROPERTY_TYPE_DATE = 3,
|
||||
BEAGLE_PROPERTY_TYPE_LAST = 4
|
||||
} BeaglePropertyType;
|
||||
|
||||
/* *static* wrapper function pointers */
|
||||
static gboolean (*beagle_client_send_request_async) (BeagleClient *client,
|
||||
BeagleRequest *request,
|
||||
GError **err) = NULL;
|
||||
static G_CONST_RETURN char *(*beagle_hit_get_uri) (BeagleHit *hit) = NULL;
|
||||
static GSList *(*beagle_hits_added_response_get_hits) (BeagleHitsAddedResponse *response) = NULL;
|
||||
static GSList *(*beagle_hits_subtracted_response_get_uris) (BeagleHitsSubtractedResponse *response) = NULL;
|
||||
static BeagleQuery *(*beagle_query_new) (void) = NULL;
|
||||
static void (*beagle_query_add_text) (BeagleQuery *query,
|
||||
const char *str) = NULL;
|
||||
static void (*beagle_query_add_hit_type) (BeagleQuery *query,
|
||||
const char *hit_type) = NULL;
|
||||
static void (*beagle_query_add_mime_type) (BeagleQuery *query,
|
||||
const char *mime_type) = NULL;
|
||||
static void (*beagle_query_set_max_hits) (BeagleQuery *query,
|
||||
gint max_hits) = NULL;
|
||||
static BeagleQueryPartProperty *(*beagle_query_part_property_new) (void) = NULL;
|
||||
static void (*beagle_query_part_set_logic) (BeagleQueryPart *part,
|
||||
BeagleQueryPartLogic logic) = NULL;
|
||||
static void (*beagle_query_part_property_set_key) (BeagleQueryPartProperty *part,
|
||||
const char *key) = NULL;
|
||||
static void (*beagle_query_part_property_set_value) (BeagleQueryPartProperty *part,
|
||||
const char * value) = NULL;
|
||||
static void (*beagle_query_part_property_set_property_type) (BeagleQueryPartProperty *part,
|
||||
BeaglePropertyType prop_type) = NULL;
|
||||
static void (*beagle_query_add_part) (BeagleQuery *query,
|
||||
BeagleQueryPart *part) = NULL;
|
||||
static GType (*beagle_request_get_type) (void) = NULL;
|
||||
static GType (*beagle_query_part_get_type) (void) = NULL;
|
||||
static gboolean (*beagle_util_daemon_is_running) (void) = NULL;
|
||||
static BeagleClient *(*beagle_client_new) (const char *client_name) = NULL;
|
||||
|
||||
static struct BeagleDlMapping
|
||||
{
|
||||
const char *fn_name;
|
||||
gpointer *fn_ptr_ref;
|
||||
} beagle_dl_mapping[] =
|
||||
{
|
||||
#define MAP(a) { #a, (gpointer *)&a }
|
||||
MAP (beagle_client_send_request_async),
|
||||
MAP (beagle_hit_get_uri),
|
||||
MAP (beagle_hits_added_response_get_hits),
|
||||
MAP (beagle_hits_subtracted_response_get_uris),
|
||||
MAP (beagle_query_new),
|
||||
MAP (beagle_query_add_text),
|
||||
MAP (beagle_query_add_hit_type),
|
||||
MAP (beagle_query_add_mime_type),
|
||||
MAP (beagle_query_set_max_hits),
|
||||
MAP (beagle_query_part_property_new),
|
||||
MAP (beagle_query_part_set_logic),
|
||||
MAP (beagle_query_part_property_set_key),
|
||||
MAP (beagle_query_part_property_set_value),
|
||||
MAP (beagle_query_part_property_set_property_type),
|
||||
MAP (beagle_query_add_part),
|
||||
MAP (beagle_request_get_type),
|
||||
MAP (beagle_query_part_get_type),
|
||||
MAP (beagle_util_daemon_is_running),
|
||||
MAP (beagle_client_new)
|
||||
#undef MAP
|
||||
};
|
||||
|
||||
static void
|
||||
open_libbeagle (void)
|
||||
{
|
||||
static gboolean done = FALSE;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
int i;
|
||||
GModule *beagle;
|
||||
|
||||
done = TRUE;
|
||||
|
||||
beagle = g_module_open ("libbeagle.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
if (!beagle)
|
||||
return;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++)
|
||||
{
|
||||
if (!g_module_symbol (beagle, beagle_dl_mapping[i].fn_name,
|
||||
beagle_dl_mapping[i].fn_ptr_ref))
|
||||
{
|
||||
g_warning ("Missing symbol '%s' in libbeagle\n",
|
||||
beagle_dl_mapping[i].fn_name);
|
||||
g_module_close (beagle);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++)
|
||||
beagle_dl_mapping[i].fn_ptr_ref = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct _GtkSearchEngineBeaglePrivate
|
||||
{
|
||||
BeagleClient *client;
|
||||
GtkQuery *query;
|
||||
|
||||
BeagleQuery *current_query;
|
||||
char *current_query_uri_prefix;
|
||||
gboolean query_finished;
|
||||
};
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkSearchEngineBeagle, _gtk_search_engine_beagle, GTK_TYPE_SEARCH_ENGINE);
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
GtkSearchEngineBeagle *beagle;
|
||||
|
||||
beagle = GTK_SEARCH_ENGINE_BEAGLE (object);
|
||||
|
||||
if (beagle->priv->current_query)
|
||||
{
|
||||
g_object_unref (beagle->priv->current_query);
|
||||
beagle->priv->current_query = NULL;
|
||||
g_free (beagle->priv->current_query_uri_prefix);
|
||||
beagle->priv->current_query_uri_prefix = NULL;
|
||||
}
|
||||
|
||||
if (beagle->priv->query)
|
||||
{
|
||||
g_object_unref (beagle->priv->query);
|
||||
beagle->priv->query = NULL;
|
||||
}
|
||||
|
||||
if (beagle->priv->client)
|
||||
{
|
||||
g_object_unref (beagle->priv->client);
|
||||
beagle->priv->client = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (_gtk_search_engine_beagle_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
beagle_hits_added (BeagleQuery *query,
|
||||
BeagleHitsAddedResponse *response,
|
||||
GtkSearchEngineBeagle *engine)
|
||||
{
|
||||
GSList *hits, *list;
|
||||
GList *hit_uris;
|
||||
const gchar *uri;
|
||||
|
||||
hit_uris = NULL;
|
||||
|
||||
hits = beagle_hits_added_response_get_hits (response);
|
||||
|
||||
for (list = hits; list != NULL; list = list->next)
|
||||
{
|
||||
BeagleHit *hit = BEAGLE_HIT (list->data);
|
||||
|
||||
uri = beagle_hit_get_uri (hit);
|
||||
|
||||
if (engine->priv->current_query_uri_prefix &&
|
||||
!g_str_has_prefix (uri, engine->priv->current_query_uri_prefix))
|
||||
continue;
|
||||
|
||||
hit_uris = g_list_prepend (hit_uris, (char *)uri);
|
||||
}
|
||||
|
||||
_gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (engine), hit_uris);
|
||||
g_list_free (hit_uris);
|
||||
}
|
||||
|
||||
static void
|
||||
beagle_hits_subtracted (BeagleQuery *query,
|
||||
BeagleHitsSubtractedResponse *response,
|
||||
GtkSearchEngineBeagle *engine)
|
||||
{
|
||||
GSList *uris, *list;
|
||||
GList *hit_uris;
|
||||
|
||||
hit_uris = NULL;
|
||||
|
||||
uris = beagle_hits_subtracted_response_get_uris (response);
|
||||
|
||||
for (list = uris; list != NULL; list = list->next)
|
||||
{
|
||||
hit_uris = g_list_prepend (hit_uris, (char *)list->data);
|
||||
}
|
||||
|
||||
_gtk_search_engine_hits_subtracted (GTK_SEARCH_ENGINE (engine), hit_uris);
|
||||
g_list_free (hit_uris);
|
||||
}
|
||||
|
||||
static void
|
||||
beagle_finished (BeagleQuery *query,
|
||||
BeagleFinishedResponse *response,
|
||||
GtkSearchEngineBeagle *engine)
|
||||
{
|
||||
/* For some reason we keep getting finished events,
|
||||
* only emit finished once */
|
||||
if (engine->priv->query_finished)
|
||||
return;
|
||||
|
||||
engine->priv->query_finished = TRUE;
|
||||
_gtk_search_engine_finished (GTK_SEARCH_ENGINE (engine));
|
||||
}
|
||||
|
||||
static void
|
||||
beagle_error (BeagleQuery *query,
|
||||
GError *error,
|
||||
GtkSearchEngineBeagle *engine)
|
||||
{
|
||||
_gtk_search_engine_error (GTK_SEARCH_ENGINE (engine), error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_search_engine_beagle_start (GtkSearchEngine *engine)
|
||||
{
|
||||
GtkSearchEngineBeagle *beagle;
|
||||
GError *error;
|
||||
GList *mimetypes, *l;
|
||||
gchar *text, *mimetype;
|
||||
|
||||
error = NULL;
|
||||
beagle = GTK_SEARCH_ENGINE_BEAGLE (engine);
|
||||
|
||||
g_return_if_fail (beagle->priv->query != NULL);
|
||||
|
||||
if (beagle->priv->current_query)
|
||||
return;
|
||||
|
||||
beagle->priv->query_finished = FALSE;
|
||||
beagle->priv->current_query = beagle_query_new ();
|
||||
g_signal_connect (beagle->priv->current_query,
|
||||
"hits-added", G_CALLBACK (beagle_hits_added), engine);
|
||||
g_signal_connect (beagle->priv->current_query,
|
||||
"hits-subtracted", G_CALLBACK (beagle_hits_subtracted), engine);
|
||||
g_signal_connect (beagle->priv->current_query,
|
||||
"finished", G_CALLBACK (beagle_finished), engine);
|
||||
g_signal_connect (beagle->priv->current_query,
|
||||
"error", G_CALLBACK (beagle_error), engine);
|
||||
|
||||
/* We only want files */
|
||||
beagle_query_add_hit_type (beagle->priv->current_query,
|
||||
"File");
|
||||
beagle_query_set_max_hits (beagle->priv->current_query,
|
||||
1000);
|
||||
|
||||
text = _gtk_query_get_text (beagle->priv->query);
|
||||
beagle_query_add_text (beagle->priv->current_query,
|
||||
text);
|
||||
|
||||
mimetypes = _gtk_query_get_mime_types (beagle->priv->query);
|
||||
for (l = mimetypes; l != NULL; l = l->next)
|
||||
{
|
||||
mimetype = l->data;
|
||||
beagle_query_add_mime_type (beagle->priv->current_query, mimetype);
|
||||
}
|
||||
|
||||
beagle->priv->current_query_uri_prefix = _gtk_query_get_location (beagle->priv->query);
|
||||
|
||||
if (!beagle_client_send_request_async (beagle->priv->client,
|
||||
BEAGLE_REQUEST (beagle->priv->current_query), &error))
|
||||
{
|
||||
_gtk_search_engine_error (engine, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
/* These must live during the lifetime of the query */
|
||||
g_free (text);
|
||||
g_list_foreach (mimetypes, (GFunc)g_free, NULL);
|
||||
g_list_free (mimetypes);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_search_engine_beagle_stop (GtkSearchEngine *engine)
|
||||
{
|
||||
GtkSearchEngineBeagle *beagle;
|
||||
|
||||
beagle = GTK_SEARCH_ENGINE_BEAGLE (engine);
|
||||
|
||||
if (beagle->priv->current_query)
|
||||
{
|
||||
g_object_unref (beagle->priv->current_query);
|
||||
beagle->priv->current_query = NULL;
|
||||
g_free (beagle->priv->current_query_uri_prefix);
|
||||
beagle->priv->current_query_uri_prefix = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_search_engine_beagle_is_indexed (GtkSearchEngine *engine)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_search_engine_beagle_set_query (GtkSearchEngine *engine,
|
||||
GtkQuery *query)
|
||||
{
|
||||
GtkSearchEngineBeagle *beagle;
|
||||
|
||||
beagle = GTK_SEARCH_ENGINE_BEAGLE (engine);
|
||||
|
||||
if (query)
|
||||
g_object_ref (query);
|
||||
|
||||
if (beagle->priv->query)
|
||||
g_object_unref (beagle->priv->query);
|
||||
|
||||
beagle->priv->query = query;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_search_engine_beagle_class_init (GtkSearchEngineBeagleClass *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_beagle_set_query;
|
||||
engine_class->start = gtk_search_engine_beagle_start;
|
||||
engine_class->stop = gtk_search_engine_beagle_stop;
|
||||
engine_class->is_indexed = gtk_search_engine_beagle_is_indexed;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (GtkSearchEngineBeaglePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_search_engine_beagle_init (GtkSearchEngineBeagle *engine)
|
||||
{
|
||||
engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeaglePrivate);
|
||||
}
|
||||
|
||||
|
||||
GtkSearchEngine *
|
||||
_gtk_search_engine_beagle_new (void)
|
||||
{
|
||||
GtkSearchEngineBeagle *engine;
|
||||
BeagleClient *client;
|
||||
|
||||
open_libbeagle ();
|
||||
|
||||
if (!beagle_util_daemon_is_running)
|
||||
return NULL;
|
||||
|
||||
/* check whether daemon is running as beagle_client_new
|
||||
* doesn't fail when a stale socket file exists */
|
||||
if (!beagle_util_daemon_is_running ())
|
||||
return NULL;
|
||||
|
||||
client = beagle_client_new (NULL);
|
||||
|
||||
if (client == NULL)
|
||||
return NULL;
|
||||
|
||||
engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_BEAGLE, NULL);
|
||||
|
||||
engine->priv->client = client;
|
||||
|
||||
return GTK_SEARCH_ENGINE (engine);
|
||||
}
|
59
gtk/gtksearchenginebeagle.h
Normal file
59
gtk/gtksearchenginebeagle.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Novell, Inc.
|
||||
*
|
||||
* 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: Anders Carlsson <andersca@imendio.com>
|
||||
*
|
||||
* Based on nautilus-search-engine-beagle.h
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SEARCH_ENGINE_BEAGLE_H__
|
||||
#define __GTK_SEARCH_ENGINE_BEAGLE_H__
|
||||
|
||||
#include "gtksearchengine.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SEARCH_ENGINE_BEAGLE (_gtk_search_engine_beagle_get_type ())
|
||||
#define GTK_SEARCH_ENGINE_BEAGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeagle))
|
||||
#define GTK_SEARCH_ENGINE_BEAGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeagleClass))
|
||||
#define GTK_IS_SEARCH_ENGINE_BEAGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE_BEAGLE))
|
||||
#define GTK_IS_SEARCH_ENGINE_BEAGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE_BEAGLE))
|
||||
#define GTK_SEARCH_ENGINE_BEAGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE_BEAGLE, GtkSearchEngineBeagleClass))
|
||||
|
||||
typedef struct _GtkSearchEngineBeagle GtkSearchEngineBeagle;
|
||||
typedef struct _GtkSearchEngineBeagleClass GtkSearchEngineBeagleClass;
|
||||
typedef struct _GtkSearchEngineBeaglePrivate GtkSearchEngineBeaglePrivate;
|
||||
|
||||
struct _GtkSearchEngineBeagle
|
||||
{
|
||||
GtkSearchEngine parent;
|
||||
|
||||
GtkSearchEngineBeaglePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkSearchEngineBeagleClass
|
||||
{
|
||||
GtkSearchEngineClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_search_engine_beagle_get_type (void);
|
||||
|
||||
GtkSearchEngine* _gtk_search_engine_beagle_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SEARCH_ENGINE_BEAGLE_H__ */
|
378
gtk/gtksearchenginesimple.c
Normal file
378
gtk/gtksearchenginesimple.c
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Red Hat, Inc
|
||||
*
|
||||
* 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: Alexander Larsson <alexl@redhat.com>
|
||||
*
|
||||
* Based on nautilus-search-engine-simple.c
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 500
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <config.h>
|
||||
#include "gtksearchenginesimple.h"
|
||||
|
||||
#define XDG_PREFIX _gtk_xdg
|
||||
#include "xdgmime/xdgmime.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ftw.h>
|
||||
#include <glib/gstrfuncs.h>
|
||||
|
||||
#define BATCH_SIZE 500
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkSearchEngineSimple *engine;
|
||||
|
||||
gchar *path;
|
||||
GList *mime_types;
|
||||
gchar **words;
|
||||
GList *found_list;
|
||||
|
||||
gint n_processed_files;
|
||||
GList *uri_hits;
|
||||
|
||||
/* accessed on both threads: */
|
||||
volatile gboolean cancelled;
|
||||
} SearchThreadData;
|
||||
|
||||
|
||||
struct _GtkSearchEngineSimplePrivate
|
||||
{
|
||||
GtkQuery *query;
|
||||
|
||||
SearchThreadData *active_search;
|
||||
|
||||
gboolean query_finished;
|
||||
};
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkSearchEngineSimple, _gtk_search_engine_simple, GTK_TYPE_SEARCH_ENGINE);
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
GtkSearchEngineSimple *simple;
|
||||
|
||||
simple = GTK_SEARCH_ENGINE_SIMPLE (object);
|
||||
|
||||
if (simple->priv->query)
|
||||
{
|
||||
g_object_unref (simple->priv->query);
|
||||
simple->priv->query = NULL;
|
||||
}
|
||||
|
||||
g_free (simple->priv);
|
||||
|
||||
G_OBJECT_CLASS (_gtk_search_engine_simple_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static SearchThreadData *
|
||||
search_thread_data_new (GtkSearchEngineSimple *engine,
|
||||
GtkQuery *query)
|
||||
{
|
||||
SearchThreadData *data;
|
||||
char *text, *lower, *uri;
|
||||
|
||||
data = g_new0 (SearchThreadData, 1);
|
||||
|
||||
data->engine = engine;
|
||||
uri = _gtk_query_get_location (query);
|
||||
if (uri != NULL)
|
||||
{
|
||||
data->path = g_filename_from_uri (uri, NULL, NULL);
|
||||
g_free (uri);
|
||||
}
|
||||
if (data->path == NULL)
|
||||
data->path = g_strdup (g_get_home_dir ());
|
||||
|
||||
text = _gtk_query_get_text (query);
|
||||
lower = g_ascii_strdown (text, -1);
|
||||
data->words = g_strsplit (lower, " ", -1);
|
||||
g_free (text);
|
||||
g_free (lower);
|
||||
|
||||
data->mime_types = _gtk_query_get_mime_types (query);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
search_thread_data_free (SearchThreadData *data)
|
||||
{
|
||||
g_free (data->path);
|
||||
g_strfreev (data->words);
|
||||
g_list_foreach (data->mime_types, (GFunc)g_free, NULL);
|
||||
g_list_free (data->mime_types);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
search_thread_done_idle (gpointer user_data)
|
||||
{
|
||||
SearchThreadData *data;
|
||||
|
||||
data = user_data;
|
||||
|
||||
if (!data->cancelled)
|
||||
{
|
||||
_gtk_search_engine_finished (GTK_SEARCH_ENGINE (data->engine));
|
||||
data->engine->priv->active_search = NULL;
|
||||
}
|
||||
|
||||
search_thread_data_free (data);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GList *uris;
|
||||
SearchThreadData *thread_data;
|
||||
} SearchHits;
|
||||
|
||||
|
||||
static gboolean
|
||||
search_thread_add_hits_idle (gpointer user_data)
|
||||
{
|
||||
SearchHits *hits;
|
||||
|
||||
hits = user_data;
|
||||
|
||||
if (!hits->thread_data->cancelled)
|
||||
{
|
||||
_gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (hits->thread_data->engine),
|
||||
hits->uris);
|
||||
}
|
||||
|
||||
g_list_foreach (hits->uris, (GFunc)g_free, NULL);
|
||||
g_list_free (hits->uris);
|
||||
g_free (hits);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
send_batch (SearchThreadData *data)
|
||||
{
|
||||
SearchHits *hits;
|
||||
|
||||
data->n_processed_files = 0;
|
||||
|
||||
if (data->uri_hits)
|
||||
{
|
||||
hits = g_new (SearchHits, 1);
|
||||
hits->uris = data->uri_hits;
|
||||
hits->thread_data = data;
|
||||
g_idle_add (search_thread_add_hits_idle, hits);
|
||||
}
|
||||
data->uri_hits = NULL;
|
||||
}
|
||||
|
||||
static GStaticPrivate search_thread_data = G_STATIC_PRIVATE_INIT;
|
||||
|
||||
static int
|
||||
search_visit_func (const char *fpath,
|
||||
const struct stat *sb,
|
||||
int typeflag,
|
||||
struct FTW *ftwbuf)
|
||||
{
|
||||
SearchThreadData *data;
|
||||
gint i;
|
||||
const gchar *name;
|
||||
gchar *lower_name, *path, *mime_type;
|
||||
gchar *uri;
|
||||
gboolean hit;
|
||||
GList *l;
|
||||
gboolean is_hidden;
|
||||
|
||||
data = (SearchThreadData*)g_static_private_get (&search_thread_data);
|
||||
|
||||
if (data->cancelled)
|
||||
return FTW_STOP;
|
||||
|
||||
name = strrchr (fpath, '/');
|
||||
if (name)
|
||||
name++;
|
||||
else
|
||||
name = fpath;
|
||||
|
||||
path = g_build_filename (data->path, fpath, NULL);
|
||||
|
||||
is_hidden = *name == '.';
|
||||
|
||||
hit = FALSE;
|
||||
|
||||
if (!is_hidden)
|
||||
{
|
||||
lower_name = g_ascii_strdown (name, -1);
|
||||
|
||||
hit = TRUE;
|
||||
for (i = 0; data->words[i] != NULL; i++)
|
||||
{
|
||||
if (strstr (lower_name, data->words[i]) == NULL)
|
||||
{
|
||||
hit = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_free (lower_name);
|
||||
}
|
||||
|
||||
if (hit && data->mime_types != NULL)
|
||||
{
|
||||
hit = FALSE;
|
||||
mime_type = xdg_mime_get_mime_type_for_file (path, (struct stat *)sb);
|
||||
for (l = data->mime_types; l != NULL; l = l->next)
|
||||
{
|
||||
if (strcmp (mime_type, l->data) == 0)
|
||||
{
|
||||
hit = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (mime_type);
|
||||
}
|
||||
|
||||
if (hit)
|
||||
{
|
||||
uri = g_filename_to_uri (path, NULL, NULL);
|
||||
data->uri_hits = g_list_prepend (data->uri_hits, uri);
|
||||
}
|
||||
|
||||
data->n_processed_files++;
|
||||
|
||||
if (data->n_processed_files > BATCH_SIZE)
|
||||
send_batch (data);
|
||||
|
||||
if (is_hidden)
|
||||
return FTW_SKIP_SUBTREE;
|
||||
else
|
||||
return FTW_CONTINUE;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
search_thread_func (gpointer user_data)
|
||||
{
|
||||
SearchThreadData *data;
|
||||
|
||||
data = user_data;
|
||||
|
||||
g_static_private_set (&search_thread_data, data, NULL);
|
||||
|
||||
nftw (data->path, search_visit_func, 20, FTW_ACTIONRETVAL | FTW_PHYS);
|
||||
|
||||
send_batch (data);
|
||||
|
||||
g_idle_add (search_thread_done_idle, data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_search_engine_simple_start (GtkSearchEngine *engine)
|
||||
{
|
||||
GtkSearchEngineSimple *simple;
|
||||
SearchThreadData *data;
|
||||
|
||||
simple = GTK_SEARCH_ENGINE_SIMPLE (engine);
|
||||
|
||||
if (simple->priv->active_search != NULL)
|
||||
return;
|
||||
|
||||
if (simple->priv->query == NULL)
|
||||
return;
|
||||
|
||||
data = search_thread_data_new (simple, simple->priv->query);
|
||||
|
||||
g_thread_create (search_thread_func, data, FALSE, NULL);
|
||||
|
||||
simple->priv->active_search = data;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_search_engine_simple_stop (GtkSearchEngine *engine)
|
||||
{
|
||||
GtkSearchEngineSimple *simple;
|
||||
|
||||
simple = GTK_SEARCH_ENGINE_SIMPLE (engine);
|
||||
|
||||
if (simple->priv->active_search != NULL)
|
||||
{
|
||||
simple->priv->active_search->cancelled = TRUE;
|
||||
simple->priv->active_search = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_search_engine_simple_is_indexed (GtkSearchEngine *engine)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_search_engine_simple_set_query (GtkSearchEngine *engine,
|
||||
GtkQuery *query)
|
||||
{
|
||||
GtkSearchEngineSimple *simple;
|
||||
|
||||
simple = GTK_SEARCH_ENGINE_SIMPLE (engine);
|
||||
|
||||
if (query)
|
||||
g_object_ref (query);
|
||||
|
||||
if (simple->priv->query)
|
||||
g_object_unref (simple->priv->query);
|
||||
|
||||
simple->priv->query = query;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_search_engine_simple_class_init (GtkSearchEngineSimpleClass *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_simple_set_query;
|
||||
engine_class->start = gtk_search_engine_simple_start;
|
||||
engine_class->stop = gtk_search_engine_simple_stop;
|
||||
engine_class->is_indexed = gtk_search_engine_simple_is_indexed;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (GtkSearchEngineSimplePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_search_engine_simple_init (GtkSearchEngineSimple *engine)
|
||||
{
|
||||
engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimplePrivate);
|
||||
}
|
||||
|
||||
GtkSearchEngine *
|
||||
_gtk_search_engine_simple_new (void)
|
||||
{
|
||||
GtkSearchEngine *engine;
|
||||
|
||||
engine = g_object_new (GTK_TYPE_SEARCH_ENGINE_SIMPLE, NULL);
|
||||
|
||||
return engine;
|
||||
}
|
59
gtk/gtksearchenginesimple.h
Normal file
59
gtk/gtksearchenginesimple.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Red Hat, Inc
|
||||
*
|
||||
* 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: Alexander Larsson <alexl@redhat.com>
|
||||
*
|
||||
* Based on nautilus-search-engine-simple.h
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SEARCH_ENGINE_SIMPLE_H__
|
||||
#define __GTK_SEARCH_ENGINE_SIMPLE_H__
|
||||
|
||||
#include "gtksearchengine.h"
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#define GTK_TYPE_SEARCH_ENGINE_SIMPLE (_gtk_search_engine_simple_get_type ())
|
||||
#define GTK_SEARCH_ENGINE_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimple))
|
||||
#define GTK_SEARCH_ENGINE_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimpleClass))
|
||||
#define GTK_IS_SEARCH_ENGINE_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE_SIMPLE))
|
||||
#define GTK_IS_SEARCH_ENGINE_SIMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE_SIMPLE))
|
||||
#define GTK_SEARCH_ENGINE_SIMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE_SIMPLE, GtkSearchEngineSimpleClass))
|
||||
|
||||
typedef struct _GtkSearchEngineSimple GtkSearchEngineSimple;
|
||||
typedef struct _GtkSearchEngineSimpleClass GtkSearchEngineSimpleClass;
|
||||
typedef struct _GtkSearchEngineSimplePrivate GtkSearchEngineSimplePrivate;
|
||||
|
||||
struct _GtkSearchEngineSimple
|
||||
{
|
||||
GtkSearchEngine parent;
|
||||
|
||||
GtkSearchEngineSimplePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkSearchEngineSimpleClass
|
||||
{
|
||||
GtkSearchEngineClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_search_engine_simple_get_type (void);
|
||||
|
||||
GtkSearchEngine* _gtk_search_engine_simple_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SEARCH_ENGINE_SIMPLE_H__ */
|
362
gtk/gtksearchenginetracker.c
Normal file
362
gtk/gtksearchenginetracker.c
Normal file
@ -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);
|
||||
}
|
59
gtk/gtksearchenginetracker.h
Normal file
59
gtk/gtksearchenginetracker.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.h
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SEARCH_ENGINE_TRACKER_H__
|
||||
#define __GTK_SEARCH_ENGINE_TRACKER_H__
|
||||
|
||||
#include "gtksearchengine.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SEARCH_ENGINE_TRACKER (_gtk_search_engine_tracker_get_type ())
|
||||
#define GTK_SEARCH_ENGINE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTracker))
|
||||
#define GTK_SEARCH_ENGINE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTrackerClass))
|
||||
#define GTK_IS_SEARCH_ENGINE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEARCH_ENGINE_TRACKER))
|
||||
#define GTK_IS_SEARCH_ENGINE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SEARCH_ENGINE_TRACKER))
|
||||
#define GTK_SEARCH_ENGINE_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SEARCH_ENGINE_TRACKER, GtkSearchEngineTrackerClass))
|
||||
|
||||
typedef struct _GtkSearchEngineTracker GtkSearchEngineTracker;
|
||||
typedef struct _GtkSearchEngineTrackerClass GtkSearchEngineTrackerClass;
|
||||
typedef struct _GtkSearchEngineTrackerPrivate GtkSearchEngineTrackerPrivate;
|
||||
|
||||
struct _GtkSearchEngineTracker
|
||||
{
|
||||
GtkSearchEngine parent;
|
||||
|
||||
GtkSearchEngineTrackerPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkSearchEngineTrackerClass
|
||||
{
|
||||
GtkSearchEngineClass parent_class;
|
||||
};
|
||||
|
||||
GType _gtk_search_engine_tracker_get_type (void);
|
||||
|
||||
GtkSearchEngine* _gtk_search_engine_tracker_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SEARCH_ENGINE_TRACKER_H__ */
|
Loading…
Reference in New Issue
Block a user