summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimoc@gnome.org>2012-10-14 13:33:01 -0400
committerCosimo Cecchi <cosimoc@gnome.org>2012-10-15 10:02:48 -0400
commitbbe59c4bb7c1d389442d00e93a7ba8482b0e102e (patch)
treedaa8504ac57744ce7be58bb5414409a70fef7a21
parent474abdb3bad65cf79b0e761d962edc8b94d51dcc (diff)
downloadnautilus-bbe59c4bb7c1d389442d00e93a7ba8482b0e102e.tar.gz
query: move string matching code in NautilusQuery
This also allows us to use a heuristic to evaluate how good the filename match is.
-rw-r--r--libnautilus-private/nautilus-query.c59
-rw-r--r--libnautilus-private/nautilus-query.h2
-rw-r--r--libnautilus-private/nautilus-search-engine-model.c30
-rw-r--r--libnautilus-private/nautilus-search-engine-simple.c51
-rw-r--r--libnautilus-private/nautilus-ui-utilities.c12
-rw-r--r--libnautilus-private/nautilus-ui-utilities.h2
-rw-r--r--src/nautilus-shell-search-provider.c30
7 files changed, 93 insertions, 93 deletions
diff --git a/libnautilus-private/nautilus-query.c b/libnautilus-private/nautilus-query.c
index 2b78213c7..107adbd21 100644
--- a/libnautilus-private/nautilus-query.c
+++ b/libnautilus-private/nautilus-query.c
@@ -35,6 +35,8 @@ struct NautilusQueryDetails {
char *location_uri;
GList *mime_types;
gboolean show_hidden;
+
+ char **prepared_words;
};
static void nautilus_query_class_init (NautilusQueryClass *class);
@@ -49,6 +51,7 @@ finalize (GObject *object)
query = NAUTILUS_QUERY (object);
g_free (query->details->text);
+ g_strfreev (query->details->prepared_words);
g_free (query->details->location_uri);
G_OBJECT_CLASS (nautilus_query_parent_class)->finalize (object);
@@ -73,6 +76,59 @@ nautilus_query_init (NautilusQuery *query)
query->details->show_hidden = TRUE;
}
+static gchar *
+prepare_string_for_compare (const gchar *string)
+{
+ gchar *normalized, *res;
+
+ normalized = g_utf8_normalize (string, -1, G_NORMALIZE_NFD);
+ res = g_utf8_strdown (normalized, -1);
+ g_free (normalized);
+
+ return res;
+}
+
+gdouble
+nautilus_query_matches_string (NautilusQuery *query,
+ const gchar *string)
+{
+ gchar *prepared_string, *ptr;
+ gboolean found;
+ gdouble retval;
+ gint idx;
+
+ if (!query->details->text) {
+ return -1;
+ }
+
+ if (!query->details->prepared_words) {
+ prepared_string = prepare_string_for_compare (query->details->text);
+ query->details->prepared_words = g_strsplit (prepared_string, " ", -1);
+ g_free (prepared_string);
+ }
+
+ prepared_string = prepare_string_for_compare (string);
+ found = TRUE;
+ ptr = NULL;
+
+ for (idx = 0; query->details->prepared_words[idx] != NULL; idx++) {
+ if ((ptr = strstr (prepared_string, query->details->prepared_words[idx])) == NULL) {
+ found = FALSE;
+ break;
+ }
+ }
+
+ if (!found) {
+ g_free (prepared_string);
+ return -1;
+ }
+
+ retval = MAX (10.0, (50.0 / idx) - (gdouble) (ptr - prepared_string));
+ g_free (prepared_string);
+
+ return retval;
+}
+
NautilusQuery *
nautilus_query_new (void)
{
@@ -91,6 +147,9 @@ nautilus_query_set_text (NautilusQuery *query, const char *text)
{
g_free (query->details->text);
query->details->text = g_strstrip (g_strdup (text));
+
+ g_strfreev (query->details->prepared_words);
+ query->details->prepared_words = NULL;
}
char *
diff --git a/libnautilus-private/nautilus-query.h b/libnautilus-private/nautilus-query.h
index 4c2e52bca..f48270006 100644
--- a/libnautilus-private/nautilus-query.h
+++ b/libnautilus-private/nautilus-query.h
@@ -61,6 +61,8 @@ GList * nautilus_query_get_mime_types (NautilusQuery *query);
void nautilus_query_set_mime_types (NautilusQuery *query, GList *mime_types);
void nautilus_query_add_mime_type (NautilusQuery *query, const char *mime_type);
+gdouble nautilus_query_matches_string (NautilusQuery *query, const gchar *string);
+
char * nautilus_query_to_readable_string (NautilusQuery *query);
NautilusQuery *nautilus_query_load (char *file);
gboolean nautilus_query_save (NautilusQuery *query, char *file);
diff --git a/libnautilus-private/nautilus-search-engine-model.c b/libnautilus-private/nautilus-search-engine-model.c
index dadfe3abb..3a57f2b9a 100644
--- a/libnautilus-private/nautilus-search-engine-model.c
+++ b/libnautilus-private/nautilus-search-engine-model.c
@@ -88,48 +88,34 @@ emit_finished_idle_cb (gpointer user_data)
return FALSE;
}
-static gchar *
-prepare_pattern_for_comparison (NautilusSearchEngineModel *model)
-{
- gchar *text, *prepared, *pattern;
-
- text = nautilus_query_get_text (model->details->query);
- prepared = nautilus_search_prepare_string_for_compare (text);
- pattern = g_strdup_printf ("*%s*", prepared);
-
- g_free (prepared);
- g_free (text);
-
- return pattern;
-}
-
static void
model_directory_ready_cb (NautilusDirectory *directory,
GList *list,
gpointer user_data)
{
NautilusSearchEngineModel *model = user_data;
- gchar *uri, *pattern;
- gchar *display_name, *prepared;
+ gchar *uri, *display_name;
GList *files, *l, *hits;
NautilusFile *file;
+ gdouble match;
+ NautilusSearchHit *hit;
- pattern = prepare_pattern_for_comparison (model);
files = nautilus_directory_get_file_list (directory);
hits = NULL;
for (l = files; l != NULL; l = l->next) {
file = l->data;
display_name = nautilus_file_get_display_name (file);
- prepared = nautilus_search_prepare_string_for_compare (display_name);
+ match = nautilus_query_matches_string (model->details->query, display_name);
- if (g_pattern_match_simple (pattern, prepared)) {
+ if (match > -1) {
uri = nautilus_file_get_uri (file);
- hits = g_list_prepend (hits, nautilus_search_hit_new (uri));
+ hit = nautilus_search_hit_new (uri);
+ nautilus_search_hit_set_fts_rank (hit, match);
+ hits = g_list_prepend (hits, hit);
g_free (uri);
}
- g_free (prepared);
g_free (display_name);
}
diff --git a/libnautilus-private/nautilus-search-engine-simple.c b/libnautilus-private/nautilus-search-engine-simple.c
index bdcaf3db0..4e7a8f71b 100644
--- a/libnautilus-private/nautilus-search-engine-simple.c
+++ b/libnautilus-private/nautilus-search-engine-simple.c
@@ -43,7 +43,6 @@ typedef struct {
GCancellable *cancellable;
GList *mime_types;
- char **words;
GList *found_list;
GQueue *directories; /* GFiles */
@@ -53,6 +52,8 @@ typedef struct {
gboolean recursive;
gint n_processed_files;
GList *hits;
+
+ NautilusQuery *query;
} SearchThreadData;
@@ -91,7 +92,7 @@ search_thread_data_new (NautilusSearchEngineSimple *engine,
NautilusQuery *query)
{
SearchThreadData *data;
- char *text, *prepared, *uri;
+ char *uri;
GFile *location;
data = g_new0 (SearchThreadData, 1);
@@ -99,23 +100,13 @@ search_thread_data_new (NautilusSearchEngineSimple *engine,
data->engine = g_object_ref (engine);
data->directories = g_queue_new ();
data->visited = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ data->query = g_object_ref (query);
+
uri = nautilus_query_get_location (query);
- location = NULL;
- if (uri != NULL) {
- location = g_file_new_for_uri (uri);
- g_free (uri);
- }
- if (location == NULL) {
- location = g_file_new_for_path ("/");
- }
- g_queue_push_tail (data->directories, location);
-
- text = nautilus_query_get_text (query);
- prepared = nautilus_search_prepare_string_for_compare (text);
- data->words = g_strsplit (prepared, " ", -1);
- g_free (text);
- g_free (prepared);
+ location = g_file_new_for_uri (uri);
+ g_free (uri);
+ g_queue_push_tail (data->directories, location);
data->mime_types = nautilus_query_get_mime_types (query);
data->cancellable = g_cancellable_new ();
@@ -131,7 +122,7 @@ search_thread_data_free (SearchThreadData *data)
g_queue_free (data->directories);
g_hash_table_destroy (data->visited);
g_object_unref (data->cancellable);
- g_strfreev (data->words);
+ g_object_unref (data->query);
g_list_free_full (data->mime_types, g_free);
g_list_free_full (data->hits, g_object_unref);
g_object_unref (data->engine);
@@ -205,9 +196,8 @@ visit_directory (GFile *dir, SearchThreadData *data)
GFileInfo *info;
GFile *child;
const char *mime_type, *display_name;
- char *prepared;
- gboolean found, is_hidden;
- int i;
+ gdouble match;
+ gboolean is_hidden, found;
GList *l;
const char *id;
gboolean visited;
@@ -232,21 +222,14 @@ visit_directory (GFile *dir, SearchThreadData *data)
}
is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
- if (is_hidden && !nautilus_query_get_show_hidden_files (data->engine->details->query)) {
+ if (is_hidden && !nautilus_query_get_show_hidden_files (data->query)) {
goto next;
}
- prepared = nautilus_search_prepare_string_for_compare (display_name);
+ child = g_file_get_child (dir, g_file_info_get_name (info));
+ match = nautilus_query_matches_string (data->query, display_name);
+ found = (match > -1);
- found = TRUE;
- for (i = 0; data->words[i] != NULL; i++) {
- if (strstr (prepared, data->words[i]) == NULL) {
- found = FALSE;
- break;
- }
- }
- g_free (prepared);
-
if (found && data->mime_types) {
mime_type = g_file_info_get_content_type (info);
found = FALSE;
@@ -259,8 +242,6 @@ visit_directory (GFile *dir, SearchThreadData *data)
}
}
- child = g_file_get_child (dir, g_file_info_get_name (info));
-
if (found) {
NautilusSearchHit *hit;
GTimeVal tv;
@@ -270,7 +251,7 @@ visit_directory (GFile *dir, SearchThreadData *data)
uri = g_file_get_uri (child);
hit = nautilus_search_hit_new (uri);
g_free (uri);
- nautilus_search_hit_set_fts_rank (hit, 10.0);
+ nautilus_search_hit_set_fts_rank (hit, match);
g_file_info_get_modification_time (info, &tv);
dt = g_date_time_new_from_timeval_local (&tv);
nautilus_search_hit_set_modification_time (hit, dt);
diff --git a/libnautilus-private/nautilus-ui-utilities.c b/libnautilus-private/nautilus-ui-utilities.c
index b70a01f87..539ddca70 100644
--- a/libnautilus-private/nautilus-ui-utilities.c
+++ b/libnautilus-private/nautilus-ui-utilities.c
@@ -61,18 +61,6 @@ nautilus_ui_prepare_merge_ui (GtkUIManager *ui_manager,
g_object_unref (*action_group); /* owned by ui manager */
}
-gchar *
-nautilus_search_prepare_string_for_compare (const gchar *string)
-{
- gchar *normalized, *res;
-
- normalized = g_utf8_normalize (string, -1, G_NORMALIZE_NFD);
- res = g_utf8_strdown (normalized, -1);
- g_free (normalized);
-
- return res;
-}
-
static void
extension_action_callback (GtkAction *action,
gpointer callback_data)
diff --git a/libnautilus-private/nautilus-ui-utilities.h b/libnautilus-private/nautilus-ui-utilities.h
index 9020a1251..12e2e5e5a 100644
--- a/libnautilus-private/nautilus-ui-utilities.h
+++ b/libnautilus-private/nautilus-ui-utilities.h
@@ -36,8 +36,6 @@ void nautilus_ui_prepare_merge_ui (GtkUIManager *ui_manage
GtkActionGroup **action_group);
GtkAction * nautilus_action_from_menu_item (NautilusMenuItem *item);
-gchar * nautilus_search_prepare_string_for_compare (const gchar *string);
-
GdkPixbuf * nautilus_ui_get_menu_icon (const char *icon_name);
char * nautilus_escape_action_name (const char *action_name,
diff --git a/src/nautilus-shell-search-provider.c b/src/nautilus-shell-search-provider.c
index 649ea159a..fc0c6551d 100644
--- a/src/nautilus-shell-search-provider.c
+++ b/src/nautilus-shell-search-provider.c
@@ -298,7 +298,7 @@ search_hit_candidate_new (const gchar *uri,
SearchHitCandidate *candidate = g_slice_new0 (SearchHitCandidate);
candidate->uri = g_strdup (uri);
- candidate->string_for_compare = nautilus_search_prepare_string_for_compare (name);
+ candidate->string_for_compare = g_strdup (name);
return candidate;
}
@@ -309,10 +309,9 @@ search_add_volumes_and_bookmarks (NautilusShellSearchProviderApp *self)
NautilusSearchHit *hit;
NautilusBookmark *bookmark;
const gchar *name;
- gint length, idx, j;
- gchar *query_text, *string, *uri;
- gchar **terms;
- gboolean found;
+ gint length, idx;
+ gchar *string, *uri;
+ gdouble match;
GList *l, *m, *drives, *volumes, *mounts, *mounts_to_check, *candidates;
GDrive *drive;
GVolume *volume;
@@ -321,12 +320,6 @@ search_add_volumes_and_bookmarks (NautilusShellSearchProviderApp *self)
SearchHitCandidate *candidate;
candidates = NULL;
- query_text = nautilus_query_get_text (self->current_search->query);
- string = nautilus_search_prepare_string_for_compare (query_text);
- terms = g_strsplit (string, " ", -1);
-
- g_free (string);
- g_free (query_text);
/* first add bookmarks */
length = nautilus_bookmark_list_length (self->bookmarks);
@@ -430,24 +423,17 @@ search_add_volumes_and_bookmarks (NautilusShellSearchProviderApp *self)
for (l = candidates; l != NULL; l = l->next) {
candidate = l->data;
- found = TRUE;
+ match = nautilus_query_matches_string (self->current_search->query,
+ candidate->string_for_compare);
- for (j = 0; terms[j] != NULL; j++) {
- if (strstr (candidate->string_for_compare, terms[j]) == NULL) {
- found = FALSE;
- break;
- }
- }
-
- if (found) {
+ if (match > -1) {
hit = nautilus_search_hit_new (candidate->uri);
+ nautilus_search_hit_set_fts_rank (hit, match);
nautilus_search_hit_compute_scores (hit, self->current_search->query);
g_hash_table_replace (self->current_search->hits, g_strdup (candidate->uri), hit);
}
}
g_list_free_full (candidates, (GDestroyNotify) search_hit_candidate_free);
-
- g_strfreev (terms);
}
static void