[evolution] I#982 - 'Message contains'-search broken in 3.36.3



commit 273416f96f3cca6bef96ad8297350b50c7b22181
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jun 11 19:06:29 2020 +0200

    I#982 - 'Message contains'-search broken in 3.36.3
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/982

 src/e-util/e-filter-rule.c           | 111 ++++++++++++++++++++++++++++++-----
 src/mail/message-list.c              |  18 +++---
 src/mail/searchtypes.xml.in          |   8 +--
 src/modules/mail/e-mail-shell-view.c |   2 +-
 4 files changed, 107 insertions(+), 32 deletions(-)
---
diff --git a/src/e-util/e-filter-rule.c b/src/e-util/e-filter-rule.c
index 2ec1d8dfc1..72bfc6af5e 100644
--- a/src/e-util/e-filter-rule.c
+++ b/src/e-util/e-filter-rule.c
@@ -811,9 +811,16 @@ filter_rule_xml_decode (EFilterRule *rule,
 }
 
 static void
-filter_rule_build_code (EFilterRule *rule,
-                        GString *out)
+filter_rule_build_code_for_parts (EFilterRule *rule,
+                                 GList *parts,
+                                 gboolean without_match_all,
+                                 gboolean force_match_all,
+                                 GString *out)
 {
+       g_return_if_fail (rule != NULL);
+       g_return_if_fail (parts != NULL);
+       g_return_if_fail (out != NULL);
+
        switch (rule->threading) {
        case E_FILTER_THREAD_NONE:
                break;
@@ -831,25 +838,97 @@ filter_rule_build_code (EFilterRule *rule,
                break;
        }
 
-       if (rule->threading != E_FILTER_THREAD_NONE)
+       if ((rule->threading != E_FILTER_THREAD_NONE && !without_match_all) || force_match_all)
                g_string_append (out, "(match-all ");
 
-       switch (rule->grouping) {
-       case E_FILTER_GROUP_ALL:
-               g_string_append (out, " (and\n  ");
-               break;
-       case E_FILTER_GROUP_ANY:
-               g_string_append (out, " (or\n  ");
-               break;
-       default:
-               g_warning ("Invalid grouping");
+       if (parts->next) {
+               switch (rule->grouping) {
+               case E_FILTER_GROUP_ALL:
+                       g_string_append (out, " (and\n  ");
+                       break;
+               case E_FILTER_GROUP_ANY:
+                       g_string_append (out, " (or\n  ");
+                       break;
+               default:
+                       g_warning ("Invalid grouping");
+               }
+       }
+
+       e_filter_part_build_code_list (parts, out);
+
+       if (parts->next)
+               g_string_append (out, ")\n");
+
+       if (rule->threading != E_FILTER_THREAD_NONE) {
+               if (without_match_all && !force_match_all)
+                       g_string_append (out, ")\n");
+               else
+                       g_string_append (out, "))\n");
+       } else if (force_match_all) {
+               g_string_append (out, ")\n");
+       }
+}
+
+static void
+filter_rule_build_code (EFilterRule *rule,
+                        GString *out)
+{
+       GList *link;
+       gboolean has_body_search = FALSE;
+
+       if (!rule->parts)
+               return;
+
+       for (link = rule->parts; link && !has_body_search; link = g_list_next (link)) {
+               EFilterPart *part = link->data;
+
+               has_body_search = g_strcmp0 (part->name, "body") == 0;
        }
 
-       e_filter_part_build_code_list (rule->parts, out);
-       g_string_append (out, ")\n");
+       if (has_body_search) {
+               GList *body_searches = NULL, *other_searches = NULL;
 
-       if (rule->threading != E_FILTER_THREAD_NONE)
-               g_string_append (out, "))\n");
+               for (link = rule->parts; link; link = g_list_next (link)) {
+                       EFilterPart *part = link->data;
+
+                       if (g_strcmp0 (part->name, "body") == 0) {
+                               body_searches = g_list_prepend (body_searches, part);
+                       } else {
+                               other_searches = g_list_prepend (other_searches, part);
+                       }
+               }
+
+               if (other_searches && body_searches) {
+                       switch (rule->grouping) {
+                       case E_FILTER_GROUP_ALL:
+                               g_string_append (out, "(and ");
+                               break;
+                       case E_FILTER_GROUP_ANY:
+                               g_string_append (out, "(or ");
+                               break;
+                       default:
+                               g_warning ("Invalid grouping");
+                       }
+
+                       body_searches = g_list_reverse (body_searches);
+                       other_searches = g_list_reverse (other_searches);
+
+                       filter_rule_build_code_for_parts (rule, other_searches, FALSE, TRUE, out);
+
+                       g_string_append_c (out, ' ');
+
+                       filter_rule_build_code_for_parts (rule, body_searches, TRUE, FALSE, out);
+
+                       g_string_append_c (out, ')');
+               } else {
+                       filter_rule_build_code_for_parts (rule, rule->parts, FALSE, FALSE, out);
+               }
+
+               g_list_free (body_searches);
+               g_list_free (other_searches);
+       } else {
+               filter_rule_build_code_for_parts (rule, rule->parts, FALSE, FALSE, out);
+       }
 }
 
 static void
diff --git a/src/mail/message-list.c b/src/mail/message-list.c
index 01b7528850..2c5741a139 100644
--- a/src/mail/message-list.c
+++ b/src/mail/message-list.c
@@ -6176,7 +6176,7 @@ message_list_regen_thread (GSimpleAsyncResult *simple,
        /* The 'expr' should be enclosed in "(match-all ...)", thus the search traverses
           folder content, but also try to not repeat it, to avoid unnecessary performance hits. */
        if (regen_data->search != NULL) {
-               gboolean is_match_all = g_str_has_prefix (regen_data->search, "(match-all ");
+               gboolean is_match_all = g_str_has_prefix (regen_data->search, "(match-all ") && !strstr 
(regen_data->search, "(body-contains ");
                gboolean is_match_threads = strstr (regen_data->search, "(match-threads ") != NULL;
 
                if (expr->len == 0) {
@@ -6186,25 +6186,21 @@ message_list_regen_thread (GSimpleAsyncResult *simple,
                                g_string_prepend (expr, "(match-all ");
                                g_string_append_c (expr, ')');
                        }
-               } else if (is_match_threads) {
+               } else if (is_match_threads || !is_match_all) {
                        /* The "match-threads" cannot be below "match-all". */
                        g_string_prepend (expr, "(and (match-all ");
                        g_string_append (expr, ") ");
                        g_string_append (expr, regen_data->search);
                        g_string_append_c (expr, ')');
                } else {
+                       const gchar *stripped_search = regen_data->search + 11; /* strlen ("(match-all ") */
+                       gint len = strlen (stripped_search);
+
                        g_string_prepend (expr, "(match-all (and ");
                        g_string_append_c (expr, ' ');
 
-                       if (is_match_all) {
-                               const gchar *stripped_search = regen_data->search + 11; /* strlen 
("(match-all ") */
-                               gint len = strlen (stripped_search);
-
-                               if (len > 0 && stripped_search[len - 1] == ')') {
-                                       g_string_append_len (expr, stripped_search, len - 1);
-                               } else {
-                                       g_string_append (expr, regen_data->search);
-                               }
+                       if (len > 0 && stripped_search[len - 1] == ')') {
+                               g_string_append_len (expr, stripped_search, len - 1);
                        } else {
                                g_string_append (expr, regen_data->search);
                        }
diff --git a/src/mail/searchtypes.xml.in b/src/mail/searchtypes.xml.in
index e03e28e60f..d0362d59dd 100644
--- a/src/mail/searchtypes.xml.in
+++ b/src/mail/searchtypes.xml.in
@@ -728,10 +728,6 @@
           <value name="subject-type" type="option" value="contains"/>
           <value name="subject" type="string"/>
         </part>
-        <part name="body">
-          <value name="body-type" type="option" value="contains"/>
-          <value name="word" type="string"/>
-        </part>
         <part name="sender">
           <value name="sender-type" type="option" value="contains"/>
           <value name="sender" type="string"/>
@@ -740,6 +736,10 @@
           <value name="recipient-type" type="option" value="contains"/>
           <value name="recipient" type="address"/>
         </part>
+        <part name="body">
+          <value name="body-type" type="option" value="contains"/>
+          <value name="word" type="string"/>
+        </part>
       </partset>
       <sources/>
     </rule>
diff --git a/src/modules/mail/e-mail-shell-view.c b/src/modules/mail/e-mail-shell-view.c
index 8dcca65eca..be72de3441 100644
--- a/src/modules/mail/e-mail-shell-view.c
+++ b/src/modules/mail/e-mail-shell-view.c
@@ -752,7 +752,7 @@ filter:
 
        /* Apply selected filter. */
 
-       if (query && *query && !g_str_has_prefix (query, "(match-all ") && !strstr (query, "(match-threads 
")) {
+       if (query && *query && !strstr (query, "(match-all ") && !strstr (query, "(match-threads ")) {
                /* Make sure the query is enclosed in "(match-all ...)", to traverse the folders' content */
                temp = g_strconcat ("(match-all ", query, ")", NULL);
                g_free (query);


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