2007-07-27 [paul] 2.10.0cvs74
authorPaul Mangan <paul@claws-mail.org>
Fri, 27 Jul 2007 14:19:05 +0000 (14:19 +0000)
committerPaul Mangan <paul@claws-mail.org>
Fri, 27 Jul 2007 14:19:05 +0000 (14:19 +0000)
* src/Makefile.am
* src/filtering.c
* src/folder.c
* src/mainwindow.c
* src/matcher.c
* src/matcher.h
* src/matcher_parser_parse.y
* src/procmsg.c
* src/procmsg.h
* src/stock_pixmap.c
* src/stock_pixmap.h
* src/summaryview.c
* src/summaryview.h
* src/toolbar.c
* src/toolbar.h
* src/pixmaps/watchthread.xpm
add 'watch thread' feature

19 files changed:
ChangeLog
PATCHSETS
configure.ac
src/Makefile.am
src/filtering.c
src/folder.c
src/mainwindow.c
src/matcher.c
src/matcher.h
src/matcher_parser_parse.y
src/pixmaps/watchthread.xpm [new file with mode: 0644]
src/procmsg.c
src/procmsg.h
src/stock_pixmap.c
src/stock_pixmap.h
src/summaryview.c
src/summaryview.h
src/toolbar.c
src/toolbar.h

index dfeb0a4..585d6a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2007-07-27 [paul]      2.10.0cvs74
+
+       * src/Makefile.am
+       * src/filtering.c
+       * src/folder.c
+       * src/mainwindow.c
+       * src/matcher.c
+       * src/matcher.h
+       * src/matcher_parser_parse.y
+       * src/procmsg.c
+       * src/procmsg.h
+       * src/stock_pixmap.c
+       * src/stock_pixmap.h
+       * src/summaryview.c
+       * src/summaryview.h
+       * src/toolbar.c
+       * src/toolbar.h
+       * src/pixmaps/watchthread.xpm
+               add 'watch thread' feature
+
 2007-07-27 [paul]      2.10.0cvs73
 
        * src/prefs_folder_item.c
index 48ca564..c976203 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.94.2.142 -r 1.94.2.143 src/messageview.c;  ) > 2.10.0cvs71.patchset
 ( cvs diff -u -r 1.395.2.315 -r 1.395.2.316 src/summaryview.c;  ) > 2.10.0cvs72.patchset
 ( cvs diff -u -r 1.52.2.42 -r 1.52.2.43 src/prefs_folder_item.c;  ) > 2.10.0cvs73.patchset
+( cvs diff -u -r 1.155.2.72 -r 1.155.2.73 src/Makefile.am;  cvs diff -u -r 1.60.2.35 -r 1.60.2.36 src/filtering.c;  cvs diff -u -r 1.213.2.151 -r 1.213.2.152 src/folder.c;  cvs diff -u -r 1.274.2.202 -r 1.274.2.203 src/mainwindow.c;  cvs diff -u -r 1.75.2.44 -r 1.75.2.45 src/matcher.c;  cvs diff -u -r 1.39.2.14 -r 1.39.2.15 src/matcher.h;  cvs diff -u -r 1.25.2.30 -r 1.25.2.31 src/matcher_parser_parse.y;  cvs diff -u -r 1.150.2.100 -r 1.150.2.101 src/procmsg.c;  cvs diff -u -r 1.60.2.46 -r 1.60.2.47 src/procmsg.h;  cvs diff -u -r 1.25.2.44 -r 1.25.2.45 src/stock_pixmap.c;  cvs diff -u -r 1.18.2.30 -r 1.18.2.31 src/stock_pixmap.h;  cvs diff -u -r 1.395.2.316 -r 1.395.2.317 src/summaryview.c;  cvs diff -u -r 1.68.2.39 -r 1.68.2.40 src/summaryview.h;  cvs diff -u -r 1.43.2.79 -r 1.43.2.80 src/toolbar.c;  cvs diff -u -r 1.19.2.21 -r 1.19.2.22 src/toolbar.h;  diff -u /dev/null src/pixmaps/watchthread.xpm;  ) > 2.10.0cvs74.patchset
index edd5702..39cb0ad 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=10
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=73
+EXTRA_VERSION=74
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 2e0f8f1..b0282e3 100644 (file)
@@ -447,6 +447,7 @@ EXTRA_DIST = \
        pixmaps/trash_mark.xpm \
        pixmaps/moved.xpm \
        pixmaps/copied.xpm \
