Add a fast way to search for Message-ID (at least)
authorColin Leroy <colin@colino.net>
Mon, 26 Oct 2015 14:44:59 +0000 (15:44 +0100)
committerColin Leroy <colin@colino.net>
Mon, 26 Oct 2015 14:44:59 +0000 (15:44 +0100)
src/advsearch.c
src/imap.c
src/matcher.c
src/matcher.h
src/matcher_parser_parse.y
src/prefs_matcher.c

index 962e9f6..94e010e 100644 (file)
@@ -164,7 +164,7 @@ gchar *advsearch_expand_search_string(const gchar *search_string)
                { "h",  "headers_part",                 1,      TRUE,   TRUE  },
                { "H",  "headers_cont",                 1,      TRUE,   TRUE  },
                { "ha", "has_attachments",              0,      FALSE,  FALSE },
-               { "i",  "header \"Message-ID\"",        1,      TRUE,   TRUE  },
+               { "i",  "messageid",                    1,      TRUE,   TRUE  },
                { "I",  "inreplyto",                    1,      TRUE,   TRUE  },
                { "k",  "colorlabel",                   1,      FALSE,  FALSE },
                { "L",  "locked",                       0,      FALSE,  FALSE },
index 79b1a89..76d1dbd 100644 (file)
@@ -2071,6 +2071,7 @@ static gboolean imap_matcher_type_is_local(gint matchertype)
        case MATCHCRITERIA_TO_OR_CC:
        case MATCHCRITERIA_SUBJECT:
        case MATCHCRITERIA_REFERENCES:
+       case MATCHCRITERIA_MESSAGEID:
        case MATCHCRITERIA_INREPLYTO:
        case MATCHCRITERIA_AGE_GREATER:
        case MATCHCRITERIA_AGE_LOWER:
@@ -2117,6 +2118,7 @@ static IMAPSearchKey* search_make_key(MatcherProp* match, gboolean* is_all)
                case MATCHCRITERIA_NOT_MESSAGE: invert = TRUE; matchertype = MATCHCRITERIA_MESSAGE; break;
                case MATCHCRITERIA_NOT_BODY_PART: invert = TRUE; matchertype = MATCHCRITERIA_BODY_PART; break;
                case MATCHCRITERIA_NOT_TO_AND_NOT_CC: invert = TRUE; matchertype = MATCHCRITERIA_TO_OR_CC; break;
+               case MATCHCRITERIA_NOT_MESSAGEID: invert = TRUE; matchertype = MATCHCRITERIA_MESSAGEID; break;
                case MATCHCRITERIA_NOT_INREPLYTO: invert = TRUE; matchertype = MATCHCRITERIA_INREPLYTO; break;
                }
 
@@ -2143,6 +2145,10 @@ static IMAPSearchKey* search_make_key(MatcherProp* match, gboolean* is_all)
                        result = imap_search_new(IMAP_SEARCH_CRITERIA_TAG, NULL, RTAG_JUNK, 0);
                        break;
 
+               case MATCHCRITERIA_MESSAGEID:
+                       result = imap_search_new(IMAP_SEARCH_CRITERIA_HEADER, "Message-ID", match->expr, 0);
+                       break;
+
                case MATCHCRITERIA_INREPLYTO:
                        result = imap_search_new(IMAP_SEARCH_CRITERIA_HEADER, "In-Reply-To", match->expr, 0);
                        break;
