[devhelp: 26/36] search: Sort first results prefixed with the search key (GNOME bug 601201)
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [devhelp: 26/36] search: Sort first results prefixed with the search key (GNOME bug 601201)
- Date: Mon, 20 Dec 2010 14:33:36 +0000 (UTC)
commit 699c6d8d744b70ca068dab8b715154ac62478d16
Author: Aleksander Morgado <aleksander lanedo com>
Date: Mon Dec 13 23:26:08 2010 +0100
search: Sort first results prefixed with the search key (GNOME bug 601201)
src/dh-keyword-model.c | 107 +++++++++++++++++++++++++++++++++++++++++-------
src/dh-link.c | 21 +++++++---
2 files changed, 107 insertions(+), 21 deletions(-)
---
diff --git a/src/dh-keyword-model.c b/src/dh-keyword-model.c
index 0d219b2..94b74a2 100644
--- a/src/dh-keyword-model.c
+++ b/src/dh-keyword-model.c
@@ -337,12 +337,15 @@ dh_keyword_model_set_words (DhKeywordModel *model,
}
static GList *
-keyword_model_search (DhKeywordModel *model,
- const gchar *string,
- gchar **stringv,
- const gchar *book_id,
- gboolean case_sensitive,
- DhLink **exact_link)
+keyword_model_search_books (DhKeywordModel *model,
+ const gchar *string,
+ gchar **stringv,
+ const gchar *book_id,
+ gboolean case_sensitive,
+ gboolean prefix,
+ guint max_hits,
+ guint *n_hits,
+ DhLink **exact_link)
{
DhKeywordModelPriv *priv;
GList *new_list = NULL, *b;
@@ -363,7 +366,7 @@ keyword_model_search (DhKeywordModel *model,
}
for (b = dh_book_manager_get_books (priv->book_manager);
- b && hits < MAX_HITS;
+ b && hits < max_hits;
b = g_list_next (b)) {
DhBook *book;
GList *l;
@@ -376,7 +379,7 @@ keyword_model_search (DhKeywordModel *model,
}
for (l = dh_book_get_keywords (book);
- l && hits < MAX_HITS;
+ l && hits < max_hits;
l = g_list_next (l)) {
DhLink *link;
gboolean found;
@@ -403,18 +406,39 @@ keyword_model_search (DhKeywordModel *model,
if (stringv[0] == NULL) {
/* means only a page was specified, no keyword */
- if (g_strrstr (file_name, page_id))
- found = TRUE;
+ if (prefix) {
+ if (g_str_has_prefix (file_name, page_id))
+ found = TRUE;
+ } else {
+ if (!g_str_has_prefix (file_name, page_id) &&
+ g_strrstr (file_name, page_id))
+ found = TRUE;
+ }
} else {
- gint i;
+ gboolean all_found;
+ gboolean prefix_found;
+ gint i;
+
+ prefix_found = FALSE;
+ all_found = TRUE;
- found = TRUE;
for (i = 0; stringv[i] != NULL; i++) {
- if (!g_strrstr (name, stringv[i])) {
- found = FALSE;
+ if (g_str_has_prefix (name, stringv[i])) {
+ prefix_found = TRUE;
+ /* If we get a prefix match and we're not
+ * looking for prefix, stop. */
+ if (!prefix)
+ break;
+ } else if (!g_strrstr (name, stringv[i])) {
+ all_found = FALSE;
break;
}
}
+
+ found = (all_found &&
+ ((prefix && prefix_found) ||
+ (!prefix && !prefix_found)) ?
+ TRUE : FALSE);
}
g_free (name);
@@ -425,7 +449,8 @@ keyword_model_search (DhKeywordModel *model,
new_list = g_list_prepend (new_list, link);
hits++;
- if (!*exact_link &&
+ if (exact_link &&
+ !*exact_link &&
dh_link_get_name (link) && (
(dh_link_get_link_type (link) == DH_LINK_TYPE_PAGE &&
page_id && strcmp (dh_link_get_name (link), page_id) == 0) ||
@@ -438,9 +463,61 @@ keyword_model_search (DhKeywordModel *model,
g_free (page_filename_prefix);
+ if (n_hits)
+ *n_hits = hits;
return g_list_sort (new_list, dh_link_compare);
}
+static GList *
+keyword_model_search (DhKeywordModel *model,
+ const gchar *string,
+ gchar **stringv,
+ const gchar *book_id,
+ gboolean case_sensitive,
+ DhLink **exact_link)
+{
+ guint max_hits = MAX_HITS;
+ guint n_hits;
+ GList *list;
+ gint i;
+
+ g_debug ("-------------------");
+ g_debug ("string: %s", string);
+ g_debug ("book_id: %s", book_id);
+ for (i = 0; stringv[i]; i++) {
+ g_debug ("stringv[%d]: '%s'", i, stringv[i]);
+ }
+
+ /* First, look for prefixed items */
+ list = keyword_model_search_books (model,
+ string,
+ stringv,
+ book_id,
+ case_sensitive,
+ TRUE,
+ max_hits,
+ &n_hits,
+ exact_link);
+
+ if (n_hits < max_hits) {
+ GList *non_prefixed_list;
+
+ /* If not enough hits, get non-prefixed ones */
+ non_prefixed_list = keyword_model_search_books (model,
+ string,
+ stringv,
+ book_id,
+ case_sensitive,
+ FALSE,
+ max_hits - n_hits,
+ NULL,
+ NULL);
+ list = g_list_concat (list, non_prefixed_list);
+ }
+
+ return list;
+}
+
DhLink *
dh_keyword_model_filter (DhKeywordModel *model,
const gchar *string,
diff --git a/src/dh-link.c b/src/dh-link.c
index a93b052..a3493b0 100644
--- a/src/dh-link.c
+++ b/src/dh-link.c
@@ -33,6 +33,7 @@ struct _DhLink {
gchar *base;
gchar *name;
+ gchar *name_collation_key;
gchar *filename;
DhLink *book;
@@ -61,10 +62,11 @@ dh_link_get_type (void)
static void
link_free (DhLink *link)
{
- g_free (link->base);
- g_free (link->id);
- g_free (link->name);
- g_free (link->filename);
+ g_free (link->base);
+ g_free (link->id);
+ g_free (link->name);
+ g_free (link->filename);
+ g_free (link->name_collation_key);
if (link->book) {
dh_link_unref (link->book);
@@ -131,13 +133,20 @@ dh_link_compare (gconstpointer a,
gint flags_diff;
/* Sort deprecated hits last. */
- flags_diff = (la->flags & DH_LINK_FLAGS_DEPRECATED) -
+ flags_diff = (la->flags & DH_LINK_FLAGS_DEPRECATED) -
(lb->flags & DH_LINK_FLAGS_DEPRECATED);
if (flags_diff != 0) {
return flags_diff;
}
- return strcmp (la->name, lb->name);
+ /* Collation-based sorting */
+ if (G_UNLIKELY (!la->name_collation_key))
+ la->name_collation_key = g_utf8_collate_key (la->name, -1);
+ if (G_UNLIKELY (!lb->name_collation_key))
+ lb->name_collation_key = g_utf8_collate_key (lb->name, -1);
+
+ return strcmp (la->name_collation_key,
+ lb->name_collation_key);
}
DhLink *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]