+       pixmaps/watchthread.xpm \
        pixmaps/empty.xpm
 
 
index 441592c..fc46d00 100644 (file)
@@ -433,6 +433,10 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                 procmsg_msginfo_set_flags(info, MSG_IGNORE_THREAD, 0);
                 return TRUE;
 
+       case MATCHACTION_WATCH:
+                procmsg_msginfo_set_flags(info, MSG_WATCH_THREAD, 0);
+                return TRUE;
+
        case MATCHACTION_ADD_TO_ADDRESSBOOK:
                {
                        AddressDataSource *book = NULL;
@@ -912,6 +916,7 @@ gchar *filteringaction_to_string(gchar *dest, gint destlen, FilteringAction *act
        case MATCHACTION_STOP:
        case MATCHACTION_HIDE:
        case MATCHACTION_IGNORE:
+       case MATCHACTION_WATCH:
        case MATCHACTION_CLEAR_TAGS:
                g_snprintf(dest, destlen, "%s", command_str);
                return dest;
index 5ed9790..f3a0945 100644 (file)
@@ -2094,6 +2094,9 @@ gint folder_item_scan_full(FolderItem *item, gboolean filtering)
                if (!MSG_IS_IGNORE_THREAD(msginfo->flags) && procmsg_msg_has_flagged_parent(msginfo, MSG_IGNORE_THREAD)) {
                        procmsg_msginfo_change_flags(msginfo, MSG_IGNORE_THREAD, 0, MSG_NEW | MSG_UNREAD, 0);
                }
+               if (!MSG_IS_WATCH_THREAD(msginfo->flags) && procmsg_msg_has_flagged_parent(msginfo, MSG_WATCH_THREAD)) {
+                       procmsg_msginfo_set_flags(msginfo, MSG_WATCH_THREAD, 0);
+               }
                if(prefs_common.thread_by_subject && !msginfo->inreplyto &&
                        !msginfo->references && !MSG_IS_IGNORE_THREAD(msginfo->flags) &&
                        (parent_msginfo = subject_table_lookup(subject_table, msginfo->subject)))
@@ -2733,6 +2736,9 @@ static void copy_msginfo_flags(MsgInfo *source, MsgInfo *dest)
        if (procmsg_msg_has_flagged_parent(dest, MSG_IGNORE_THREAD))
                perm_flags |= MSG_IGNORE_THREAD;
 
+       if (procmsg_msg_has_flagged_parent(dest, MSG_WATCH_THREAD))
+               perm_flags |= MSG_WATCH_THREAD;
+
        /* Unset tmp flags that should not be copied */
        tmp_flags &= ~(MSG_MOVE | MSG_COPY | MSG_MOVE_DONE);
 
index 2a05e39..ef829df 100644 (file)
@@ -271,6 +271,12 @@ static void ignore_thread_cb               (MainWindow     *mainwin,
 static void unignore_thread_cb         (MainWindow     *mainwin, 
                                         guint           action,
                                         GtkWidget      *widget);
+static void watch_thread_cb            (MainWindow     *mainwin, 
+                                        guint           action,
+                                        GtkWidget      *widget);
+static void unwatch_thread_cb          (MainWindow     *mainwin, 
+                                        guint           action,
+                                        GtkWidget      *widget);
 static void lock_msgs_cb               (MainWindow     *mainwin, 
                                         guint           action,
                                         GtkWidget      *widget);
@@ -816,6 +822,8 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_Message/_Mark/Mark all _read"),  NULL, mark_all_read_cb, 0, NULL},
        {N_("/_Message/_Mark/Ignore thread"),   NULL, ignore_thread_cb, 0, NULL},
        {N_("/_Message/_Mark/Unignore thread"), NULL, unignore_thread_cb, 0, NULL},
+       {N_("/_Message/_Mark/Watch thread"),    NULL, watch_thread_cb, 0, NULL},
+       {N_("/_Message/_Mark/Unwatch thread"),  NULL, unwatch_thread_cb, 0, NULL},
        {N_("/_Message/_Mark/---"),             NULL, NULL, 0, "<Separator>"},
        {N_("/_Message/_Mark/Mark as _spam"),   NULL, mark_as_spam_cb, 1, NULL},
        {N_("/_Message/_Mark/Mark as _ham"),    NULL, mark_as_spam_cb, 0, NULL},
@@ -3717,6 +3725,18 @@ static void unignore_thread_cb(MainWindow *mainwin, guint action,
        summary_unignore_thread(mainwin->summaryview);
 }
 
+static void watch_thread_cb(MainWindow *mainwin, guint action,
+                           GtkWidget *widget)
+{
+       summary_watch_thread(mainwin->summaryview);
+}
+
+static void unwatch_thread_cb(MainWindow *mainwin, guint action,
+                           GtkWidget *widget)
+{
+       summary_unwatch_thread(mainwin->summaryview);
+}
+
 static void lock_msgs_cb(MainWindow *mainwin, guint action,
                            GtkWidget *widget)
 {
index 8c8aef9..f25d61c 100644 (file)
@@ -81,6 +81,8 @@ static const MatchParser matchparser_tab[] = {
        {MATCHCRITERIA_NOT_COLORLABEL, "~colorlabel"},
        {MATCHCRITERIA_IGNORE_THREAD, "ignore_thread"},
        {MATCHCRITERIA_NOT_IGNORE_THREAD, "~ignore_thread"},
+       {MATCHCRITERIA_WATCH_THREAD, "watch_thread"},
+       {MATCHCRITERIA_NOT_WATCH_THREAD, "~watch_thread"},
        {MATCHCRITERIA_SPAM, "spam"},
        {MATCHCRITERIA_NOT_SPAM, "~spam"},
 
@@ -160,6 +162,7 @@ static const MatchParser matchparser_tab[] = {
        {MATCHACTION_STOP, "stop"},
        {MATCHACTION_HIDE, "hide"},
        {MATCHACTION_IGNORE, "ignore"},
+       {MATCHACTION_WATCH, "watch"},
        {MATCHACTION_ADD_TO_ADDRESSBOOK, "add_to_addressbook"},
        {MATCHACTION_SET_TAG, "set_tag"},
        {MATCHACTION_UNSET_TAG, "unset_tag"},
@@ -805,6 +808,10 @@ gboolean matcherprop_match(MatcherProp *prop,
                return MSG_IS_IGNORE_THREAD(info->flags);
        case MATCHCRITERIA_NOT_IGNORE_THREAD:
                return !MSG_IS_IGNORE_THREAD(info->flags);
+       case MATCHCRITERIA_WATCH_THREAD:
+               return MSG_IS_WATCH_THREAD(info->flags);
+       case MATCHCRITERIA_NOT_WATCH_THREAD:
+               return !MSG_IS_WATCH_THREAD(info->flags);
        case MATCHCRITERIA_SUBJECT:
                return matcherprop_string_match(prop, info->subject,
                                                prefs_common_translated_header_name("Subject:"));
@@ -1648,6 +1655,8 @@ gboolean matcherlist_match(MatcherList *matchers, MsgInfo *info)
                case MATCHCRITERIA_NOT_COLORLABEL:
                case MATCHCRITERIA_IGNORE_THREAD:
                case MATCHCRITERIA_NOT_IGNORE_THREAD:
+               case MATCHCRITERIA_WATCH_THREAD:
+               case MATCHCRITERIA_NOT_WATCH_THREAD:
                case MATCHCRITERIA_SUBJECT:
                case MATCHCRITERIA_NOT_SUBJECT:
                case MATCHCRITERIA_FROM:
@@ -1841,6 +1850,8 @@ gchar *matcherprop_to_string(MatcherProp *matcher)
        case MATCHCRITERIA_NOT_PARTIAL:
        case MATCHCRITERIA_IGNORE_THREAD:
        case MATCHCRITERIA_NOT_IGNORE_THREAD:
+       case MATCHCRITERIA_WATCH_THREAD:
+       case MATCHCRITERIA_NOT_WATCH_THREAD:
        case MATCHCRITERIA_TAGGED:
        case MATCHCRITERIA_NOT_TAGGED:
                return g_strdup(criteria_str);
index 337b73c..5b00a1a 100644 (file)
@@ -83,6 +83,7 @@ enum {
        MC_(PARTIAL), MC_(NOT_PARTIAL),
        MC_(COLORLABEL), MC_(NOT_COLORLABEL),
        MC_(IGNORE_THREAD), MC_(NOT_IGNORE_THREAD),
+       MC_(WATCH_THREAD), MC_(NOT_WATCH_THREAD),
        MC_(SUBJECT), MC_(NOT_SUBJECT),
        MC_(FROM), MC_(NOT_FROM),
        MC_(TO), MC_(NOT_TO),
@@ -134,6 +135,7 @@ enum {
        MA_(STOP),
        MA_(HIDE),
        MA_(IGNORE),
+       MA_(WATCH),
        MA_(ADD_TO_ADDRESSBOOK),
        MA_(SET_TAG),
        MA_(UNSET_TAG),
index 5a6839e..c06bcdd 100644 (file)
@@ -332,9 +332,10 @@ int matcher_parserwrap(void)
 %token MATCHER_PARTIAL MATCHER_NOT_PARTIAL
 %token MATCHER_COLORLABEL MATCHER_NOT_COLORLABEL
 %token MATCHER_IGNORE_THREAD MATCHER_NOT_IGNORE_THREAD
+%token MATCHER_WATCH_THREAD MATCHER_NOT_WATCH_THREAD
 %token MATCHER_CHANGE_SCORE MATCHER_SET_SCORE
 %token MATCHER_ADD_TO_ADDRESSBOOK
-%token MATCHER_STOP MATCHER_HIDE MATCHER_IGNORE
+%token MATCHER_STOP MATCHER_HIDE MATCHER_IGNORE MATCHER_WATCH
 %token MATCHER_SPAM MATCHER_NOT_SPAM
 %token MATCHER_TAG MATCHER_NOT_TAG MATCHER_SET_TAG MATCHER_UNSET_TAG
 %token MATCHER_TAGGED MATCHER_NOT_TAGGED MATCHER_CLEAR_TAGS
@@ -760,6 +761,20 @@ MATCHER_ALL
        criteria = MATCHCRITERIA_NOT_IGNORE_THREAD;
        prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
 }
+| MATCHER_WATCH_THREAD
+{
+       gint criteria = 0;
+
+       criteria = MATCHCRITERIA_WATCH_THREAD;
+       prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
+}
+| MATCHER_NOT_WATCH_THREAD
+{
+       gint criteria = 0;
+
+       criteria = MATCHCRITERIA_NOT_WATCH_THREAD;
+       prop = matcherprop_new(criteria, NULL, 0, NULL, 0);
+}
 | MATCHER_SUBJECT match_type MATCHER_STRING
 {
        gint criteria = 0;
diff --git a/src/pixmaps/watchthread.xpm b/src/pixmaps/watchthread.xpm
new file mode 100644 (file)
index 0000000..fcd163d
--- /dev/null
@@ -0,0 +1,49 @@
+/* XPM */
+static char * watchthread_xpm[] = {
+"16 16 30 1",
+"      c None",
+".     c #1B2B3C",
+"+     c #000000",
+"@     c #B6B6B6",
+"#     c #264057",
+"$     c #233B51",
+"%     c #253F56",
+"&     c #374E63",
+"*     c #606B76",
+"=     c #2B2B2B",
+"-     c #CACACA",
+";     c #334F68",
+">     c #E7E7E7",
+",     c #FFFFFF",
+"'     c #314E6C",
+")     c #597187",
+"!     c #262626",
+"~     c #DFDFDF",
+"{     c #F5F5F5",
+"]     c #3B5673",
+"^     c #506881",
+"/     c #E1E1E1",
+"(     c #A0A0A0",
+"_     c #F0F0F0",
+":     c #8091A3",
+"<     c #3A5572",
+"[     c #EBEBEB",
+"}     c #7D8EA0",
+"|     c #303030",
+"1     c #1F262D",
+"                ",
+"                ",
+"                ",
+"                ",
+"    .+++++      ",
+"   .@#$%&*=     ",
+"  +-;>,+')@!    ",
+" +~{],,+'^/(+   ",
+"  +_:'''<<~+    ",
+"   +[}<<}[+     ",
+"    |++1++      ",
+"                ",
+"                ",
+"                ",
+"                ",
+"                "};
index f980c84..4f54ab7 100644 (file)
@@ -1848,6 +1848,9 @@ void procmsg_msginfo_set_flags(MsgInfo *msginfo, MsgPermFlags perm_flags, MsgTmp
        if ((perm_flags & MSG_IGNORE_THREAD) || (perm_flags_old & MSG_IGNORE_THREAD)) {
                perm_flags_new &= ~(MSG_NEW | MSG_UNREAD);
        }
+       if ((perm_flags & MSG_WATCH_THREAD) || (perm_flags_old & MSG_WATCH_THREAD)) {
+               perm_flags_new &= ~(MSG_IGNORE_THREAD);
+       }
 
        if (perm_flags_old != perm_flags_new) {
                folder_item_change_msg_flags(msginfo->folder, msginfo, perm_flags_new);
@@ -1926,6 +1929,9 @@ void procmsg_msginfo_change_flags(MsgInfo *msginfo,
        if ((add_perm_flags & MSG_IGNORE_THREAD) || (perm_flags_old & MSG_IGNORE_THREAD)) {
                perm_flags_new &= ~(MSG_NEW | MSG_UNREAD);
        }
+       if ((add_perm_flags & MSG_WATCH_THREAD) || (perm_flags_old & MSG_WATCH_THREAD)) {
+               perm_flags_new &= ~(MSG_IGNORE_THREAD);
+       }
 
        if (perm_flags_old != perm_flags_new) {
                folder_item_change_msg_flags(msginfo->folder, msginfo, perm_flags_new);
index 264dd40..c7fee40 100644 (file)
@@ -47,7 +47,6 @@ typedef GSList MsgNumberList;
 #define MSG_DELETED            (1U << 3)
 #define MSG_REPLIED            (1U << 4)
 #define MSG_FORWARDED          (1U << 5)
-#define MSG_POSTFILTERED       (1U << 14)
 
 #define MSG_CLABEL_SBIT        (6)             /* start bit of color label */
 /* color labels use 4 bits: 6, 7, 8, 9; bit weight is 7<8<9<6,
@@ -86,6 +85,8 @@ typedef GSList MsgNumberList;
 #define MSG_LOCKED             (1U << 11)   /* msg is locked  */
 #define MSG_RETRCPT_SENT       (1U << 12)   /* new one */ 
 #define MSG_SPAM               (1U << 13)   /* new one */ 
+#define MSG_POSTFILTERED       (1U << 14)
+#define MSG_WATCH_THREAD       (1U << 15)   /* watch threads */
                                                
 /* RESERVED */
 #define        MSG_RESERVED_CLAWS      (1U << 30)   /* for claws-mail */
@@ -159,6 +160,7 @@ typedef guint32 MsgTmpFlags;
 #define MSG_IS_RETRCPT_PENDING(msg)    (((msg).perm_flags & MSG_RETRCPT_PENDING) != 0)
 #define MSG_IS_RETRCPT_SENT(msg)       (((msg).perm_flags & MSG_RETRCPT_SENT) != 0)
 #define MSG_IS_SPAM(msg)               (((msg).perm_flags & MSG_SPAM) != 0)
+#define MSG_IS_WATCH_THREAD(msg)       (((msg).perm_flags & MSG_WATCH_THREAD) != 0)
 
 #define MSGINFO_UPDATE_HOOKLIST "msginfo_update"
 #define MAIL_FILTERING_HOOKLIST "mail_filtering_hooklist"
index f3b8987..dda4d16 100644 (file)
 #include "pixmaps/moved.xpm"
 #include "pixmaps/copied.xpm"
 #include "pixmaps/selection.xpm"
+#include "pixmaps/watchthread.xpm"
 #include "pixmaps/empty.xpm"
 
 typedef struct _StockPixmapData        StockPixmapData;
@@ -353,6 +354,7 @@ static StockPixmapData pixmaps[] =
        {moved_xpm                              , NULL, NULL, "moved", NULL},
        {copied_xpm                             , NULL, NULL, "copied", NULL},
        {selection_xpm                          , NULL, NULL, "selection", NULL},
+       {watchthread_xpm                        , NULL, NULL, "watchthread", NULL},
         {empty_xpm                              , NULL, NULL, "empty" , NULL}
 };
 
index e5e0d72..821f8b4 100644 (file)
@@ -167,6 +167,7 @@ typedef enum
        STOCK_PIXMAP_MOVED,
        STOCK_PIXMAP_COPIED,
        STOCK_PIXMAP_SELECTION,
+       STOCK_PIXMAP_WATCHTHREAD,
        STOCK_PIXMAP_EMPTY,              /* last entry */
        N_STOCK_PIXMAPS
 } StockPixmap;
index 8e6d7df..7e2a1e3 100644 (file)
@@ -125,6 +125,8 @@ static GdkPixmap *forwardedxpm;
 static GdkBitmap *forwardedxpmmask;
 static GdkPixmap *ignorethreadxpm;
 static GdkBitmap *ignorethreadxpmmask;
+static GdkPixmap *watchthreadxpm;
+static GdkBitmap *watchthreadxpmmask;
 static GdkPixmap *lockedxpm;
 static GdkBitmap *lockedxpmmask;
 static GdkPixmap *spamxpm;
@@ -479,6 +481,8 @@ static GtkItemFactoryEntry summary_popup_entries[] =
        {N_("/_Mark/Mark all read"),    NULL, summary_mark_all_read, 0, NULL},
        {N_("/_Mark/Ignore thread"),    NULL, summary_ignore_thread, 0, NULL},
        {N_("/_Mark/Unignore thread"),  NULL, summary_unignore_thread, 0, NULL},
+       {N_("/_Mark/Watch thread"),     NULL, summary_watch_thread, 0, NULL},
+       {N_("/_Mark/Unwatch thread"),   NULL, summary_unwatch_thread, 0, NULL},
        {N_("/_Mark/---"),              NULL, NULL, 0, "<Separator>"},
        {N_("/_Mark/Mark as _spam"),    NULL, summary_mark_as_spam, 1, NULL},
        {N_("/_Mark/Mark as _ham"),     NULL, summary_mark_as_spam, 0, NULL},
@@ -929,6 +933,8 @@ void summary_init(SummaryView *summaryview)
                         &lockedxpm, &lockedxpmmask);
        stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_IGNORETHREAD,
                         &ignorethreadxpm, &ignorethreadxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_WATCHTHREAD,
+                        &watchthreadxpm, &watchthreadxpmmask);
        stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_CLIP_KEY,
                         &clipkeyxpm, &clipkeyxpmmask);
        stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_KEY,
@@ -3490,6 +3496,9 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
        if (MSG_IS_IGNORE_THREAD(flags)) {
                gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_STATUS],
                                          ignorethreadxpm, ignorethreadxpmmask);
+       } else if (MSG_IS_WATCH_THREAD(flags)) {
+               gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_STATUS],
+                                         watchthreadxpm, watchthreadxpmmask);
        } else if (MSG_IS_SPAM(flags)) {
                gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_STATUS],
                                          spamxpm, spamxpmmask);
@@ -6694,6 +6703,7 @@ static void summary_ignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpoin
        msginfo = gtk_ctree_node_get_row_data(ctree, row);
        g_return_if_fail(msginfo);
 
+       summary_msginfo_unset_flags(msginfo, MSG_WATCH_THREAD, 0);
        summary_msginfo_change_flags(msginfo, MSG_IGNORE_THREAD, 0, MSG_NEW | MSG_UNREAD, 0);
 
        summary_set_row_marks(summaryview, row);
@@ -6780,6 +6790,100 @@ void summary_toggle_ignore_thread(SummaryView *summaryview)
                summary_ignore_thread(summaryview);
 }
 
+static void summary_watch_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpointer data)
+{
+       SummaryView *summaryview = (SummaryView *) data;
+       MsgInfo *msginfo;
+
+       msginfo = gtk_ctree_node_get_row_data(ctree, row);
+       g_return_if_fail(msginfo);
+
+       summary_msginfo_change_flags(msginfo, MSG_WATCH_THREAD, 0, MSG_IGNORE_THREAD, 0);
+
+       summary_set_row_marks(summaryview, row);
+       debug_print("Message %d is marked as watch thread\n",
+           msginfo->msgnum);
+}
+
+void summary_watch_thread(SummaryView *summaryview)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GList *cur;
+       gboolean froze = FALSE;
+
+       START_LONG_OPERATION(summaryview, FALSE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+               gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data), 
+                                       GTK_CTREE_FUNC(summary_watch_thread_func), 
+                                       summaryview);
+
+       END_LONG_OPERATION(summaryview);
+
+       summary_status_show(summaryview);
+}
+
+static void summary_unwatch_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpointer data)
+{
+       SummaryView *summaryview = (SummaryView *) data;
+       MsgInfo *msginfo;
+
+       msginfo = gtk_ctree_node_get_row_data(ctree, row);
+       g_return_if_fail(msginfo);
+
+       summary_msginfo_unset_flags(msginfo, MSG_WATCH_THREAD, 0);
+
+       summary_set_row_marks(summaryview, row);
+       debug_print("Message %d is marked as unwatch thread\n",
+           msginfo->msgnum);
+}
+
+void summary_unwatch_thread(SummaryView *summaryview)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GList *cur;
+       gboolean froze = FALSE;
+
+       START_LONG_OPERATION(summaryview, FALSE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+               gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data), 
+                                       GTK_CTREE_FUNC(summary_unwatch_thread_func), 
+                                       summaryview);
+
+       END_LONG_OPERATION(summaryview);
+
+       summary_status_show(summaryview);
+}
+
+static void summary_check_watch_thread_func
+               (GtkCTree *ctree, GtkCTreeNode *row, gpointer data)
+{
+       MsgInfo *msginfo;
+       gint *found_watch = (gint *) data;
+
+       if (*found_watch) return;
+       else {
+               msginfo = gtk_ctree_node_get_row_data(ctree, row);
+               *found_watch = msginfo && MSG_IS_WATCH_THREAD(msginfo->flags);
+       }               
+}
+
+void summary_toggle_watch_thread(SummaryView *summaryview)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GList *cur;
+       gint found_watch = 0;
+
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+               gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data),
+                                       GTK_CTREE_FUNC(summary_check_watch_thread_func),
+                                       &found_watch);
+
+       if (found_watch) 
+               summary_unwatch_thread(summaryview);
+       else 
+               summary_watch_thread(summaryview);
+}
+
 void summary_toggle_show_read_messages(SummaryView *summaryview)
 {
        FolderItemUpdateData source;
@@ -6823,6 +6927,7 @@ void summary_reflect_prefs_pixmap_theme(SummaryView *summaryview)
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_CLIP, &clipxpm, &clipxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_LOCKED, &lockedxpm, &lockedxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_IGNORETHREAD, &ignorethreadxpm, &ignorethreadxpmmask);
+       stock_pixmap_gdk(ctree, STOCK_PIXMAP_WATCHTHREAD, &watchthreadxpm, &watchthreadxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_CLIP_KEY, &clipkeyxpm, &clipkeyxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_KEY, &keyxpm, &keyxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_GPG_SIGNED, &gpgsignedxpm, &gpgsignedxpmmask);
index d8a3c17..e34aeea 100644 (file)
@@ -220,6 +220,7 @@ void summary_thread_build     (SummaryView          *summaryview);
 void summary_expand_threads      (SummaryView          *summaryview);
 void summary_collapse_threads    (SummaryView          *summaryview);
 void summary_toggle_ignore_thread (SummaryView         *summaryview);
