gtk2/gtk/gtksearchenginesimple.c
Emmanuele Bassi 477067ee43 Remove the MIME type calls and queries from the search engine
2007-06-22  Emmanuele Bassi  <ebassi@gnome.org>

	* gtk/gtksearchenginebeagle.c:
	* gtk/gtksearchenginesimple.c:
	* gtk/gtksearchenginetracker.c: Remove the MIME type calls and
	queries from the search engine implementations, since we use our
	own GtkFileSystem to filter out basing on MIME types and we cannot
	query MIME types anyway. The GtkQuery private object still has
	MIME type, as well as location, support for future expansion.

svn path=/trunk/; revision=18219
2007-06-22 14:32:22 +00:00

377 lines
7.8 KiB
C

/*
* 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
*/
#include <config.h>
/* these must be defined even when HAVE_GNU_FTW is not defined
* because (really) old versions of GNU libc have ftw.h but do
* export ftw() and friends only if _XOPEN_SOURCE and _GNU_SOURCE
* are defined. see bug #444097.
*/
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE
#ifdef HAVE_FTW_H
#include <ftw.h>
#endif
#include "gtksearchenginesimple.h"
#include <string.h>
#include <glib/gstrfuncs.h>
#define BATCH_SIZE 500
typedef struct
{
GtkSearchEngineSimple *engine;
gchar *path;
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_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);
return data;
}
static void
search_thread_data_free (SearchThreadData *data)
{
g_free (data->path);
g_strfreev (data->words);
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;
#ifdef HAVE_FTW_H
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;
gchar *uri;
gboolean hit;
GList *l;
gboolean is_hidden;
data = (SearchThreadData*)g_static_private_get (&search_thread_data);
if (data->cancelled)
#ifdef HAVE_GNU_FTW
return FTW_STOP;
#else
return 1;
#endif /* HAVE_GNU_FTW */
name = strrchr (fpath, '/');
if (name)
name++;
else
name = fpath;
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)
{
uri = g_filename_to_uri (fpath, 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);
#ifdef HAVE_GNU_FTW
if (is_hidden)
return FTW_SKIP_SUBTREE;
else
return FTW_CONTINUE;
#else
return 0;
#endif /* HAVE_GNU_FTW */
}
#endif /* HAVE_FTW_H */
static gpointer
search_thread_func (gpointer user_data)
{
#ifdef HAVE_FTW_H
SearchThreadData *data;
data = user_data;
g_static_private_set (&search_thread_data, data, NULL);
nftw (data->path, search_visit_func, 20,
#ifdef HAVE_GNU_FTW
FTW_ACTIONRETVAL |
#endif
FTW_PHYS);
send_batch (data);
g_idle_add (search_thread_done_idle, data);
#endif /* HAVE_FTW_H */
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)
{
#ifdef HAVE_FTW_H
return g_object_new (GTK_TYPE_SEARCH_ENGINE_SIMPLE, NULL);
#else
return NULL;
#endif
}