evolution/0004-I-982-Message-contains-search-broken-in-3.36.3.patch
2020-06-23 13:22:24 -07:00

236 lines
7.6 KiB
Diff

From fb5dfe31f4985cf3b42eba899fd71f3cf2d256bf Mon Sep 17 00:00:00 2001
From: Milan Crha <mcrha@redhat.com>
Date: Thu, 11 Jun 2020 19:06:29 +0200
Subject: [PATCH 4/5] 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);
--
2.27.0