+void summary_toggle_watch_thread  (SummaryView         *summaryview);
 
 void summary_filter              (SummaryView          *summaryview,
                                   gboolean              selected_only);
@@ -282,6 +283,8 @@ void summary_mark_as_spam     (SummaryView          *summaryview,
                                   GtkWidget            *widget);
 void summary_ignore_thread       (SummaryView          *summaryview);
 void summary_unignore_thread     (SummaryView          *summaryview);
+void summary_watch_thread        (SummaryView          *summaryview);
+void summary_unwatch_thread      (SummaryView          *summaryview);
 
 void summary_add_address         (SummaryView          *summaryview);
 void summary_select_all                  (SummaryView          *summaryview);
index ac66739..5b8b1ff 100644 (file)
@@ -127,6 +127,9 @@ static void toolbar_next_unread_cb          (GtkWidget      *widget,
 static void toolbar_ignore_thread_cb           (GtkWidget      *widget,
                                                 gpointer        data);
 
+static void toolbar_watch_thread_cb            (GtkWidget      *widget,
+                                                gpointer        data);
+
 static void toolbar_print_cb                   (GtkWidget      *widget,
                                                 gpointer        data);
 
@@ -186,6 +189,7 @@ struct {
        { "A_GOTO_PREV",        N_("Go to Previous Unread Message")        },
        { "A_GOTO_NEXT",        N_("Go to Next Unread Message")            },
        { "A_IGNORE_THREAD",    N_("Ignore thread")                        },
+       { "A_WATCH_THREAD",     N_("Watch thread")                         },
        { "A_PRINT",            N_("Print")                                },
        { "A_LEARN_SPAM",       N_("Learn Spam or Ham")                    },
        { "A_GO_FOLDERS",       N_("Open folder/Go to folder list")        },
@@ -324,7 +328,7 @@ GList *toolbar_get_action_items(ToolbarType source)
                                        A_COMPOSE_EMAIL, A_REPLY_MESSAGE, A_REPLY_SENDER, 
                                        A_REPLY_ALL,     A_REPLY_ML,      A_OPEN_MAIL,  A_FORWARD, 
                                        A_TRASH , A_DELETE_REAL,       A_EXECUTE,       A_GOTO_PREV, 
-                                       A_GOTO_NEXT,    A_IGNORE_THREAD,  A_PRINT,
+                                       A_GOTO_NEXT,    A_IGNORE_THREAD,  A_WATCH_THREAD,       A_PRINT,
                                        A_ADDRBOOK,     A_LEARN_SPAM, A_GO_FOLDERS, 
                                        A_SYL_ACTIONS, A_CANCEL_INC };
 
@@ -1325,6 +1329,28 @@ static void toolbar_ignore_thread_cb(GtkWidget *widget, gpointer data)
        }
 }
 
