dialog box for matching and some other changes
authorHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Tue, 8 May 2001 14:25:21 +0000 (14:25 +0000)
committerHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Tue, 8 May 2001 14:25:21 +0000 (14:25 +0000)
14 files changed:
ChangeLog.claws
src/Makefile.am
src/alertpanel.c
src/mainwindow.c
src/matcher.c
src/matcher.h
src/prefs_display_header.c
src/prefs_folder_item.c
src/prefs_folder_item.h
src/prefs_headers.c
src/procheader.c
src/scoring.c
src/summaryview.c
src/textview.c

index c4b2e2b25d52f18c00d16c08ff65af6b598367ed..a8ed22a8fdeccb2ad3c4b059771f82c7552dd9c8 100644 (file)
@@ -1,3 +1,39 @@
+2001-05-08 [hoa]
+
+       * src/Makefile.am
+               added prefs_matcher.[ch]
+               compilation with -W -Wall
+       * src/alertpanel.c
+               ungrab the mouse events if grabbed - does it
+               fix the bug for disposition notification ?
+       * src/mainwindow.c
+               added a menu option to open the matching dialog.
+       * src/matcher.[ch]
+               added matcherprop_to_string() and matcherlist_to_string()
+               fixed some bugs, changed the name of some options
+               age_sup and age_inf becomes age_greater and age_lower,
+               body and messageheaders becomes body_part and headers_part,
+               changed the names of constants from SCORING_XXX to MATCHING_XXX
+       * src/prefs_display_header.c
+       * src/prefs_headers.c
+               fixed a bug that accidentally destroyed dialogs
+               when closed them with delete_event
+               Added *_deleted() which handle delete_event signal correctly.
+       * src/prefs_folder_item.[ch]
+               added "enable_thread" field for future customization
+       * added src/prefs_matcher.[ch]
+               sample of the UI to define matching properties
+       * src/procheader.c
+               using procheader_headername_equal instead of str*cmp functions
+               using procheader_parse_header() function
+       * src/scoring.c
+               using MATCHING_XXX instead of SCORING_XXX
+       * src/summaryview.c
+               display the sender of the news even if this is ourself
+               when this is a news message.
+       * src/textview.c
+               using headername_equal() instead of str*cmp functions
+
 2001-05-08 [alfons]
 
        0.4.66claws
index 113fce5c784a8b1ea9f6879375ebe09a99122b36..3c519111c860ec0e1874c44a65ac1b60ef4b5e37 100644 (file)
@@ -81,7 +81,8 @@ sylpheed_SOURCES = \
        prefs_headers.c prefs_headers.h \
        scoring.c scoring.h \
        prefs_folder_item.c prefs_folder_item.h \
-       matcher.c matcher.h
+       matcher.c matcher.h \
+       prefs_matcher.c prefs_matcher.h
 
 EXTRA_DIST = \
        pixmaps/clip.xpm \
@@ -141,7 +142,7 @@ sylpheed_LDADD = \
        $(GDK_PIXBUF_LIBS) \
        $(GPGME_LIBS)
 
-CPPFLAGS = \
+CPPFLAGS = -W -Wall \
        -DLOCALEDIR=\""$(localedir)"\" \
        -DMANUALDIR=\""$(manualdir)"\" \
        -DHOST_ALIAS=\""$(host_alias)"\"
index 757af10e1d124c35c5d7ec50b36ee2d04076210c..ca6f06d0e11c118cee0ace9ed1194414288d46a0 100644 (file)
@@ -149,6 +149,10 @@ static void alertpanel_show(void)
        manage_window_set_transient(GTK_WINDOW(dialog));
        value = G_ALERTWAIT;
 
+       /* ungrab the mouse events ? */
+       if (gdk_pointer_is_grabbed())
+               gdk_pointer_ungrab(GDK_CURRENT_TIME);
+
        while ((value & G_ALERT_VALUE_MASK) == G_ALERTWAIT)
                gtk_main_iteration();
 
