From fb5dfe31f4985cf3b42eba899fd71f3cf2d256bf Mon Sep 17 00:00:00 2001 From: Milan Crha 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 @@ - - - - @@ -740,6 +736,10 @@ + + + + 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