change gtk_ctree_sort_node() into gtk_ctree_sort_recursive() so messages on same...
[claws.git] / src / summaryview.c
index a305bca69d969fab1e6858cb2baae55c8ff8b220..35f68211dcd1d2d7d24ddb6ab7942ff1b333a547 100644 (file)
@@ -16,7 +16,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
-
 #include "defs.h"
 
 #include <glib.h>
@@ -46,6 +45,7 @@
 #include <ctype.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <regex.h>
 
 #include "intl.h"
 #include "main.h"
@@ -65,6 +65,7 @@
 #include "compose.h"
 #include "utils.h"
 #include "gtkutils.h"
+#include "stock_pixmap.h"
 #include "filesel.h"
 #include "manage_window.h"
 #include "alertpanel.h"
 #include "folder.h"
 #include "colorlabel.h"
 #include "inc.h"
+#include "imap.h"
 #include "addressbook.h"
 #include "addr_compl.h"
 #include "scoring.h"
 #include "prefs_folder_item.h"
 #include "filtering.h"
-
-#include "pixmaps/dir-open.xpm"
-#include "pixmaps/mark.xpm"
-#include "pixmaps/deleted.xpm"
-#include "pixmaps/new.xpm"
-#include "pixmaps/unread.xpm"
-#include "pixmaps/replied.xpm"
-#include "pixmaps/forwarded.xpm"
-#include "pixmaps/clip.xpm"
-#include "pixmaps/ignorethread.xpm"
-#include "pixmaps/locked.xpm"
+#include "string_match.h"
 
 #define STATUSBAR_PUSH(mainwin, str) \
 { \
 #define SUMMARY_COL_MARK_WIDTH         10
 #define SUMMARY_COL_UNREAD_WIDTH       13
 #define SUMMARY_COL_LOCKED_WIDTH       13
-#define SUMMARY_COL_MIME_WIDTH         10
+#define SUMMARY_COL_MIME_WIDTH         11
 
 static GdkFont *boldfont;
 static GdkFont *smallfont;
@@ -119,9 +111,6 @@ static GtkStyle *small_style;
 static GtkStyle *small_marked_style;
 static GtkStyle *small_deleted_style;
 
-static GdkPixmap *folderxpm;
-static GdkBitmap *folderxpmmask;
-
 static GdkPixmap *markxpm;
 static GdkBitmap *markxpmmask;
 static GdkPixmap *deletedxpm;
@@ -142,6 +131,10 @@ static GdkBitmap *lockedxpmmask;
 
 static GdkPixmap *clipxpm;
 static GdkBitmap *clipxpmmask;
+static GdkPixmap *keyxpm;
+static GdkBitmap *keyxpmmask;
+static GdkPixmap *clipkeyxpm;
+static GdkBitmap *clipkeyxpmmask;
 
 static void summary_free_msginfo_func  (GtkCTree               *ctree,
                                         GtkCTreeNode           *node,
@@ -155,6 +148,9 @@ static void summary_write_cache_func        (GtkCTree               *ctree,
 
 static void summary_set_menu_sensitive (SummaryView            *summaryview);
 
+static void summary_set_hide_read_msgs_menu (SummaryView *summaryview,
+                                            guint action);
+
 static guint summary_get_msgnum                (SummaryView            *summaryview,
                                         GtkCTreeNode           *node);
 
@@ -202,6 +198,7 @@ static void summary_display_msg             (SummaryView            *summaryview,
 static void summary_toggle_view                (SummaryView            *summaryview);
 static void summary_set_row_marks      (SummaryView            *summaryview,
                                         GtkCTreeNode           *row);
+static void summaryview_subject_filter_init (PrefsFolderItem    *prefs);
 
 /* message handling */
 static void summary_mark_row           (SummaryView            *summaryview,
@@ -250,6 +247,9 @@ static void summary_unthread_for_exec_func  (GtkCTree       *ctree,
                                                 GtkCTreeNode   *node,
                                                 gpointer        data);
 
+void summary_simplify_subject(SummaryView *summaryview, gchar * rexp,
+                             GSList * mlist);
+
 void summary_processing(SummaryView *summaryview, GSList * mlist);
 static void summary_filter_func                (GtkCTree               *ctree,
                                         GtkCTreeNode           *node,
@@ -389,8 +389,6 @@ static GtkItemFactoryEntry summary_popup_entries[] =
        {N_("/Follow-up and reply to"), NULL, summary_reply_cb, COMPOSE_FOLLOWUP_AND_REPLY_TO, NULL},
        {N_("/Reply to a_ll"),          NULL, summary_reply_cb, COMPOSE_REPLY_TO_ALL, NULL},
        {N_("/_Forward"),               NULL, summary_reply_cb, COMPOSE_FORWARD, NULL},
-       {N_("/Forward as a_ttachment"),
-                                       NULL, summary_reply_cb, COMPOSE_FORWARD_AS_ATTACH, NULL},
        {N_("/Bounce"),                 NULL, summary_reply_cb, COMPOSE_BOUNCE, NULL},
        {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
        {N_("/Re-_edit"),               NULL, summary_reedit,   0, NULL},
@@ -532,21 +530,28 @@ void summary_init(SummaryView *summaryview)
        GtkStyle *style;
        GtkWidget *pixmap;
 
-       PIXMAP_CREATE(summaryview->ctree, markxpm, markxpmmask, mark_xpm);
-       PIXMAP_CREATE(summaryview->ctree, deletedxpm, deletedxpmmask,
-                     deleted_xpm);
-       PIXMAP_CREATE(summaryview->ctree, newxpm, newxpmmask, new_xpm);
-       PIXMAP_CREATE(summaryview->ctree, unreadxpm, unreadxpmmask, unread_xpm);
-       PIXMAP_CREATE(summaryview->ctree, repliedxpm, repliedxpmmask,
-                     replied_xpm);
-       PIXMAP_CREATE(summaryview->ctree, forwardedxpm, forwardedxpmmask,
-                     forwarded_xpm);
-       PIXMAP_CREATE(summaryview->ctree, ignorethreadxpm, ignorethreadxpmmask,
-                     ignorethread_xpm);
-       PIXMAP_CREATE(summaryview->ctree, lockedxpm, lockedxpmmask, locked_xpm);                      
-       PIXMAP_CREATE(summaryview->ctree, clipxpm, clipxpmmask, clip_xpm);
-       PIXMAP_CREATE(summaryview->hbox, folderxpm, folderxpmmask,
-                     dir_open_xpm);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_MARK,
+                        &markxpm, &markxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_DELETED,
+                        &deletedxpm, &deletedxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_NEW,
+                        &newxpm, &newxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_UNREAD,
+                        &unreadxpm, &unreadxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_REPLIED,
+                        &repliedxpm, &repliedxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_FORWARDED,
+                        &forwardedxpm, &forwardedxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_CLIP,
+                        &clipxpm, &clipxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_LOCKED,
+                        &lockedxpm, &lockedxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_IGNORETHREAD,
+                        &ignorethreadxpm, &ignorethreadxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_CLIP_KEY,
+                        &clipkeyxpm, &clipkeyxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_KEY,
+                        &keyxpm, &keyxpmmask);
 
        if (!small_style) {
                small_style = gtk_style_copy
@@ -582,7 +587,7 @@ void summary_init(SummaryView *summaryview)
        gtk_widget_set_style(summaryview->statlabel_select, style);
        gtk_widget_set_style(summaryview->statlabel_msgs, style);
 
-       pixmap = gtk_pixmap_new(folderxpm, folderxpmmask);
+       pixmap = stock_pixmap_widget(summaryview->hbox, STOCK_PIXMAP_DIR_OPEN);
        gtk_box_pack_start(GTK_BOX(summaryview->hbox), pixmap, FALSE, FALSE, 4);
        gtk_box_reorder_child(GTK_BOX(summaryview->hbox), pixmap, 0);
        gtk_widget_show(pixmap);
@@ -707,9 +712,8 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item,
                        return FALSE;
                }
                folder_update_op_count();
-       }
-        
-       summary_write_cache(summaryview);
+       } else
+               summary_write_cache(summaryview);
         
        summaryview->folderview->opened = selected_node;
 
@@ -728,6 +732,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item,
              change_dir(buf) < 0))) {
                g_free(buf);
                debug_print(_("empty folder\n\n"));
+               summary_set_hide_read_msgs_menu(summaryview, FALSE);
                if (is_refresh)
                        messageview_clear(summaryview->messageview);
                summary_clear_all(summaryview);
@@ -766,6 +771,31 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item,
        }
 
        summaryview->killed_messages = NULL;
+
+       if (summaryview->folder_item->hide_read_msgs) {
+               GSList *not_killed;
+               gint kill_score;
+               
+               summary_set_hide_read_msgs_menu(summaryview, TRUE);
+               not_killed = NULL;
+               for(cur = mlist ; cur != NULL ; cur = g_slist_next(cur)) {
+                       MsgInfo * msginfo = (MsgInfo *) cur->data;
+                       
+                       if ((MSG_IS_UNREAD(msginfo->flags)
+                            || MSG_IS_MARKED(msginfo->flags)
+                            || MSG_IS_LOCKED(msginfo->flags))
+                            && !MSG_IS_IGNORE_THREAD(msginfo->flags))
+                           not_killed = g_slist_append(not_killed, msginfo);
+                       else
+                               summaryview->killed_messages = 
+                                       g_slist_append(summaryview->killed_messages, msginfo);
+               }
+               g_slist_free(mlist);
+               mlist = not_killed;
+       } else {
+               summary_set_hide_read_msgs_menu(summaryview, FALSE);
+       }
+
        if ((global_scoring || item->prefs->scoring) &&
            (item->folder->type == F_NEWS)) {
                GSList *not_killed;
@@ -1012,7 +1042,6 @@ static void summary_set_menu_sensitive(SummaryView *summaryview)
        menu_set_sensitive(ifactory, "/Reply to sender",          sens);
        menu_set_sensitive(ifactory, "/Reply to all",             sens);
        menu_set_sensitive(ifactory, "/Forward",                  TRUE);
-       menu_set_sensitive(ifactory, "/Forward as attachment",    TRUE);
        menu_set_sensitive(ifactory, "/Bounce",                   TRUE);
 
        menu_set_sensitive(ifactory, "/Add sender to address book", sens);
@@ -1624,6 +1653,7 @@ static void summary_status_show(SummaryView *summaryview)
        gchar *del, *mv, *cp;
        gchar *sel;
        gchar *spc;
+       gchar *itstr;
        GList *rowlist, *cur;
        guint n_selected = 0;
        off_t sel_size = 0;
@@ -1674,19 +1704,26 @@ static void summary_status_show(SummaryView *summaryview)
        else
                spc = "";
 
-       if (n_selected)
+       if (n_selected) {
                sel = g_strdup_printf(" (%s)", to_human_readable(sel_size));
-       else
+               if (n_selected == 1)
+                       itstr = g_strdup(_(" item selected"));
+               else
+                       itstr = g_strdup(_(" items selected"));
+       } else {
                sel = g_strdup("");
+               itstr = g_strdup("");
+       }
+               
        str = g_strconcat(n_selected ? itos(n_selected) : "",
-                         n_selected ? _(" item(s) selected") : "",
-                         sel, spc, del, mv, cp, NULL);
+                                       itstr, sel, spc, del, mv, cp, NULL);
        gtk_label_set(GTK_LABEL(summaryview->statlabel_select), str);
        g_free(str);
        g_free(sel);
        g_free(del);
        g_free(mv);
        g_free(cp);
+       g_free(itstr);
 
        if (summaryview->folder_item &&
            FOLDER_IS_LOCAL(summaryview->folder_item->folder)) {
@@ -1731,14 +1768,16 @@ static void summary_set_column_titles(SummaryView *summaryview)
                SORT_BY_FROM,
                SORT_BY_DATE,
                SORT_BY_SIZE,
-               SORT_BY_NUMBER
+               SORT_BY_NUMBER,
+               SORT_BY_SCORE,
+               SORT_BY_LOCKED
        };
 
        for (pos = 0; pos < N_SUMMARY_COLS; pos++) {
                type = summaryview->col_state[pos].type;
 
-               single_char = (type == S_COL_MIME ||
-                              type == S_COL_MARK || type == S_COL_UNREAD);
+               /* CLAWS: mime and unread are single char headers */
+               single_char = (type == S_COL_MIME || type == S_COL_UNREAD);
                justify = (type == S_COL_NUMBER || type == S_COL_SIZE)
                        ? GTK_JUSTIFY_RIGHT : GTK_JUSTIFY_LEFT;
 
@@ -1752,6 +1791,11 @@ static void summary_set_column_titles(SummaryView *summaryview)
                        else
                                title = col_label[type];
                        break;
+               /* CLAWS: dummies for mark and locked headers */        
+               case S_COL_MARK:        
+               case S_COL_LOCKED:
+                       title = "";
+                       break;
                default:
                        title = gettext(col_label[type]);
                }
@@ -1767,8 +1811,17 @@ static void summary_set_column_titles(SummaryView *summaryview)
                        continue;
                }
 
