diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2012-10-14 13:33:01 -0400 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2012-10-15 10:02:48 -0400 |
commit | bbe59c4bb7c1d389442d00e93a7ba8482b0e102e (patch) | |
tree | daa8504ac57744ce7be58bb5414409a70fef7a21 | |
parent | 474abdb3bad65cf79b0e761d962edc8b94d51dcc (diff) | |
download | nautilus-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.c | 59 | ||||
-rw-r--r-- | libnautilus-private/nautilus-query.h | 2 | ||||
-rw-r--r-- | libnautilus-private/nautilus-search-engine-model.c | 30 | ||||
-rw-r--r-- | libnautilus-private/nautilus-search-engine-simple.c | 51 | ||||
-rw-r--r-- | libnautilus-private/nautilus-ui-utilities.c | 12 | ||||
-rw-r--r-- | libnautilus-private/nautilus-ui-utilities.h | 2 | ||||
-rw-r--r-- | src/nautilus-shell-search-provider.c | 30 |
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 |