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:
Emmanuele Bassi 2007-05-02 22:51:43 +00:00 committed by Emmanuele Bassi
parent e82e337ee9
commit d3aeccf774
14 changed files with 3088 additions and 330 deletions

View File

@ -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

View File

@ -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

View File

@ -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
View 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
View 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
View 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
View 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
View 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);
}

View 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
View 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;
}

View 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__ */

View 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);
}

View 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__ */