-               hbox = gtk_hbox_new(FALSE, 4);
-               label = gtk_label_new(title);
+               /* CLAWS: changed so that locked and mark headers
+                * show a pixmap instead of single character */
+               hbox  = gtk_hbox_new(FALSE, 4);
+               
+               if (type == S_COL_LOCKED)
+                       label = gtk_pixmap_new(lockedxpm, lockedxpmmask);
+               else if (type == S_COL_MARK) 
+                       label = gtk_pixmap_new(markxpm, markxpmmask);
+               else 
+                       label = gtk_label_new(title);
+               
                if (justify == GTK_JUSTIFY_RIGHT)
                        gtk_box_pack_end(GTK_BOX(hbox), label,
                                         FALSE, FALSE, 0);
@@ -1860,7 +1913,7 @@ void summary_sort(SummaryView *summaryview, SummarySortType type)
 
        summary_set_column_titles(summaryview);
 
-       gtk_ctree_sort_node(ctree, NULL);
+       gtk_ctree_sort_recursive(ctree, NULL);
 
        gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0);
        prefs_folder_item_set_config(summaryview->folder_item,
@@ -1951,6 +2004,8 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
                        summaryview->important_score =
                                summaryview->folder_item->prefs->important_score;
        }
+
+       summaryview_subject_filter_init(summaryview->folder_item->prefs);
        
        if (summaryview->folder_item->threaded) {
                GNode *root, *gnode;
@@ -2133,6 +2188,8 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
        static gchar *from_name = NULL;
        static gchar col_number[11];
        static gchar col_score[11];
+       static gchar buf[BUFFSIZE];
+       PrefsFolderItem *prefs = summaryview->folder_item->prefs;
        gint *col_pos = summaryview->col_pos;
 
        text[col_pos[S_COL_MARK]]   = NULL;
@@ -2192,8 +2249,16 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
                }
        }
 