+static void toolbar_watch_thread_cb(GtkWidget *widget, gpointer data)
+{
+       ToolbarItem *toolbar_item = (ToolbarItem*)data;
+       MainWindow *mainwin;
+
+       g_return_if_fail(toolbar_item != NULL);
+
+       switch (toolbar_item->type) {
+       case TOOLBAR_MAIN:
+               mainwin = (MainWindow *) toolbar_item->parent;
+               summary_toggle_watch_thread(mainwin->summaryview);
+               break;
+       case TOOLBAR_MSGVIEW:
+               /* TODO: see toolbar_next_unread_cb() if you need
+                * this in the message view */
+               break;
+       default:
+               debug_print("toolbar event not supported\n");
+               break;
+       }
+}
+
 static void toolbar_cancel_inc_cb(GtkWidget *widget, gpointer data)
 {
        ToolbarItem *toolbar_item = (ToolbarItem*)data;
@@ -1560,6 +1586,7 @@ static void toolbar_buttons_cb(GtkWidget   *widget,
                { A_GOTO_PREV,          toolbar_prev_unread_cb          },
                { A_GOTO_NEXT,          toolbar_next_unread_cb          },
                { A_IGNORE_THREAD,      toolbar_ignore_thread_cb        },
+               { A_WATCH_THREAD,       toolbar_watch_thread_cb         },
                { A_PRINT,              toolbar_print_cb                },
                { A_LEARN_SPAM,         toolbar_learn_cb                },
                { A_GO_FOLDERS,         toolbar_go_folders_cb           },
index c6c7388..7b16f30 100644 (file)
@@ -166,6 +166,7 @@ enum {
        A_GOTO_PREV,
        A_GOTO_NEXT,
        A_IGNORE_THREAD,
+       A_WATCH_THREAD,
        A_PRINT,
        A_LEARN_SPAM,
        A_GO_FOLDERS,