index eacd7d5b50911e8ad78bea0b7231f167886598e3..0049f04a0d7601c25c6ad9a255a6fe53e7b72b0e 100644 (file)
@@ -318,6 +318,9 @@ static void prefs_common_open_cb (MainWindow        *mainwin,
 static void prefs_filter_open_cb (MainWindow   *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
+static void prefs_matcher_open_cb (MainWindow  *mainwin,
+                                 guint          action,
+                                 GtkWidget     *widget);
 static void prefs_account_open_cb(MainWindow   *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
@@ -518,6 +521,8 @@ static GtkItemFactoryEntry mainwin_entries[] =
                                                NULL, prefs_common_open_cb, 0, NULL},
        {N_("/_Configuration/_Filter setting..."),
                                                NULL, prefs_filter_open_cb, 0, NULL},
+       {N_("/_Configuration/_Scoring ..."),
+                                               NULL, prefs_matcher_open_cb, 0, NULL},
        {N_("/_Configuration/_Preferences per account..."),
                                                NULL, prefs_account_open_cb, 0, NULL},
        {N_("/_Configuration/---"),             NULL, NULL, 0, "<Separator>"},
@@ -2051,6 +2056,12 @@ static void prefs_filter_open_cb(MainWindow *mainwin, guint action,
        prefs_filter_open();
 }
 
+static void prefs_matcher_open_cb(MainWindow *mainwin, guint action,
+                                 GtkWidget *widget)
+{
+       prefs_matcher_open(NULL);
+}
+
 static void prefs_account_open_cb(MainWindow *mainwin, guint action,
                                  GtkWidget *widget)
 {
index 6becce60d0e09d22cb604f73a70320f90443ef40..dbb4922bdc5eb20a4ea9b7e3d066211d6d28f5ba 100644 (file)
@@ -16,40 +16,40 @@ typedef struct _MatchParser MatchParser;
 
 MatchParser matchparser_tab[] = {
        /* msginfo */
-       {SCORING_ALL, "all"},
-       {SCORING_SUBJECT, "subject"},
-       {SCORING_NOT_SUBJECT, "~subject"},
-       {SCORING_FROM, "from"},
-       {SCORING_NOT_FROM, "~from"},
-       {SCORING_TO, "to"},
-       {SCORING_NOT_TO, "~to"},
-       {SCORING_CC, "cc"},
-       {SCORING_NOT_CC, "~cc"},
-       {SCORING_TO_OR_CC, "to_or_cc"},
-       {SCORING_NOT_TO_AND_NOT_CC, "~to_or_cc"},
-       {SCORING_AGE_SUP, "age_sup"},
-       {SCORING_AGE_INF, "age_inf"},
-       {SCORING_NEWSGROUPS, "newsgroups"},
-       {SCORING_NOT_NEWSGROUPS, "~newsgroups"},
+       {MATCHING_ALL, "all"},
+       {MATCHING_SUBJECT, "subject"},
+       {MATCHING_NOT_SUBJECT, "~subject"},
+       {MATCHING_FROM, "from"},
+       {MATCHING_NOT_FROM, "~from"},
+       {MATCHING_TO, "to"},
+       {MATCHING_NOT_TO, "~to"},
+       {MATCHING_CC, "cc"},
+       {MATCHING_NOT_CC, "~cc"},
+       {MATCHING_TO_OR_CC, "to_or_cc"},
+       {MATCHING_NOT_TO_AND_NOT_CC, "~to_or_cc"},
+       {MATCHING_AGE_GREATER, "age_greater"},
+       {MATCHING_AGE_LOWER, "age_lower"},
+       {MATCHING_NEWSGROUPS, "newsgroups"},
+       {MATCHING_NOT_NEWSGROUPS, "~newsgroups"},
 
        /* content have to be read */
-       {SCORING_HEADER, "header"},
-       {SCORING_NOT_HEADER, "~header"},
-       {SCORING_MESSAGEHEADERS, "messageheaders"},
-       {SCORING_NOT_MESSAGEHEADERS, "~messageheaders"},
-       {SCORING_MESSAGE, "message"},
-       {SCORING_NOT_MESSAGE, "~message"},
-       {SCORING_BODY, "body"},
-       {SCORING_NOT_BODY, "~body"},
+       {MATCHING_HEADER, "header"},
+       {MATCHING_NOT_HEADER, "~header"},
+       {MATCHING_HEADERS_PART, "headers_part"},
+       {MATCHING_NOT_HEADERS_PART, "~headers_part"},
+       {MATCHING_MESSAGE, "message"},
+       {MATCHING_NOT_MESSAGE, "~message"},
+       {MATCHING_BODY_PART, "body_part"},
+       {MATCHING_NOT_BODY_PART, "~body_part"},
 
        /* match type */
-       {SCORING_MATCHCASE, "matchcase"},
-       {SCORING_MATCH, "match"},
-       {SCORING_REGEXPCASE, "regexpcase"},
-       {SCORING_REGEXP, "regexp"},
+       {MATCHING_MATCHCASE, "matchcase"},
+       {MATCHING_MATCH, "match"},
+       {MATCHING_REGEXPCASE, "regexpcase"},
+       {MATCHING_REGEXP, "regexp"},
 
        /* actions */
-       {SCORING_SCORE, "score"},
+       {MATCHING_SCORE, "score"},
 };
 
 /*
@@ -89,8 +89,8 @@ MatcherProp * matcherprop_parse(gchar ** str)
        }
 
        switch (key) {
-       case SCORING_AGE_INF:
-       case SCORING_AGE_SUP:
+       case MATCHING_AGE_LOWER:
+       case MATCHING_AGE_GREATER:
                age = matcher_parse_number(&tmp);
                if (tmp == NULL) {
                        * str = NULL;
@@ -102,33 +102,33 @@ MatcherProp * matcherprop_parse(gchar ** str)
 
                return prop;
 
-       case SCORING_ALL:
+       case MATCHING_ALL:
                prop = matcherprop_new(key, NULL, 0, NULL, 0);
                *str = tmp;
 
                return prop;
 
-       case SCORING_SUBJECT:
-       case SCORING_NOT_SUBJECT:
-       case SCORING_FROM:
-       case SCORING_NOT_FROM:
-       case SCORING_TO:
-       case SCORING_NOT_TO:
-       case SCORING_CC:
-       case SCORING_NOT_CC:
-       case SCORING_TO_OR_CC:
-       case SCORING_NOT_TO_AND_NOT_CC:
-       case SCORING_NEWSGROUPS:
-       case SCORING_NOT_NEWSGROUPS:
-       case SCORING_MESSAGE:
-       case SCORING_NOT_MESSAGE:
-       case SCORING_MESSAGEHEADERS:
-       case SCORING_NOT_MESSAGEHEADERS:
-       case SCORING_BODY:
-       case SCORING_NOT_BODY:
-       case SCORING_HEADER:
-       case SCORING_NOT_HEADER:
-               if ((key == SCORING_HEADER) || (key == SCORING_NOT_HEADER)) {
+       case MATCHING_SUBJECT:
+       case MATCHING_NOT_SUBJECT:
+       case MATCHING_FROM:
+       case MATCHING_NOT_FROM:
+       case MATCHING_TO:
+       case MATCHING_NOT_TO:
+       case MATCHING_CC:
+       case MATCHING_NOT_CC:
+       case MATCHING_TO_OR_CC:
+       case MATCHING_NOT_TO_AND_NOT_CC:
+       case MATCHING_NEWSGROUPS:
+       case MATCHING_NOT_NEWSGROUPS:
+       case MATCHING_MESSAGE:
+       case MATCHING_NOT_MESSAGE:
+       case MATCHING_HEADERS_PART:
+       case MATCHING_NOT_HEADERS_PART:
+       case MATCHING_BODY_PART:
+       case MATCHING_NOT_BODY_PART:
+       case MATCHING_HEADER:
+       case MATCHING_NOT_HEADER:
+               if ((key == MATCHING_HEADER) || (key == MATCHING_NOT_HEADER)) {
                        header = matcher_parse_str(&tmp);
                        if (tmp == NULL) {
                                * str = NULL;
@@ -145,8 +145,8 @@ MatcherProp * matcherprop_parse(gchar ** str)
                }
 
                switch(match) {
-               case SCORING_REGEXP:
-               case SCORING_REGEXPCASE:
+               case MATCHING_REGEXP:
+               case MATCHING_REGEXPCASE:
                        expr = matcher_parse_regexp(&tmp);
                        if (tmp == NULL) {
                                if (header)
@@ -159,8 +159,8 @@ MatcherProp * matcherprop_parse(gchar ** str)
                        g_free(expr);
 
                        return prop;
-               case SCORING_MATCH:
-               case SCORING_MATCHCASE:
+               case MATCHING_MATCH:
+               case MATCHING_MATCHCASE:
                        expr = matcher_parse_str(&tmp);
                        if (tmp == NULL) {
                                if (header)
@@ -397,13 +397,13 @@ static gboolean matcherprop_string_match(MatcherProp * prop, gchar * str)
                str = "";
 
        switch(prop->matchtype) {
-       case SCORING_REGEXP:
-       case SCORING_REGEXPCASE:
+       case MATCHING_REGEXP:
+       case MATCHING_REGEXPCASE:
                if (!prop->preg && (prop->error == 0)) {
                        prop->preg = g_new0(regex_t, 1);
                        if (regcomp(prop->preg, prop->expr,
                                    REG_NOSUB | REG_EXTENDED
-                                   | ((prop->matchtype == SCORING_REGEXPCASE)
+                                   | ((prop->matchtype == MATCHING_REGEXPCASE)
                                    ? REG_ICASE : 0)) != 0) {
                                prop->error = 1;
                                g_free(prop->preg);
@@ -417,10 +417,10 @@ static gboolean matcherprop_string_match(MatcherProp * prop, gchar * str)
                else
                        return 0;
 
-       case SCORING_MATCH:
+       case MATCHING_MATCH:
                return (strstr(str, prop->expr) != NULL);
 
-       case SCORING_MATCHCASE:
+       case MATCHING_MATCHCASE:
                g_strup(prop->expr);
                str1 = alloca(strlen(str) + 1);
                strcpy(str1, str);
@@ -440,41 +440,41 @@ gboolean matcherprop_match(MatcherProp * prop, MsgInfo * info)
        time_t t;
 
        switch(prop->criteria) {
-       case SCORING_ALL:
+       case MATCHING_ALL:
                return 1;
-       case SCORING_SUBJECT:
+       case MATCHING_SUBJECT:
                return matcherprop_string_match(prop, info->subject);
-       case SCORING_NOT_SUBJECT:
+       case MATCHING_NOT_SUBJECT:
                return !matcherprop_string_match(prop, info->subject);
-       case SCORING_FROM:
+       case MATCHING_FROM:
                return matcherprop_string_match(prop, info->from);
-       case SCORING_NOT_FROM:
+       case MATCHING_NOT_FROM:
                return !matcherprop_string_match(prop, info->from);
-       case SCORING_TO:
+       case MATCHING_TO:
                return matcherprop_string_match(prop, info->to);
-       case SCORING_NOT_TO:
+       case MATCHING_NOT_TO:
                return !matcherprop_string_match(prop, info->to);
-       case SCORING_CC:
+       case MATCHING_CC:
                return matcherprop_string_match(prop, info->cc);
-       case SCORING_NOT_CC:
+       case MATCHING_NOT_CC:
                return !matcherprop_string_match(prop, info->cc);
-       case SCORING_TO_OR_CC:
+       case MATCHING_TO_OR_CC:
                return matcherprop_string_match(prop, info->to)
                        || matcherprop_string_match(prop, info->cc);
-       case SCORING_NOT_TO_AND_NOT_CC:
+       case MATCHING_NOT_TO_AND_NOT_CC:
                return !(matcherprop_string_match(prop, info->to)
                || matcherprop_string_match(prop, info->cc));
-       case SCORING_AGE_SUP:
+       case MATCHING_AGE_GREATER:
                t = time(NULL);
                return ((t - info->date_t) / (60 * 60 * 24)) >= prop->age;
-       case SCORING_AGE_INF:
+       case MATCHING_AGE_LOWER:
                t = time(NULL);
                return ((t - info->date_t) / (60 * 60 * 24)) <= prop->age;
-       case SCORING_NEWSGROUPS:
+       case MATCHING_NEWSGROUPS:
                return matcherprop_string_match(prop, info->newsgroups);
-       case SCORING_NOT_NEWSGROUPS:
+       case MATCHING_NOT_NEWSGROUPS:
                return !matcherprop_string_match(prop, info->newsgroups);
-       case SCORING_HEADER:
+       case MATCHING_HEADER:
        default:
                return 0;
        }
@@ -493,7 +493,7 @@ MatcherList * matcherlist_parse(gchar ** str)
        gboolean bool_and = TRUE;
        gchar * save;
        MatcherList * cond;
-       gboolean main_bool_and;
+       gboolean main_bool_and = TRUE;
 
        tmp = * str;
 
@@ -556,7 +556,7 @@ void matcherlist_free(MatcherList * cond)
   skip the headers
  */
 
-static void matcherprop_skip_headers(FILE *fp)
+static void matcherlist_skip_headers(FILE *fp)
 {
        gchar buf[BUFFSIZE];
 
@@ -576,12 +576,12 @@ static gboolean matcherprop_match_one_header(MatcherProp * matcher,
        Header *header;
 
        switch(matcher->criteria) {
-       case SCORING_HEADER:
-       case SCORING_NOT_HEADER:
+       case MATCHING_HEADER:
+       case MATCHING_NOT_HEADER:
                header = procheader_parse_header(buf);
                if (procheader_headername_equal(header->name,
                                                matcher->header)) {
-                       if (matcher->criteria == SCORING_HEADER)
+                       if (matcher->criteria == MATCHING_HEADER)
                                result = matcherprop_string_match(matcher, header->body);
                        else
                                result = !matcherprop_string_match(matcher, header->body);
@@ -589,11 +589,11 @@ static gboolean matcherprop_match_one_header(MatcherProp * matcher,
                        return result;
                }
                break;
-       case SCORING_MESSAGEHEADERS:
-       case SCORING_MESSAGE:
+       case MATCHING_HEADERS_PART:
+       case MATCHING_MESSAGE:
                return matcherprop_string_match(matcher, buf);
-       case SCORING_NOT_MESSAGE:
-       case SCORING_NOT_MESSAGEHEADERS:
+       case MATCHING_NOT_MESSAGE:
+       case MATCHING_NOT_HEADERS_PART:
                return !matcherprop_string_match(matcher, buf);
        }
        return FALSE;
@@ -607,12 +607,12 @@ static gboolean matcherprop_match_one_header(MatcherProp * matcher,
 static gboolean matcherprop_criteria_headers(MatcherProp * matcher)
 {
        switch(matcher->criteria) {
-       case SCORING_HEADER:
-       case SCORING_NOT_HEADER:
-       case SCORING_MESSAGEHEADERS:
-       case SCORING_NOT_MESSAGEHEADERS:
-       case SCORING_MESSAGE:
-       case SCORING_NOT_MESSAGE:
+       case MATCHING_HEADER:
+       case MATCHING_NOT_HEADER:
+       case MATCHING_HEADERS_PART:
+       case MATCHING_NOT_HEADERS_PART:
+       case MATCHING_MESSAGE:
+       case MATCHING_NOT_MESSAGE:
                return TRUE;
        default:
                return FALSE;
@@ -631,8 +631,6 @@ static gboolean matcherlist_match_one_header(MatcherList * matchers,
        
        for(l = matchers->matchers ; l != NULL ; l = g_slist_next(l)) {
                MatcherProp * matcher = (MatcherProp *) l->data;
-               gboolean matched = FALSE;
-               gboolean partial_result;
 
                if (matcherprop_criteria_headers(matcher)) {
                        if (matcherprop_match_one_header(matcher, buf)) {
@@ -680,10 +678,10 @@ static gboolean matcherlist_match_headers(MatcherList * matchers, FILE * fp,
 static gboolean matcherprop_criteria_body(MatcherProp * matcher)
 {
        switch(matcher->criteria) {
-       case SCORING_BODY:
-       case SCORING_NOT_BODY:
-       case SCORING_MESSAGE:
-       case SCORING_NOT_MESSAGE:
+       case MATCHING_BODY_PART:
+       case MATCHING_NOT_BODY_PART:
+       case MATCHING_MESSAGE:
+       case MATCHING_NOT_MESSAGE:
                return TRUE;
        default:
                return FALSE;
@@ -698,13 +696,14 @@ static gboolean matcherprop_criteria_body(MatcherProp * matcher)
 static gboolean matcherprop_match_line(MatcherProp * matcher, gchar * line)
 {
        switch(matcher->criteria) {
-       case SCORING_BODY:
-       case SCORING_MESSAGE:
+       case MATCHING_BODY_PART:
+       case MATCHING_MESSAGE:
                return matcherprop_string_match(matcher, line);
-       case SCORING_NOT_BODY:
-       case SCORING_NOT_MESSAGE:
+       case MATCHING_NOT_BODY_PART:
+       case MATCHING_NOT_MESSAGE:
                return !matcherprop_string_match(matcher, line);
        }
+       return FALSE;
 }
 
 /*
@@ -783,7 +782,8 @@ gboolean matcherlist_match_file(MatcherList * matchers, MsgInfo * info,
                return result;
 
        file = procmsg_get_message_file(info);
-       g_return_if_fail(file != NULL);
+       if (file == NULL)
+               return FALSE;
 
        if ((fp = fopen(file, "r")) == NULL) {
                FILE_OP_ERROR(file, "fopen");
@@ -803,6 +803,9 @@ gboolean matcherlist_match_file(MatcherList * matchers, MsgInfo * info,
                                result = FALSE;
                }
        }
+       else {
+               matcherlist_skip_headers(fp);
+       }
        
        /* read the body */
        if (read_body) {
@@ -879,16 +882,16 @@ static void matcherprop_print(MatcherProp * matcher)
        }
 
        switch (matcher->matchtype) {
-       case SCORING_MATCH:
+       case MATCHING_MATCH:
                printf("match\n");
                break;
-       case SCORING_REGEXP:
+       case MATCHING_REGEXP:
                printf("regexp\n");
                break;
-       case SCORING_MATCHCASE:
+       case MATCHING_MATCHCASE:
                printf("matchcase\n");
                break;
-       case SCORING_REGEXPCASE:
+       case MATCHING_REGEXPCASE:
                printf("regexpcase\n");
                break;
        }
@@ -908,3 +911,125 @@ static void matcherprop_print(MatcherProp * matcher)
        printf("error: %i\n",  matcher->error);
 }
 #endif
+
+gchar * matcherprop_to_string(MatcherProp * matcher)
+{
+       gchar * matcher_str;
+       gchar * criteria_str;
+       gchar * matchtype_str;
+       int i;
+       gchar * p;
+       gint count;
+       gchar * expr_str;
+       gchar * out;
+
+       criteria_str = NULL;
+       for(i = 0 ; i < (int) (sizeof(matchparser_tab) / sizeof(MatchParser)) ;
+           i++) {
+               if (matchparser_tab[i].id == matcher->criteria)
+                       criteria_str = matchparser_tab[i].str;
+       }
+       if (criteria_str == NULL)
+               return NULL;
+
+       switch(matcher->criteria) {
+       case MATCHING_AGE_GREATER:
+       case MATCHING_AGE_LOWER:
+               return g_strdup_printf("%s %i", criteria_str, matcher->age);
+               break;
+       case MATCHING_ALL:
+               return g_strdup(criteria_str);
+       }
+
+       matchtype_str = NULL;
+       for(i = 0 ; i < (int) (sizeof(matchparser_tab) / sizeof(MatchParser)) ;
+           i++) {
+               if (matchparser_tab[i].id == matcher->matchtype)
+                       matchtype_str = matchparser_tab[i].str;
+       }
+
+       if (matchtype_str == NULL)
+               return NULL;
+
+       switch (matcher->matchtype) {
+       case MATCHING_MATCH:
+       case MATCHING_MATCHCASE:
+               count = 0;
+               for(p = matcher->expr; *p != 0 ; p++)
+                       if (*p == '\"') count ++;
+               
+               expr_str = g_new(char, strlen(matcher->expr) + count + 1);
+
+               for(p = matcher->expr, out = expr_str ; *p != 0 ; p++, out++) {
+                       if (*p == '\"') {
+                               *out = '\\'; out++;
+                               *out = '\"';
+                       }
+                       else
+                               *out = *p;
+               }
+               * out = '\0';
+
+               if (matcher->header)
+                       matcher_str =
+                               g_strdup_printf("%s \"%s\" %s \"%s\"",
+                                          criteria_str, matcher->header,
+                                          matchtype_str, expr_str);
+               else
+                       matcher_str =
+                               g_strdup_printf("%s %s \"%s\"", criteria_str,
+                                               matchtype_str, expr_str);
+               
+               g_free(expr_str);
+               
+               break;
+
+       case MATCHING_REGEXP:
+       case MATCHING_REGEXPCASE:
+
+               if (matcher->header)
+                       matcher_str =
+                               g_strdup_printf("%s \"%s\" %s /%s/",
+                                               criteria_str, matcher->header,
+                                               matchtype_str, matcher->expr);
+               else
+                       matcher_str =
+                               g_strdup_printf("%s %s /%s/", criteria_str,
+                                               matchtype_str, matcher->expr);
+
+               break;
+       }
+
+       return matcher_str;
+}
+
+gchar * matcherlist_to_string(MatcherList * matchers)
+{
+       gint count;
+       gchar ** vstr;
+       GSList * l;
+       gchar ** cur_str;
+       gchar * result;
+
+       count = g_slist_length(matchers->matchers);
+       vstr = g_new(gchar *, count + 1);
+
+       for (l = matchers->matchers, cur_str = vstr ; l != NULL ;
+            l = g_slist_next(l), cur_str ++) {
+               *cur_str = matcherprop_to_string((MatcherProp *) l->data);
+               if (*cur_str == NULL)
+                       break;
+       }
+       *cur_str = NULL;
+       
+       if (matchers->bool_and)
+               result = g_strjoinv(" & ", vstr);
+       else
+               result = g_strjoinv(" | ", vstr);
+
+       for(cur_str = vstr ; *cur_str != NULL ; cur_str ++)
+               g_free(*cur_str);
+       g_free(vstr);
+
+       return result;
+}
index ff54bfbbab0b4750dbf3a0bdc05636a0c4b5e0a9..85c77617b86724e92cc72addaaed260855760628 100644 (file)
@@ -8,34 +8,34 @@
 #include "procmsg.h"
 
 enum {
-       SCORING_ALL,
-       SCORING_SUBJECT,
-       SCORING_NOT_SUBJECT,
-       SCORING_FROM,
-       SCORING_NOT_FROM,
-       SCORING_TO,
-       SCORING_NOT_TO,
-       SCORING_CC,
-       SCORING_NOT_CC,
-       SCORING_TO_OR_CC,
-       SCORING_NOT_TO_AND_NOT_CC,
-       SCORING_AGE_SUP,
-       SCORING_AGE_INF,
-       SCORING_NEWSGROUPS,
-       SCORING_NOT_NEWSGROUPS,
-       SCORING_HEADER,
-       SCORING_NOT_HEADER,
-       SCORING_MESSAGE,
-       SCORING_NOT_MESSAGE,
-       SCORING_MESSAGEHEADERS,
-       SCORING_NOT_MESSAGEHEADERS,
-       SCORING_BODY,
-       SCORING_NOT_BODY,
-       SCORING_SCORE,
-       SCORING_MATCH,
-       SCORING_REGEXP,
-       SCORING_MATCHCASE,
-       SCORING_REGEXPCASE
+       MATCHING_ALL,
+       MATCHING_SUBJECT,
+       MATCHING_NOT_SUBJECT,
+       MATCHING_FROM,
+       MATCHING_NOT_FROM,
+       MATCHING_TO,
+       MATCHING_NOT_TO,
+       MATCHING_CC,
+       MATCHING_NOT_CC,
+       MATCHING_TO_OR_CC,
+       MATCHING_NOT_TO_AND_NOT_CC,
+       MATCHING_AGE_GREATER,
+       MATCHING_AGE_LOWER,
+       MATCHING_NEWSGROUPS,
+       MATCHING_NOT_NEWSGROUPS,
+       MATCHING_HEADER,
+       MATCHING_NOT_HEADER,
+       MATCHING_MESSAGE,
+       MATCHING_NOT_MESSAGE,
+       MATCHING_HEADERS_PART,
+       MATCHING_NOT_HEADERS_PART,
+       MATCHING_BODY_PART,
+       MATCHING_NOT_BODY_PART,
+       MATCHING_SCORE,
+       MATCHING_MATCH,
+       MATCHING_REGEXP,
+       MATCHING_MATCHCASE,
+       MATCHING_REGEXPCASE
 };
 
 struct _MatcherProp {
@@ -76,5 +76,7 @@ gint matcher_parse_number(gchar ** str);
 gboolean matcher_parse_boolean_op(gchar ** str);
 gchar * matcher_parse_regexp(gchar ** str);
 gchar * matcher_parse_str(gchar ** str);
+gchar * matcherprop_to_string(MatcherProp * matcher);
+gchar * matcherlist_to_string(MatcherList * matchers);
 
 #endif
index 603ba3241bbc597ee83c2961a8e7034edd04da23..0a98079854c9811adb5799d1d00fb6bb9fb11600 100644 (file)
@@ -88,6 +88,8 @@ static void prefs_display_header_key_pressed  (GtkWidget      *widget,
                                                 gpointer        data);
 static void prefs_display_header_ok            (void);
 static void prefs_display_header_cancel                (void);
+static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
+                                        gpointer data);
 
 static gchar *defaults[] =
 {
@@ -201,7 +203,8 @@ static void prefs_display_header_create(void)
        gtk_window_set_title (GTK_WINDOW(window),
                              _("Display header setting"));
        gtk_signal_connect (GTK_OBJECT(window), "delete_event",
-                           GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), NULL);
+                           GTK_SIGNAL_FUNC(prefs_display_header_deleted),
+                           NULL);
        gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
                            GTK_SIGNAL_FUNC(prefs_display_header_key_pressed),
                            NULL);
@@ -629,3 +632,10 @@ static void prefs_display_header_cancel(void)
        prefs_display_header_read_config();
        gtk_widget_hide(dispheader.window);
 }
+
+static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
+                                        gpointer data)
+{
+       prefs_display_header_cancel();
+       return TRUE;
+}
index c2bbdf0869fe195bd8896ab7fcf3fc52f9f55e01..9297b645f948443b550b375f1b873150c059efab 100644 (file)
@@ -21,6 +21,8 @@ static PrefParam param[] = {
         NULL, NULL, NULL},
        {"sort_descending", "FALSE", &tmp_prefs.sort_descending, P_BOOL,
         NULL, NULL, NULL},
+       {"enable_thread", "FALSE", &tmp_prefs.enable_thread, P_BOOL,
+        NULL, NULL, NULL},
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
 
index 84fa4d531aa113830a7bdea7de4758873f7c0aa9..6b03f5232174d3ccc9572cdf775f94dd0c1b62fd 100644 (file)
@@ -17,6 +17,8 @@ struct _PrefsFolderItem {
 
        gboolean sort_descending;
 
+       gboolean enable_thread;
+
        GSList * scoring;
 };
 
@@ -28,5 +30,7 @@ void prefs_folder_item_set_config(FolderItem * item,
                                  int sort_type, gint sort_mode);
 PrefsFolderItem * prefs_folder_item_new(void);
 void prefs_folder_item_free(PrefsFolderItem * prefs);
+gint prefs_folder_item_get_sort_type(FolderItem * item);
+gint prefs_folder_item_get_sort_mode(FolderItem * item);
 
 #endif
index 451145df2762d662a5f339ed4e743c177d36ad3b..430fc34ae3297b29cf080f4c164c27920cfcf6da 100644 (file)
@@ -101,6 +101,8 @@ static void prefs_headers_close             (GtkButton      *button);
 */
 static void prefs_headers_ok           (GtkButton      *button);
 static void prefs_headers_cancel       (GtkButton      *button);
+static gint prefs_headers_deleted(GtkWidget *widget, GdkEventAny *event,
+                                 gpointer data);
 
 static PrefsAccount * cur_ac = NULL;
 
@@ -187,7 +189,7 @@ static void prefs_headers_create(void)
        gtk_window_set_title (GTK_WINDOW(window),
                              _("Headers setting"));
        gtk_signal_connect (GTK_OBJECT(window), "delete_event",
-                           GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), NULL);
+                           GTK_SIGNAL_FUNC(prefs_headers_deleted), NULL);
        gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
                            GTK_SIGNAL_FUNC(prefs_headers_key_pressed), NULL);
        gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
@@ -663,3 +665,10 @@ static void prefs_headers_cancel(GtkButton *button)
        prefs_headers_read_config(cur_ac); 
        gtk_widget_hide(headers.window);
 }
+
+static gint prefs_headers_deleted(GtkWidget *widget, GdkEventAny *event,
+                                 gpointer data)
+{
+       prefs_headers_cancel(widget);
+       return TRUE;
+}
index 22fce1034f273135e0f13c1cd06af80b78903cb8..667e6c89794f5b971c8868bf323c30c846a7bcf4 100644 (file)
@@ -211,6 +211,9 @@ GSList *procheader_get_header_list(FILE *fp)
        g_return_val_if_fail(fp != NULL, NULL);
 
        while (procheader_get_unfolded_line(buf, sizeof(buf), fp) != NULL) {
+               if (header = procheader_parse_header(buf))
+                       g_ptr_array_add(headers, header);
+               /*
                if (*buf == ':') continue;
                for (p = buf; *p && *p != ' '; p++) {
                        if (*p == ':') {
@@ -225,6 +228,7 @@ GSList *procheader_get_header_list(FILE *fp)
                                break;
                        }
                }
+               */
        }
 
        return hlist;
@@ -242,6 +246,9 @@ GPtrArray *procheader_get_header_array(FILE *fp)
        headers = g_ptr_array_new();
 
        while (procheader_get_unfolded_line(buf, sizeof(buf), fp) != NULL) {
+               if (header = procheader_parse_header(buf))
+                       g_ptr_array_add(headers, header);
+               /*
                if (*buf == ':') continue;
                for (p = buf; *p && *p != ' '; p++) {
                        if (*p == ':') {
@@ -255,6 +262,7 @@ GPtrArray *procheader_get_header_array(FILE *fp)
                                g_ptr_array_add(headers, header);
                                break;
                        }
+               */
                }
        }
 
@@ -273,6 +281,9 @@ GPtrArray *procheader_get_header_array_asis(FILE *fp)
        headers = g_ptr_array_new();
 
        while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) {
+               if (header = procheader_parse_header(buf))
+                       g_ptr_array_add(headers, header);
+                       /*
                if (*buf == ':') continue;
                for (p = buf; *p && *p != ' '; p++) {
                        if (*p == ':') {
@@ -286,6 +297,7 @@ GPtrArray *procheader_get_header_array_asis(FILE *fp)
                                break;
                        }
                }
+                       */
        }
 
        return headers;
@@ -342,7 +354,7 @@ gboolean procheader_headername_equal(char * hdr1, char * hdr2)
                len2--;
        if (len1 != len2)
                return 0;
-       return (strncasecmp(hdr1, hdr2, len1) == 0);
+       return (g_strncasecmp(hdr1, hdr2, len1) == 0);
 }
 
 /*
@@ -393,8 +405,8 @@ void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
 
                if (hp->body == NULL)
                        hp->body = g_strdup(p);
-               else if (!strcasecmp(hp->name, "To:") ||
-                        !strcasecmp(hp->name, "Cc:")) {
+               else if (procheader_headername_equal(hp->name, "To") ||
+                        procheader_headername_equal(hp->name, "Cc")) {
                        gchar *tp = hp->body;
                        hp->body = g_strconcat(tp, ", ", p, NULL);
                        g_free(tp);
index 7e7cdde08d592d15e005d64c972eb8da8f5031d7..77dbacfad88e99b24dc6c2026ed39559d67a9bb6 100644 (file)
@@ -39,7 +39,7 @@ ScoringProp * scoringprop_parse(gchar ** str)
                return NULL;
        }
 
-       if (key != SCORING_SCORE) {
+       if (key != MATCHING_SCORE) {
                matcherlist_free(matchers);
                * str = NULL;
                return NULL;
index 30b1a20699f88dbaf5802c02c1aed45962d776dc..045e0a71fd87001b5f726c0c92722343c3430c65 100644 (file)
@@ -74,6 +74,7 @@
 #include "addressbook.h"
 #include "addr_compl.h"
 #include "scoring.h"
+#include "prefs_folder_item.h"
 
 #include "pixmaps/dir-open.xpm"
 #include "pixmaps/mark.xpm"
@@ -1567,7 +1568,8 @@ static void summary_set_header(gchar *text[], MsgInfo *msginfo)
        text[S_COL_FROM] = msginfo->fromname ? msginfo->fromname :
                _("(No From)");
        if (prefs_common.swap_from && msginfo->from && msginfo->to &&
-           cur_account && cur_account->address) {
+           cur_account && cur_account->address &&
++          !MSG_IS_NEWS(msginfo->flags)) {
                gchar *from;
 
                Xalloca(from, strlen(msginfo->from) + 1, return);
index c312771cd121f8476e29816cf79224ef23573cf7..947f2e9bb761fc06b8ac3cc5cb0fcb6f8b66a17b 100644 (file)
@@ -958,7 +958,8 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
                for (i = 0; i < headers->len; i++) {
                        header = g_ptr_array_index(headers, i);
 
-                       if (!g_strcasecmp(header->name, dp->name)) {
+                       if (procheader_headername_equal(header->name,
+                                                       dp->name)) {
                                if (dp->hidden)
                                        procheader_header_free(header);
                                else
@@ -999,15 +1000,16 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
                                header->name, -1);
                gtk_text_insert(text, textview->boldfont, NULL, NULL, ":", 2);
 
-               if (!g_strcasecmp(header->name, "Subject") ||
-                   !g_strcasecmp(header->name, "From")    ||
-                   !g_strcasecmp(header->name, "To")      ||
-                   !g_strcasecmp(header->name, "Cc"))
+               if (procheader_headername_equal(header->name, "Subject") ||
+                   procheader_headername_equal(header->name, "From")    ||
+                   procheader_headername_equal(header->name, "To")      ||
+                   procheader_headername_equal(header->name, "Cc"))
                        unfold_line(header->body);
 
                if (prefs_common.enable_color &&
-                   (!strncmp(header->name, "X-Mailer", 8) ||
-                    !strncmp(header->name, "X-Newsreader", 12)) &&
+                   (procheader_headername_equal(header->name, "X-Mailer") ||
+                    procheader_headername_equal(header->name,
+                                                "X-Newsreader")) &&
                    strstr(header->body, "Sylpheed") != NULL)
                        gtk_text_insert(text, NULL, &emphasis_color, NULL,
                                        header->body, -1);