-       text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? msginfo->subject :
-               _("(No Subject)");
+       if (prefs->enable_simplify_subject 
+           && prefs->simplify_subject_preg != NULL )
+               text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? 
+                       string_remove_match(buf, BUFFSIZE, msginfo->subject, 
+                                       prefs->simplify_subject_preg) : 
+                       
+                       _("(No Subject)");
+       else 
+               text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? msginfo->subject :
+                       _("(No Subject)");
 }
 
 #define CHANGE_FLAGS(msginfo) \
@@ -2209,6 +2274,7 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row,
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        MsgInfo *msginfo;
+       MsgFlags flags;
        gchar *filename;
 
        if (!new_window && summaryview->displayed == row) return;
@@ -2233,6 +2299,17 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row,
                summaryview->newmsgs--;
        if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
                summaryview->unread--;
+       if (MSG_IS_NEW(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags) || 
+           MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) {
+               MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
+               if (MSG_IS_IMAP(msginfo->flags))
+                       imap_msg_unset_perm_flags(msginfo, MSG_NEW | MSG_UNREAD);
+               summary_set_row_marks(summaryview, row);
+               gtk_clist_thaw(GTK_CLIST(ctree));
+               summary_status_show(summaryview);
+       }
+
+       flags = msginfo->flags;
 
        if (new_window) {
                MessageView *msgview;
@@ -2256,7 +2333,8 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row,
                gtkut_ctree_node_move_if_on_the_edge(ctree, row);
        }
 