index 47fb7be..d909ae1 100644 (file)
@@ -114,6 +114,8 @@ static const MatchParser matchparser_tab[] = {
        {MATCHCRITERIA_AGE_LOWER_HOURS, "age_lower_hours"},
        {MATCHCRITERIA_NEWSGROUPS, "newsgroups"},
        {MATCHCRITERIA_NOT_NEWSGROUPS, "~newsgroups"},
+       {MATCHCRITERIA_MESSAGEID, "messageid"},
+       {MATCHCRITERIA_NOT_MESSAGEID, "~messageid"},
        {MATCHCRITERIA_INREPLYTO, "inreplyto"},
        {MATCHCRITERIA_NOT_INREPLYTO, "~inreplyto"},
        {MATCHCRITERIA_REFERENCES, "references"},
@@ -192,6 +194,7 @@ enum {
        CONTEXT_TO,
        CONTEXT_CC,
        CONTEXT_NEWSGROUPS,
+       CONTEXT_MESSAGEID,
        CONTEXT_IN_REPLY_TO,
        CONTEXT_REFERENCES,
        CONTEXT_HEADER,
@@ -213,6 +216,7 @@ void matcher_init(void)
        context_str[CONTEXT_TO] = g_strdup_printf(_("%s header"), prefs_common_translated_header_name("To:"));
        context_str[CONTEXT_CC] = g_strdup_printf(_("%s header"), prefs_common_translated_header_name("Cc:"));
        context_str[CONTEXT_NEWSGROUPS] = g_strdup_printf(_("%s header"), prefs_common_translated_header_name("Newsgroups:"));
+       context_str[CONTEXT_MESSAGEID] = g_strdup_printf(_("%s header"), prefs_common_translated_header_name("Message-ID:"));
        context_str[CONTEXT_IN_REPLY_TO] = g_strdup_printf(_("%s header"), prefs_common_translated_header_name("In-Reply-To:"));
        context_str[CONTEXT_REFERENCES] = g_strdup_printf(_("%s header"), prefs_common_translated_header_name("References:"));
        context_str[CONTEXT_HEADER] = g_strdup(_("header"));
@@ -1117,6 +1121,10 @@ static gboolean matcherprop_match(MatcherProp *prop,
                return matcherprop_string_match(prop, info->newsgroups, context_str[CONTEXT_NEWSGROUPS]);
        case MATCHCRITERIA_NOT_NEWSGROUPS:
                return !matcherprop_string_match(prop, info->newsgroups, context_str[CONTEXT_NEWSGROUPS]);
+       case MATCHCRITERIA_MESSAGEID:
+               return matcherprop_string_match(prop, info->msgid, context_str[CONTEXT_MESSAGEID]);
+       case MATCHCRITERIA_NOT_MESSAGEID:
+               return !matcherprop_string_match(prop, info->msgid, context_str[CONTEXT_MESSAGEID]);
        case MATCHCRITERIA_INREPLYTO:
                return matcherprop_string_match(prop, info->inreplyto, context_str[CONTEXT_IN_REPLY_TO]);
        case MATCHCRITERIA_NOT_INREPLYTO:
@@ -1892,6 +1900,8 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info)
                case MATCHCRITERIA_AGE_LOWER_HOURS:
                case MATCHCRITERIA_NEWSGROUPS:
                case MATCHCRITERIA_NOT_NEWSGROUPS:
+               case MATCHCRITERIA_MESSAGEID:
+               case MATCHCRITERIA_NOT_MESSAGEID:
                case MATCHCRITERIA_INREPLYTO:
                case MATCHCRITERIA_NOT_INREPLYTO:
                case MATCHCRITERIA_REFERENCES:
index b8e637d..66cd8c7 100644 (file)
@@ -91,6 +91,7 @@ enum {
        MC_(AGE_GREATER), MC_(AGE_LOWER),
        MC_(AGE_GREATER_HOURS), MC_(AGE_LOWER_HOURS),
        MC_(NEWSGROUPS), MC_(NOT_NEWSGROUPS),
+       MC_(MESSAGEID), MC_(NOT_MESSAGEID),
        MC_(INREPLYTO), MC_(NOT_INREPLYTO),
        MC_(REFERENCES), MC_(NOT_REFERENCES),
        MC_(SCORE_GREATER), MC_(SCORE_LOWER),
index 1c22be7..dd2aee7 100644 (file)
@@ -321,6 +321,7 @@ int matcher_parserwrap(void)
 %token MATCHER_AGE_GREATER  MATCHER_AGE_LOWER  MATCHER_NEWSGROUPS
 %token MATCHER_AGE_GREATER_HOURS  MATCHER_AGE_LOWER_HOURS
 %token MATCHER_NOT_NEWSGROUPS  MATCHER_INREPLYTO  MATCHER_NOT_INREPLYTO
+%token MATCHER_MESSAGEID MATCHER_NOT_MESSAGEID
 %token MATCHER_REFERENCES  MATCHER_NOT_REFERENCES  MATCHER_SCORE_GREATER
 %token MATCHER_SCORE_LOWER  MATCHER_HEADER  MATCHER_NOT_HEADER
 %token MATCHER_HEADERS_PART  MATCHER_NOT_HEADERS_PART  MATCHER_MESSAGE
@@ -991,6 +992,24 @@ MATCHER_ALL
        expr = $3;
        prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
 }
+| MATCHER_MESSAGEID match_type MATCHER_STRING
+{
+       gint criteria = 0;
+       gchar *expr = NULL;
+
+       criteria = MATCHCRITERIA_MESSAGEID;
+       expr = $3;
+       prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
+}
+| MATCHER_NOT_MESSAGEID match_type MATCHER_STRING
+{
+       gint criteria = 0;
+       gchar *expr = NULL;
+
+       criteria = MATCHCRITERIA_NOT_MESSAGEID;
+       expr = $3;
+       prop = matcherprop_new(criteria, NULL, match_type, expr, 0);
+}
 | MATCHER_INREPLYTO match_type MATCHER_STRING
 {
        gint criteria = 0;
index cff1645..2db83f2 100644 (file)
@@ -188,7 +188,8 @@ enum {
        CRITERIA_AGE_GREATER_HOURS = 39,
        CRITERIA_AGE_LOWER_HOURS = 40,
 
-       CRITERIA_HEADERS_CONT = 41
+       CRITERIA_MESSAGEID = 41,
+       CRITERIA_HEADERS_CONT = 42
 };
 
 enum {
@@ -311,6 +312,8 @@ static int header_name_to_crit(const gchar *header)
                return CRITERIA_CC;
        if (!strcasecmp(header, "To or Cc"))
                return CRITERIA_TO_OR_CC;
+       if (!strcasecmp(header, "Message-ID"))
+               return CRITERIA_MESSAGEID;
        if (!strcasecmp(header, "In-Reply-To"))
                return CRITERIA_INREPLYTO;
        if (!strcasecmp(header, "Newsgroups"))
@@ -366,6 +369,7 @@ static void prefs_matcher_models_create(void)
        COMBOBOX_ADD(store, "To", CRITERIA_TO);
        COMBOBOX_ADD(store, "Cc", CRITERIA_CC);
        COMBOBOX_ADD(store, "To or Cc", CRITERIA_TO_OR_CC);
+       COMBOBOX_ADD(store, "Message-ID", CRITERIA_MESSAGEID);
        COMBOBOX_ADD(store, "In-Reply-To", CRITERIA_INREPLYTO);
        COMBOBOX_ADD(store, "Newsgroups", CRITERIA_NEWSGROUPS);
        COMBOBOX_ADD(store, "References", CRITERIA_REFERENCES);
@@ -1127,6 +1131,9 @@ static gint prefs_matcher_get_criteria_from_matching(gint matching_id)
        case MATCHCRITERIA_NOT_NEWSGROUPS:
        case MATCHCRITERIA_NEWSGROUPS:
                return CRITERIA_NEWSGROUPS;
+       case MATCHCRITERIA_NOT_MESSAGEID:
+       case MATCHCRITERIA_MESSAGEID:
+               return CRITERIA_MESSAGEID;
        case MATCHCRITERIA_NOT_INREPLYTO:
        case MATCHCRITERIA_INREPLYTO:
                return CRITERIA_INREPLYTO;
@@ -1247,6 +1254,8 @@ static gint prefs_matcher_get_matching_from_criteria(gint criteria_id)
                return MATCHCRITERIA_TAGGED;
        case CRITERIA_NEWSGROUPS:
                return MATCHCRITERIA_NEWSGROUPS;
+       case CRITERIA_MESSAGEID:
+               return MATCHCRITERIA_MESSAGEID;
        case CRITERIA_INREPLYTO:
                return MATCHCRITERIA_INREPLYTO;
        case CRITERIA_REFERENCES:
@@ -1347,6 +1356,8 @@ static gint prefs_matcher_not_criteria(gint matcher_criteria)
                return MATCHCRITERIA_NOT_TAGGED;
        case MATCHCRITERIA_NEWSGROUPS:
                return MATCHCRITERIA_NOT_NEWSGROUPS;
+       case MATCHCRITERIA_MESSAGEID:
+               return MATCHCRITERIA_NOT_MESSAGEID;
        case MATCHCRITERIA_INREPLYTO:
                return MATCHCRITERIA_NOT_INREPLYTO;
        case MATCHCRITERIA_REFERENCES:
@@ -1417,6 +1428,7 @@ static gint prefs_matcher_get_pred(const gint criteria)
        case CRITERIA_CC:
        case CRITERIA_TO_OR_CC:
        case CRITERIA_NEWSGROUPS:
+       case CRITERIA_MESSAGEID:
        case CRITERIA_INREPLYTO:
        case CRITERIA_REFERENCES:
        case CRITERIA_HEADER:
@@ -1522,6 +1534,7 @@ static MatcherProp *prefs_matcher_dialog_to_matcher(void)
        case CRITERIA_TO_OR_CC:
        case CRITERIA_TAG:
        case CRITERIA_NEWSGROUPS:
+       case CRITERIA_MESSAGEID:
        case CRITERIA_INREPLYTO:
        case CRITERIA_REFERENCES:
        case CRITERIA_HEADERS_PART:
@@ -2327,6 +2340,7 @@ static void prefs_matcher_set_criteria(const gint criteria)
        case CRITERIA_CC:
        case CRITERIA_TO_OR_CC:
        case CRITERIA_NEWSGROUPS:
+       case CRITERIA_MESSAGEID:
        case CRITERIA_INREPLYTO:
        case CRITERIA_REFERENCES:
        case CRITERIA_HEADER:
@@ -2461,6 +2475,7 @@ static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
        case MATCHCRITERIA_NOT_TAG:
        case MATCHCRITERIA_NOT_TAGGED:
        case MATCHCRITERIA_NOT_NEWSGROUPS:
+       case MATCHCRITERIA_NOT_MESSAGEID:
        case MATCHCRITERIA_NOT_INREPLYTO:
        case MATCHCRITERIA_NOT_REFERENCES:
        case MATCHCRITERIA_NOT_HEADER:
@@ -2485,6 +2500,7 @@ static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
        case MATCHCRITERIA_NOT_TO_AND_NOT_CC:
        case MATCHCRITERIA_NOT_TAG:
        case MATCHCRITERIA_NOT_NEWSGROUPS:
+       case MATCHCRITERIA_NOT_MESSAGEID:
        case MATCHCRITERIA_NOT_INREPLYTO:
        case MATCHCRITERIA_NOT_REFERENCES:
        case MATCHCRITERIA_NOT_HEADERS_PART:
@@ -2499,6 +2515,7 @@ static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
        case MATCHCRITERIA_TO_OR_CC:
        case MATCHCRITERIA_TAG:
        case MATCHCRITERIA_NEWSGROUPS:
+       case MATCHCRITERIA_MESSAGEID:
        case MATCHCRITERIA_INREPLYTO:
        case MATCHCRITERIA_REFERENCES:
        case MATCHCRITERIA_HEADERS_PART:
@@ -2609,6 +2626,7 @@ static gboolean prefs_matcher_selected(GtkTreeSelection *selector,
        case CRITERIA_CC:
        case CRITERIA_TO_OR_CC:
        case CRITERIA_NEWSGROUPS:
+       case CRITERIA_MESSAGEID:
        case CRITERIA_INREPLYTO:
        case CRITERIA_REFERENCES:
        case CRITERIA_HEADER: