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:
		
				
					committed by
					
						
						Emmanuele Bassi
					
				
			
			
				
	
			
			
			
						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__ */
 | 
			
		||||
		Reference in New Issue
	
	Block a user