-       if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
+       if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags) ||
+           (MSG_IS_MIME(msginfo->flags) - MSG_IS_MIME(flags) != 0)) {
                MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
                CHANGE_FLAGS(msginfo);
                summary_set_row_marks(summaryview, row);
@@ -2513,7 +2591,13 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
                gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_LOCKED], NULL);
        }
 
-       if (MSG_IS_MIME(flags)) {
+       if (MSG_IS_MIME(flags) && MSG_IS_ENCRYPTED(flags)) {
+               gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_MIME],
+                                         clipkeyxpm, clipkeyxpmmask);
+       } else if (MSG_IS_ENCRYPTED(flags)) {
+               gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_MIME],
+                                         keyxpm, keyxpmmask);
+       } else if (MSG_IS_MIME(flags)) {
                gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_MIME],
                                          clipxpm, clipxpmmask);
        } else {
@@ -2564,9 +2648,10 @@ static void summary_mark_row(SummaryView *summaryview, GtkCTreeNode *row)
        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_DELETED);
        MSG_UNSET_TMP_FLAGS(msginfo->flags, MSG_MOVE | MSG_COPY);
        MSG_SET_PERM_FLAGS(msginfo->flags, MSG_MARKED);
+       if (MSG_IS_IMAP(msginfo->flags))
+               imap_msg_set_perm_flags(msginfo, MSG_MARKED);
        CHANGE_FLAGS(msginfo);
        summary_set_row_marks(summaryview, row);
