[devhelp] KeywordModel: delegate is_exact_link() to DhSearchContext



commit 38bb71dbd91b70892764a6669660bbf64207a2ee
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Thu Jan 18 19:00:33 2018 +0100

    KeywordModel: delegate is_exact_link() to DhSearchContext
    
    And better implement it.

 src/dh-keyword-model.c  |   37 ++++++++++++++++---------------------
 src/dh-search-context.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 src/dh-search-context.h |    4 ++++
 3 files changed, 67 insertions(+), 21 deletions(-)
---
diff --git a/src/dh-keyword-model.c b/src/dh-keyword-model.c
index bc314df..848f60d 100644
--- a/src/dh-keyword-model.c
+++ b/src/dh-keyword-model.c
@@ -53,7 +53,6 @@ typedef struct {
 
 typedef struct {
         DhSearchContext *search_context;
-        const gchar *search_string;
         GStrv keywords;
         const gchar *book_id;
         const gchar *skip_book_id;
@@ -373,27 +372,24 @@ search_single_book (DhBook          *book,
              l = l->next) {
                 DhLink *link = l->data;
 
-                if (_dh_search_context_match_link (settings->search_context,
-                                                   link,
-                                                   settings->prefix)) {
-                        g_queue_push_tail (ret, link);
+                if (!_dh_search_context_match_link (settings->search_context,
+                                                    link,
+                                                    settings->prefix)) {
+                        continue;
+                }
 
-                        if (exact_link == NULL || dh_link_get_name (link) == NULL)
-                                continue;
+                g_queue_push_tail (ret, link);
 
-                        /* Look for an exact link match. If the link is a PAGE,
-                         * we can overwrite any previous exact link set. For
-                         * example, when looking for GFile, we want the page,
-                         * not the struct. */
-                        if (dh_link_get_link_type (link) == DH_LINK_TYPE_PAGE &&
-                            ((settings->page_id != NULL &&
-                              strcmp (dh_link_get_name (link), settings->page_id) == 0) ||
-                             (strcmp (dh_link_get_name (link), settings->search_string) == 0))) {
-                                *exact_link = link;
-                        } else if (*exact_link == NULL &&
-                                   strcmp (dh_link_get_name (link), settings->search_string) == 0) {
-                                *exact_link = link;
-                        }
+                if (exact_link == NULL)
+                        continue;
+
+                /* Look for an exact link match. If the link is a PAGE, we can
+                 * overwrite any previous exact link set. For example, when
+                 * looking for GFile, we want the page, not the struct.
+                 */
+                if ((*exact_link == NULL || dh_link_get_link_type (link) == DH_LINK_TYPE_PAGE) &&
+                    _dh_search_context_is_exact_link (settings->search_context, link)) {
+                        *exact_link = link;
                 }
         }
 
@@ -498,7 +494,6 @@ keyword_model_search (DhKeywordModel   *model,
         GQueue *out = g_queue_new ();
 
         settings.search_context = search_context;
-        settings.search_string = search_string;
         settings.keywords = _dh_search_context_get_keywords (search_context);
         settings.book_id = priv->current_book_id;
         settings.skip_book_id = NULL;
diff --git a/src/dh-search-context.c b/src/dh-search-context.c
index 53c14df..cd04f8b 100644
--- a/src/dh-search-context.c
+++ b/src/dh-search-context.c
@@ -33,6 +33,8 @@ struct _DhSearchContext {
         GPatternSpec *pattern_spec_prefix;
         GPatternSpec *pattern_spec_nonprefix;
 
+        gchar *joined_keywords;
+
         guint case_sensitive : 1;
 };
 
@@ -233,6 +235,17 @@ create_pattern_specs (DhSearchContext *search)
         g_free (pattern_nonprefix_str);
 }
 
+static void
+join_keywords (DhSearchContext *search)
+{
+        g_assert (search->joined_keywords == NULL);
+
+        if (search->keywords == NULL)
+                return;
+
+        search->joined_keywords = g_strjoinv (" ", search->keywords);
+}
+
 /* Returns: (transfer full) (nullable): a new #DhSearchContext, or %NULL if
  * @search_string is invalid.
  */
@@ -252,6 +265,7 @@ _dh_search_context_new (const gchar *search_string)
 
         set_case_sensitive (search);
         create_pattern_specs (search);
+        join_keywords (search);
 
         return search;
 }
@@ -272,6 +286,8 @@ _dh_search_context_free (DhSearchContext *search)
         if (search->pattern_spec_nonprefix != NULL)
                 g_pattern_spec_free (search->pattern_spec_nonprefix);
 
+        g_free (search->joined_keywords);
+
         g_free (search);
 }
 
@@ -350,3 +366,34 @@ _dh_search_context_match_link (DhSearchContext *search,
         g_free (str_to_free);
         return match;
 }
+
+/* This function assumes:
+ * - That checking that the DhBook (book_id) matches has already been done (to
+ *   not check the book_id for each DhLink).
+ * - That _dh_search_context_match_link() returns TRUE for @link.
+ */
+gboolean
+_dh_search_context_is_exact_link (DhSearchContext *search,
+                                  DhLink          *link)
+{
+        const gchar *name;
+
+        g_return_val_if_fail (search != NULL, FALSE);
+        g_return_val_if_fail (link != NULL, FALSE);
+
+        if (search->page_id != NULL && search->keywords == NULL) {
+                DhLinkType link_type;
+
+                link_type = dh_link_get_link_type (link);
+
+                /* Can be DH_LINK_TYPE_BOOK for page_id "index". */
+                return (link_type == DH_LINK_TYPE_BOOK ||
+                        link_type == DH_LINK_TYPE_PAGE);
+        }
+
+        if (search->keywords == NULL)
+                return FALSE;
+
+        name = dh_link_get_name (link);
+        return g_strcmp0 (name, search->joined_keywords) == 0;
+}
diff --git a/src/dh-search-context.h b/src/dh-search-context.h
index ea00d92..1fcc175 100644
--- a/src/dh-search-context.h
+++ b/src/dh-search-context.h
@@ -49,6 +49,10 @@ gboolean                _dh_search_context_match_link           (DhSearchContext
                                                                  DhLink          *link,
                                                                  gboolean         prefix);
 
+G_GNUC_INTERNAL
+gboolean                _dh_search_context_is_exact_link        (DhSearchContext *search,
+                                                                 DhLink          *link);
+
 G_END_DECLS
 
 #endif /* DH_SEARCH_CONTEXT_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]