-       imap_do_mark(msginfo);
        debug_print(_("Message %s/%d is marked\n"), msginfo->folder->path, msginfo->msgnum);
 }
 
@@ -2597,6 +2682,8 @@ static void summary_lock_row(SummaryView *summaryview, GtkCTreeNode *row)
        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_DELETED);
        MSG_UNSET_TMP_FLAGS(msginfo->flags, MSG_MOVE | MSG_COPY);
        MSG_SET_PERM_FLAGS(msginfo->flags, MSG_LOCKED);
+       if (MSG_IS_IMAP(msginfo->flags))
+               imap_msg_set_perm_flags(msginfo, MSG_LOCKED);
        CHANGE_FLAGS(msginfo);
        summary_set_row_marks(summaryview, row);
        debug_print(_("Message %d is locked\n"), msginfo->msgnum);
@@ -2628,6 +2715,8 @@ static void summary_mark_row_as_read(SummaryView *summaryview,
        if (MSG_IS_NEW(msginfo->flags) ||
            MSG_IS_UNREAD(msginfo->flags)) {
                MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
+               if (MSG_IS_IMAP(msginfo->flags))
+                       imap_msg_unset_perm_flags(msginfo, MSG_NEW | MSG_UNREAD);
                CHANGE_FLAGS(msginfo);
                summary_set_row_marks(summaryview, row);
                debug_print(_("Message %d is marked as read\n"),
@@ -2680,8 +2769,12 @@ static void summary_mark_row_as_unread(SummaryView *summaryview,
                summaryview->deleted--;
        }
        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_REPLIED | MSG_FORWARDED);
+       if (MSG_IS_IMAP(msginfo->flags))
+               imap_msg_unset_perm_flags(msginfo, MSG_REPLIED);
        if (!MSG_IS_UNREAD(msginfo->flags)) {
                MSG_SET_PERM_FLAGS(msginfo->flags, MSG_UNREAD);
+               if (MSG_IS_IMAP(msginfo->flags))
+                       imap_msg_set_perm_flags(msginfo, MSG_UNREAD);
                summaryview->unread++;
                debug_print(_("Message %d is marked as unread\n"),
                            msginfo->msgnum);
@@ -2731,6 +2824,8 @@ static void summary_delete_row(SummaryView *summaryview, GtkCTreeNode *row)
        }
        msginfo->to_folder = NULL;
        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_MARKED);
+       if (MSG_IS_IMAP(msginfo->flags))
+               imap_msg_unset_perm_flags(msginfo, MSG_MARKED);
        MSG_UNSET_TMP_FLAGS(msginfo->flags, MSG_MOVE | MSG_COPY);
        MSG_SET_PERM_FLAGS(msginfo->flags, MSG_DELETED);
        CHANGE_FLAGS(msginfo);
@@ -2856,10 +2951,11 @@ static void summary_unmark_row(SummaryView *summaryview, GtkCTreeNode *row)
        }
        msginfo->to_folder = NULL;
        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_MARKED | MSG_DELETED);
+       if (MSG_IS_IMAP(msginfo->flags))
+               imap_msg_unset_perm_flags(msginfo, MSG_MARKED);
        MSG_UNSET_TMP_FLAGS(msginfo->flags, MSG_MOVE | MSG_COPY);
        CHANGE_FLAGS(msginfo);
        summary_set_row_marks(summaryview, row);
-       imap_do_unmark(msginfo);
        debug_print(_("Message %s/%d is unmarked\n"),
                    msginfo->folder->path, msginfo->msgnum);
 }
@@ -2869,8 +2965,7 @@ void summary_unmark(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL;
-            cur = cur->next)
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
                summary_unmark_row(summaryview, GTK_CTREE_NODE(cur->data));
 
        summary_status_show(summaryview);
@@ -2904,6 +2999,8 @@ static void summary_move_row_to(SummaryView *summaryview, GtkCTreeNode *row,
                        msginfo->to_folder->op_count--;
        }
        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_MARKED | MSG_DELETED);
+       if (MSG_IS_IMAP(msginfo->flags))
+               imap_msg_unset_perm_flags(msginfo, MSG_MARKED);
        MSG_UNSET_TMP_FLAGS(msginfo->flags, MSG_COPY);
        if (!MSG_IS_MOVE(msginfo->flags)) {
                MSG_SET_TMP_FLAGS(msginfo->flags, MSG_MOVE);
@@ -2993,6 +3090,8 @@ static void summary_copy_row_to(SummaryView *summaryview, GtkCTreeNode *row,
                        msginfo->to_folder->op_count--;
        }
        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_MARKED | MSG_DELETED);
+       if (MSG_IS_IMAP(msginfo->flags))
+               imap_msg_unset_perm_flags(msginfo, MSG_MARKED);
        MSG_UNSET_TMP_FLAGS(msginfo->flags, MSG_MOVE);
        if (!MSG_IS_COPY(msginfo->flags)) {
                MSG_SET_TMP_FLAGS(msginfo->flags, MSG_COPY);
@@ -3654,8 +3753,6 @@ void summary_filter(SummaryView *summaryview)
 
                g_hash_table_destroy(summaryview->folder_table);
                summaryview->folder_table = NULL;
-
-               summary_show(summaryview, summaryview->folder_item, FALSE);
        }
 
        debug_print(_("done.\n"));
@@ -3663,6 +3760,11 @@ void summary_filter(SummaryView *summaryview)
        main_window_cursor_normal(summaryview->mainwin);
 
        summary_unlock(summaryview);
+
+       /* CLAWS: summary_show() only valid after having a lock. ideally
+        * we want the lock to be context aware...  */
+       if (global_processing)
+               summary_show(summaryview, summaryview->folder_item, FALSE);
 }
 
 static void summary_filter_func(GtkCTree *ctree, GtkCTreeNode *node,
@@ -3683,7 +3785,7 @@ static void summary_filter_func(GtkCTree *ctree, GtkCTreeNode *node,
                    summaryview->folder_item != dest)
                        summary_move_row_to(summaryview, node, dest);
        }
-       else
+       else 
                filter_msginfo_move_or_delete(global_processing, msginfo,
                                              summaryview->folder_table);
 }
@@ -4007,8 +4109,16 @@ void summary_set_column_order(SummaryView *summaryview)
        GtkWidget *scrolledwin = summaryview->scrolledwin;
        GtkWidget *pixmap;
        FolderItem *item;
+       guint selected_msgnum = summary_get_msgnum(summaryview, summaryview->selected);
+       guint displayed_msgnum = summary_get_msgnum(summaryview, summaryview->displayed);
 
+       
        item = summaryview->folder_item;
+
+       summary_lock(summaryview);
+       summary_write_cache(summaryview);
+       summary_unlock(summaryview);
+       
        summary_clear_all(summaryview);
        gtk_widget_destroy(summaryview->ctree);
 
@@ -4025,6 +4135,13 @@ void summary_set_column_order(SummaryView *summaryview)
        gtk_widget_show(ctree);
 
        summary_show(summaryview, item, FALSE);
+
+       summary_select_by_msgnum(summaryview, selected_msgnum);
+       summaryview->displayed = summary_find_msg_by_msgnum(summaryview, displayed_msgnum);
+       if (!summaryview->displayed)
+               messageview_clear(summaryview->messageview);
+       else
+               summary_redisplay_msg(summaryview);
 }
 
 
@@ -4309,6 +4426,8 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
        case S_COL_MARK:
                if (MSG_IS_MARKED(msginfo->flags)) {
                        MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_MARKED);
+                       if (MSG_IS_IMAP(msginfo->flags))
+                               imap_msg_unset_perm_flags(msginfo, MSG_MARKED);
                        CHANGE_FLAGS(msginfo);
                        summary_set_row_marks(summaryview, row);
                } else
@@ -4398,7 +4517,16 @@ static void summary_reply_cb(SummaryView *summaryview, guint action,
                compose_reply(msginfo, FALSE, TRUE, FALSE);
                break;
        case COMPOSE_FORWARD:
-               if (!sel->next) {
+               if (prefs_common.forward_as_attachment) {
+                       summary_reply_cb(summaryview, COMPOSE_FORWARD_AS_ATTACH, widget);
+                       return;
+               } else {
+                       summary_reply_cb(summaryview, COMPOSE_FORWARD_INLINE, widget);
+                       return;
+               }
+               break;
+       case COMPOSE_FORWARD_INLINE:
+               if (!sel->next) {
                        compose_forward(NULL, msginfo, FALSE);
                        break;
                }
@@ -4511,7 +4639,7 @@ static void summary_start_drag(GtkWidget *widget, gint button, GdkEvent *event,
        list = gtk_target_list_new(summary_drag_types, 1);
 
        context = gtk_drag_begin(widget, list,
-                                GDK_ACTION_MOVE, button, event);
+                                GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_DEFAULT, button, event);
        gtk_drag_set_icon_default(context);
 }
 
@@ -4802,6 +4930,59 @@ void processing_apply(SummaryView * summaryview)
        }
 }
 
+void summary_toggle_show_read_messages(SummaryView *summaryview)
+{
+       if (summaryview->folder_item->hide_read_msgs)
+               summaryview->folder_item->hide_read_msgs = 0;
+       else
+               summaryview->folder_item->hide_read_msgs = 1;
+       summary_show(summaryview, summaryview->folder_item, FALSE);
+}
+static void summary_set_hide_read_msgs_menu (SummaryView *summaryview,
+                                            guint action)
+{
+       GtkWidget *widget;
+       widget = gtk_item_factory_get_item(gtk_item_factory_from_widget(summaryview->mainwin->menubar),
+                                          "/View/Hide read messages");
+       gtk_object_set_data(GTK_OBJECT(widget), "dont_toggle",
+                           GINT_TO_POINTER(1));
+       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(widget), action);
+       gtk_object_set_data(GTK_OBJECT(widget), "dont_toggle",
+                           GINT_TO_POINTER(0));
+}
+static void summaryview_subject_filter_init(PrefsFolderItem *prefs)
+{
+       int err;
+       gchar buf[BUFFSIZE];
+       if (prefs->enable_simplify_subject) {
+               if (prefs->simplify_subject_regexp && 
+                               *prefs->simplify_subject_regexp != 0x00) {
+
+                       if (!prefs->simplify_subject_preg) 
+                               prefs->simplify_subject_preg = g_new(regex_t, 1);
+                       else
+                               regfree(prefs->simplify_subject_preg);
+
+                       err = string_match_precompile(prefs->simplify_subject_regexp, 
+                                       prefs->simplify_subject_preg, REG_EXTENDED);
+                       if (err) {
+                               regerror(err, prefs->simplify_subject_preg, buf, BUFFSIZE);
+                               alertpanel_error(_("Regular expression (regexp) error:\n%s"), buf);
+                               g_free(prefs->simplify_subject_preg);
+                               prefs->simplify_subject_preg = NULL;
+                       }
+               } else {
+                       if (prefs->simplify_subject_preg) {
+                               regfree(prefs->simplify_subject_preg);
+                               g_free(prefs->simplify_subject_preg);
+                               prefs->simplify_subject_preg = NULL;
+                       }
+               }
+       }
+}
+
 
 /*
  * End of Source.