2005-10-08 [colin] 1.9.15cvs21
[claws.git] / src / summaryview.c
index 43e13d9bd023ac2b315a35826a2b3b3225132e2b..4520c77273eae2d66aeac77ab057eb14ee806ced 100644 (file)
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #include "defs.h"
@@ -86,6 +86,7 @@
 #include "quicksearch.h"
 #include "partial_download.h"
 #include "timing.h"
+#include "gedit-print.h"
 
 #define SUMMARY_COL_MARK_WIDTH         10
 #define SUMMARY_COL_STATUS_WIDTH       13
@@ -207,7 +208,7 @@ static void summary_copy_row_to             (SummaryView            *summaryview,
                                         GtkCTreeNode           *row,
                                         FolderItem             *to_folder);
 
-static void summary_execute_move       (SummaryView            *summaryview);
+static gint summary_execute_move       (SummaryView            *summaryview);
 static void summary_execute_move_func  (GtkCTree               *ctree,
                                         GtkCTreeNode           *node,
                                         gpointer                data);
@@ -311,6 +312,8 @@ static void summary_date_clicked    (GtkWidget              *button,
                                         SummaryView            *summaryview);
 static void summary_from_clicked       (GtkWidget              *button,
                                         SummaryView            *summaryview);
+static void summary_to_clicked         (GtkWidget              *button,
+                                        SummaryView            *summaryview);
 static void summary_subject_clicked    (GtkWidget              *button,
                                         SummaryView            *summaryview);
 static void summary_score_clicked      (GtkWidget              *button,
@@ -404,7 +407,8 @@ static GtkItemFactoryEntry summary_popup_entries[] =
        {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
        {N_("/M_ove..."),               "<control>O", summary_move_to,  0, NULL},
        {N_("/_Copy..."),               "<shift><control>O", summary_copy_to,   0, NULL},
-       {N_("/_Delete"),                "<control>D", summary_delete,   0, NULL},
+       {N_("/Move to _trash"),         "<control>D", summary_delete_trash,     0, NULL},
+       {N_("/_Delete..."),             NULL, summary_delete, 0, NULL},
        {N_("/Cancel a news message"),  NULL, summary_cancel,   0, NULL},
        {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
        {N_("/_Mark"),                  NULL, NULL,             0, "<Branch>"},
@@ -457,6 +461,7 @@ static const gchar *const col_label[N_SUMMARY_COLS] = {
        "",             /* S_COL_MIME    */
        N_("Subject"),  /* S_COL_SUBJECT */
        N_("From"),     /* S_COL_FROM    */
+       N_("To"),       /* S_COL_TO      */
        N_("Date"),     /* S_COL_DATE    */
        N_("Size"),     /* S_COL_SIZE    */
        N_("No."),      /* S_COL_NUMBER  */
@@ -464,6 +469,21 @@ static const gchar *const col_label[N_SUMMARY_COLS] = {
        N_("L")         /* S_COL_LOCKED  */
 };
 
+#define START_LONG_OPERATION(summaryview) {                    \
+       summary_lock(summaryview);                              \
+       main_window_cursor_wait(summaryview->mainwin);          \
+       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));        \
+       folder_item_update_freeze();                            \
+       inc_lock();                                             \
+}
+#define END_LONG_OPERATION(summaryview) {                      \
+       inc_unlock();                                           \
+       folder_item_update_thaw();                              \
+       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));          \
+       main_window_cursor_normal(summaryview->mainwin);        \
+       summary_unlock(summaryview);                            \
+}
+
 SummaryView *summary_create(void)
 {
        SummaryView *summaryview;
@@ -613,40 +633,11 @@ SummaryView *summary_create(void)
        return summaryview;
 }
 
-void summary_init(SummaryView *summaryview)
+static void summary_set_fonts(SummaryView *summaryview)
 {
-       GtkWidget *pixmap;
        PangoFontDescription *font_desc;
        gint size;
 
-       gtk_widget_realize(summaryview->ctree);
-       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);
-       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_GPG_SIGNED,
-                        &gpgsignedxpm, &gpgsignedxpmmask);
-       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_CLIP_GPG_SIGNED,
-                        &clipgpgsignedxpm, &clipgpgsignedxpmmask);
-
        font_desc = pango_font_description_from_string(NORMAL_FONT);
        gtk_widget_modify_font(summaryview->ctree, font_desc);
        pango_font_description_free(font_desc);
@@ -654,7 +645,7 @@ void summary_init(SummaryView *summaryview)
        if (!bold_style) {
                bold_style = gtk_style_copy
                        (gtk_widget_get_style(summaryview->ctree));
-               font_desc = pango_font_description_from_string(BOLD_FONT);
+               font_desc = pango_font_description_from_string(NORMAL_FONT);
                if (font_desc) {
                        pango_font_description_free(bold_style->font_desc);
                        bold_style->font_desc = font_desc;
@@ -672,12 +663,47 @@ void summary_init(SummaryView *summaryview)
 
        font_desc = pango_font_description_new();
        size = pango_font_description_get_size
-               (summaryview->statlabel_folder->style->font_desc);
+               (summaryview->ctree->style->font_desc);
        pango_font_description_set_size(font_desc, size * PANGO_SCALE_SMALL);
        gtk_widget_modify_font(summaryview->statlabel_folder, font_desc);
        gtk_widget_modify_font(summaryview->statlabel_select, font_desc);
        gtk_widget_modify_font(summaryview->statlabel_msgs, font_desc);
        pango_font_description_free(font_desc);
+}
+
+void summary_init(SummaryView *summaryview)
+{
+       GtkWidget *pixmap;
+
+       gtk_widget_realize(summaryview->ctree);
+       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);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_GPG_SIGNED,
+                        &gpgsignedxpm, &gpgsignedxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_CLIP_GPG_SIGNED,
+                        &clipgpgsignedxpm, &clipgpgsignedxpmmask);
+
+       summary_set_fonts(summaryview);
 
        pixmap = stock_pixmap_widget(summaryview->hbox_l, STOCK_PIXMAP_DIR_OPEN);
        gtk_box_pack_start(GTK_BOX(summaryview->hbox_l), pixmap, FALSE, FALSE, 4);
@@ -783,6 +809,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        guint displayed_msgnum = 0;
        GSList *cur;
         GSList *not_killed;
+       gboolean hidden_removed = FALSE;
 
        if (summary_is_locked(summaryview)) return FALSE;
 
@@ -798,6 +825,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        /* STATUSBAR_POP(summaryview->mainwin); */
 
        is_refresh = (item == summaryview->folder_item) ? TRUE : FALSE;
+
        if (is_refresh) {
                selected_msgnum = summary_get_msgnum(summaryview,
                                                     summaryview->selected);
@@ -833,7 +861,6 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        gtk_clist_freeze(GTK_CLIST(ctree));
 
        summary_clear_list(summaryview);
-       summary_set_column_titles(summaryview);
 
        buf = NULL;
        if (!item || !item->path || !folder_item_parent(item) || item->no_select) {
@@ -871,32 +898,34 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
        main_window_cursor_wait(summaryview->mainwin);
 
-/*
-       mlist = item->folder->get_msg_list(item->folder, item, !update_cache);
-
-       !!! NEW !!!
-       USE LIST FROM CACHE, WILL NOT DISPLAY ANY MESSAGES DROPED
-       BY OTHER PROGRAMS TO THE FOLDER
-*/
        mlist = folder_item_get_msg_list(item);
 
-       if (summaryview->folder_item->hide_read_msgs) {
+       if (summaryview->folder_item->hide_read_msgs &&
+           quicksearch_is_active(summaryview->quicksearch) == FALSE) {
                GSList *not_killed;
                
                summary_set_hide_read_msgs_menu(summaryview, TRUE);
                not_killed = NULL;
-               for(cur = mlist ; cur != NULL ; cur = g_slist_next(cur)) {
+               for(cur = mlist ; cur != NULL && cur->data != 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)
-                            || CURRENTLY_DISPLAYED(msginfo))
-                            && !MSG_IS_IGNORE_THREAD(msginfo->flags))
-                               not_killed = g_slist_prepend(not_killed, msginfo);
-                       else
-                               procmsg_msginfo_free(msginfo);
+                       if (!msginfo->hidden) {
+                               if (MSG_IS_UNREAD(msginfo->flags) &&
+                                   !MSG_IS_IGNORE_THREAD(msginfo->flags))
+                                       not_killed = g_slist_prepend(not_killed, msginfo);
+                               else if (MSG_IS_MARKED(msginfo->flags) ||
+                                        MSG_IS_LOCKED(msginfo->flags))
+                                       not_killed = g_slist_prepend(not_killed, msginfo);
+                               else if (is_refresh &&
+                                       (msginfo->msgnum == selected_msgnum ||
+                                        msginfo->msgnum == displayed_msgnum))
+                                       not_killed = g_slist_prepend(not_killed, msginfo);
+                               else
+                                       procmsg_msginfo_free(msginfo);
+                        } else
+                               procmsg_msginfo_free(msginfo);
                }
+               hidden_removed = TRUE;
                g_slist_free(mlist);
                mlist = not_killed;
        } else {
@@ -907,15 +936,15 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                GSList *not_killed;
                
                not_killed = NULL;
-               for (cur = mlist ; cur != NULL ; cur = g_slist_next(cur)) {
+               for (cur = mlist ; cur != NULL && cur->data != NULL ; cur = g_slist_next(cur)) {
                        MsgInfo * msginfo = (MsgInfo *) cur->data;
 
-                       if (quicksearch_match(summaryview->quicksearch, msginfo))
+                       if (!msginfo->hidden && quicksearch_match(summaryview->quicksearch, msginfo))
                                not_killed = g_slist_prepend(not_killed, msginfo);
                        else
                                procmsg_msginfo_free(msginfo);
                }
-               
+               hidden_removed = TRUE;
                if (quicksearch_is_running(summaryview->quicksearch)) {
                        /* only scan subfolders when quicksearch changed,
                         * not when search is the same and folder changed */
@@ -931,38 +960,19 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                mlist = not_killed;
        }
 
-#if 0  
-       if ((global_scoring || item->prefs->scoring)) {
-               GSList *not_killed;
-               gint kill_score;
+       if (!hidden_removed) {
+               not_killed = NULL;
+               for(cur = mlist ; cur != NULL && cur->data != NULL ; cur = g_slist_next(cur)) {
+                       MsgInfo * msginfo = (MsgInfo *) cur->data;
 
-               not_killed = NULL;
-               kill_score = prefs_common.kill_score;
-               if (item->prefs->kill_score > kill_score)
-                       kill_score = item->prefs->kill_score;
-               for(cur = mlist ; cur != NULL ; cur = g_slist_next(cur)) {
-                       MsgInfo * msginfo = (MsgInfo *) cur->data;
-
-                       if (msginfo->score > kill_score)
-                               not_killed = g_slist_prepend(not_killed, msginfo);
-                       else
-                               procmsg_msginfo_free(msginfo);
-               }
+                       if (!msginfo->hidden)
+                               not_killed = g_slist_prepend(not_killed, msginfo);
+                       else
+                               procmsg_msginfo_free(msginfo);
+               }
                g_slist_free(mlist);
                mlist = not_killed;
        }
-#endif
-        not_killed = NULL;
-        for(cur = mlist ; cur != NULL ; cur = g_slist_next(cur)) {
-                MsgInfo * msginfo = (MsgInfo *) cur->data;
-                
-                if (!msginfo->hidden)
-                        not_killed = g_slist_prepend(not_killed, msginfo);
-                else
-                        procmsg_msginfo_free(msginfo);
-        }
-        g_slist_free(mlist);
-        mlist = not_killed;
 
        STATUSBAR_POP(summaryview->mainwin);
 
@@ -980,7 +990,9 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                                                   displayed_msgnum);
                if (!summaryview->displayed)
                        messageview_clear(summaryview->messageview);
+               summary_unlock(summaryview);
                summary_select_by_msgnum(summaryview, selected_msgnum);
+               summary_lock(summaryview);
                if (!summaryview->selected) {
                        /* no selected message - select first unread
                           message, but do not display it */
@@ -991,35 +1003,43 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                                        (ctree,
                                         item->sort_type == SORT_DESCENDING
                                         ? 0 : GTK_CLIST(ctree)->rows - 1);
+                       summary_unlock(summaryview);
                        summary_select_node(summaryview, node, FALSE, TRUE);
+                       summary_lock(summaryview);
                }
        } else {
-               /* select first unread message */
-#if 0
-               if (summaryview->sort_key == SORT_BY_SCORE)
-                       node = summary_find_next_important_score(summaryview,
-                                                                NULL);
-               else
-#endif
-               node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                    MSG_UNREAD, FALSE);
+               switch (prefs_common.select_on_entry) {
+                       case SELECTONENTRY_NEW:
+                               node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    MSG_NEW, FALSE);
+                               if (node == NULL)
+                                       node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    MSG_UNREAD, FALSE);
+                               break;
+                       case SELECTONENTRY_UNREAD:
+                               node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    MSG_UNREAD, FALSE);
+                               if (node == NULL)
+                                       node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    MSG_NEW, FALSE);
+                               break;
+                       default:
+                               node = NULL;
+               }
+
                if (node == NULL && GTK_CLIST(ctree)->row_list != NULL) {
                        node = gtk_ctree_node_nth
                                (ctree,
                                 item->sort_type == SORT_DESCENDING
                                 ? 0 : GTK_CLIST(ctree)->rows - 1);
                }
-               if (prefs_common.open_unread_on_enter) {
-                       summary_unlock(summaryview);
-                       summary_select_node(summaryview, node, 
-                                           messageview_is_visible(summaryview->messageview), 
-                                           TRUE);
-                       summary_lock(summaryview);
-               } else
-                       summary_select_node(summaryview, node, FALSE, TRUE);
+               summary_unlock(summaryview);
+               summary_select_node(summaryview, node,
+                                   prefs_common.always_show_msg,
+                                   TRUE);
+               summary_lock(summaryview);
        }
 
-       summary_set_column_titles(summaryview);
        summary_status_show(summaryview);
        summary_set_menu_sensitive(summaryview);
        toolbar_main_set_sensitive(summaryview->mainwin);
@@ -1036,6 +1056,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
 #undef CURRENTLY_DISPLAYED
 
+
 void summary_clear_list(SummaryView *summaryview)
 {
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
@@ -1144,7 +1165,7 @@ GSList *summary_get_selected_msg_list(SummaryView *summaryview)
        GList *cur;
        MsgInfo *msginfo;
 
-       for (cur = GTK_CLIST(summaryview->ctree)->selection; cur != NULL;
+       for (cur = GTK_CLIST(summaryview->ctree)->selection; cur != NULL && cur->data != NULL;
             cur = cur->next) {
                msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(cur->data);
                mlist = g_slist_prepend(mlist, msginfo);
@@ -1201,7 +1222,8 @@ static void summary_set_menu_sensitive(SummaryView *summaryview)
 
                {"/Move..."                     , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NOT_NEWS},
                {"/Copy..."                     , M_TARGET_EXIST|M_EXEC|M_UNLOCKED},
-               {"/Delete"                      , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NOT_NEWS},
+               {"/Move to trash"               , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NOT_NEWS},
+               {"/Delete..."                   , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NOT_NEWS},
                {"/Cancel a news message"       , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NEWS},
 
                {"/Mark"                        , M_TARGET_EXIST},
@@ -1264,7 +1286,7 @@ void summary_select_prev_unread(SummaryView *summaryview)
        node = summary_find_prev_flagged_msg
                (summaryview, summaryview->selected, MSG_UNREAD, skip_cur);
 
-       if (!node) {
+       if (!node || node == summaryview->selected) {
                AlertValue val = 0;
 
                switch (prefs_common.next_unread_msg_dialog) {
@@ -1298,12 +1320,12 @@ void summary_select_prev_unread(SummaryView *summaryview)
 void summary_select_next_unread(SummaryView *summaryview)
 {
        GtkCTreeNode *node = summaryview->selected;
-       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        gboolean skip_cur = FALSE;
        
        if (summaryview->displayed 
        &&  summaryview->selected == summaryview->displayed) {
-               debug_print("skipping cur\n");
+               debug_print("skipping cur (%p %p)\n",
+                       summaryview->displayed, summaryview->selected);
                skip_cur = TRUE;
        }
 
@@ -1316,7 +1338,7 @@ void summary_select_next_unread(SummaryView *summaryview)
        else {
                node = summary_find_next_flagged_msg
                        (summaryview, NULL, MSG_UNREAD, FALSE);
-               if (node == NULL) {
+               if (node == NULL || node == summaryview->selected) {
                        AlertValue val = 0;
 
                        switch (prefs_common.next_unread_msg_dialog) {
@@ -1338,8 +1360,6 @@ void summary_select_next_unread(SummaryView *summaryview)
                        }
 
                        if (val == G_ALERTDEFAULT) {
-                               g_signal_stop_emission_by_name(G_OBJECT(ctree),
-                                                        "key_press_event");
                                folderview_select_next_unread(summaryview->folderview);
                                return;
                        } 
@@ -1354,17 +1374,37 @@ void summary_select_next_unread(SummaryView *summaryview)
 void summary_select_prev_new(SummaryView *summaryview)
 {
        GtkCTreeNode *node;
+       gboolean skip_cur = FALSE;
+
+       if (summaryview->displayed 
+       &&  summaryview->selected == summaryview->displayed) {
+               debug_print("skipping current\n");
+               skip_cur = TRUE;
+       }
 
        node = summary_find_prev_flagged_msg
-               (summaryview, summaryview->selected, MSG_NEW, FALSE);
+               (summaryview, summaryview->selected, MSG_NEW, skip_cur);
 
-       if (!node) {
-               AlertValue val;
+       if (!node || node == summaryview->selected) {
+               AlertValue val = 0;
 
-               val = alertpanel(_("No more new messages"),
-                                _("No new message found. "
-                                  "Search from the end?"),
-                                GTK_STOCK_YES, GTK_STOCK_NO, NULL);
+               switch (prefs_common.next_unread_msg_dialog) {
+                       case NEXTUNREADMSGDIALOG_ALWAYS:
+                               val = alertpanel(_("No more new messages"),
+                                                _("No new message found. "
+                                                  "Search from the end?"),
+                                                GTK_STOCK_YES, GTK_STOCK_NO, NULL);
+                               break;
+                       case NEXTUNREADMSGDIALOG_ASSUME_YES:
+                               val = G_ALERTDEFAULT;
+                               break;
+                       case NEXTUNREADMSGDIALOG_ASSUME_NO:
+                               val = !G_ALERTDEFAULT;
+                               break;
+                       default:
+                               debug_print(
+                                       _("Internal error: unexpected value for prefs_common.next_unread_msg_dialog\n"));
+               }
                if (val != G_ALERTDEFAULT) return;
                node = summary_find_prev_flagged_msg(summaryview, NULL,
                                                     MSG_NEW, FALSE);
@@ -1379,29 +1419,55 @@ void summary_select_prev_new(SummaryView *summaryview)
 void summary_select_next_new(SummaryView *summaryview)
 {
        GtkCTreeNode *node = summaryview->selected;
-       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-
-       while ((node = summary_find_next_flagged_msg
-               (summaryview, node, MSG_NEW, FALSE)) == NULL) {
-               AlertValue val;
-
-               val = alertpanel(_("No more new messages"),
-                                _("No new message found. "
-                                  "Go to next folder?"),
-                                GTK_STOCK_YES, _("Search again"),
-                                GTK_STOCK_NO);
-               if (val == G_ALERTDEFAULT) {
-                       g_signal_stop_emission_by_name(G_OBJECT(ctree),"key_press_event");
-                       folderview_select_next_unread(summaryview->folderview);
-                       return;
-               } else if (val == G_ALERTALTERNATE)
-                       node = NULL;
-               else
-                       return;
+       gboolean skip_cur = FALSE;
+       
+       if (summaryview->displayed 
+       &&  summaryview->selected == summaryview->displayed) {
+               debug_print("skipping cur (%p %p)\n",
+                       summaryview->displayed, summaryview->selected);
+               skip_cur = TRUE;
        }
 
+
+       node = summary_find_next_flagged_msg
+               (summaryview, node, MSG_NEW, skip_cur);
+       
        if (node)
                summary_select_node(summaryview, node, TRUE, FALSE);
+       else {
+               node = summary_find_next_flagged_msg
+                       (summaryview, NULL, MSG_NEW, FALSE);
+               if (node == NULL || node == summaryview->selected) {
+                       AlertValue val = 0;
+
+                       switch (prefs_common.next_unread_msg_dialog) {
+                               case NEXTUNREADMSGDIALOG_ALWAYS:
+                                       val = alertpanel(_("No more new messages"),
+                                                        _("No new message found. "
+                                                          "Go to next folder?"),
+                                                        GTK_STOCK_YES, GTK_STOCK_NO, NULL);
+                                       break;
+                               case NEXTUNREADMSGDIALOG_ASSUME_YES:
+                                       val = G_ALERTDEFAULT;
+                                       break;
+                               case NEXTUNREADMSGDIALOG_ASSUME_NO:
+                                       val = G_ALERTOTHER;
+                                       break;
+                               default:
+                                       debug_print(
+                                               _("Internal error: unexpected value for prefs_common.next_unread_msg_dialog\n"));
+                       }
+
+                       if (val == G_ALERTDEFAULT) {
+                               folderview_select_next_new(summaryview->folderview);
+                               return;
+                       } 
+                       else
+                               return;
+               } else
+                       summary_select_node(summaryview, node, TRUE, FALSE);
+
+       }
 }
 
 void summary_select_prev_marked(SummaryView *summaryview)
@@ -1536,19 +1602,24 @@ void summary_select_node(SummaryView *summaryview, GtkCTreeNode *node,
                        gtk_widget_grab_focus(GTK_WIDGET(ctree));
                        gtk_ctree_node_moveto(ctree, node, -1, 0.5, 0);
                }
-               gtk_sctree_unselect_all(GTK_SCTREE(ctree));
+               summary_unselect_all(summaryview);
                if (display_msg && summaryview->displayed == node)
                        summaryview->displayed = NULL;
                summaryview->display_msg = display_msg;
                gtk_sctree_select(GTK_SCTREE(ctree), node);
+               if (summaryview->selected == NULL)
+                       summaryview->selected = node;
        }
 }
 
 static guint summary_get_msgnum(SummaryView *summaryview, GtkCTreeNode *node)
 {
-       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GtkCTree *ctree =NULL;
        MsgInfo *msginfo;
 
+       if (!summaryview)
+               return 0;
+       ctree = GTK_CTREE(summaryview->ctree);
        if (!node)
                return 0;
        msginfo = gtk_ctree_node_get_row_data(ctree, node);
@@ -1774,10 +1845,6 @@ static void summary_set_marks_func(GtkCTree *ctree, GtkCTreeNode *node,
            msginfo->folder->folder->klass->type == F_NEWS)
                news_flag_crosspost(msginfo);
 
-       if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
-       && procmsg_msg_has_marked_parent(msginfo))
-               summaryview->unreadmarked++;
-
        if (MSG_IS_DELETED(msginfo->flags))
                summaryview->deleted++;
 
@@ -1799,9 +1866,6 @@ static void summary_update_status(SummaryView *summaryview)
             node != NULL; node = gtkut_ctree_node_next(ctree, node)) {
                msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(node);
 
-               if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
-               && procmsg_msg_has_marked_parent(msginfo))
-                       summaryview->unreadmarked++;
                if (MSG_IS_DELETED(msginfo->flags))
                        summaryview->deleted++;
                if (MSG_IS_MOVE(msginfo->flags))
@@ -1833,7 +1897,7 @@ static void summary_status_show(SummaryView *summaryview)
        }
 
        rowlist = GTK_CLIST(summaryview->ctree)->selection;
-       for (cur = rowlist; cur != NULL; cur = cur->next) {
+       for (cur = rowlist; cur != NULL && cur->data != NULL; cur = cur->next) {
                msginfo = gtk_ctree_node_get_row_data
                        (GTK_CTREE(summaryview->ctree),
                         GTK_CTREE_NODE(cur->data));
@@ -1921,6 +1985,7 @@ static void summary_set_column_titles(SummaryView *summaryview)
                SORT_BY_MIME,
                SORT_BY_SUBJECT,
                SORT_BY_FROM,
+               SORT_BY_TO,
                SORT_BY_DATE,
                SORT_BY_SIZE,
                SORT_BY_NUMBER,
@@ -1939,6 +2004,7 @@ static void summary_set_column_titles(SummaryView *summaryview)
                switch (type) {
                case S_COL_SUBJECT:
                case S_COL_FROM:
+               case S_COL_TO:
                case S_COL_DATE:
                case S_COL_NUMBER:
                        if (prefs_common.trans_hdr)
@@ -1960,8 +2026,7 @@ static void summary_set_column_titles(SummaryView *summaryview)
                        gtk_widget_show(label);
                        gtk_clist_set_column_widget(clist, pos, label);
                        continue;
-               }
-               if (single_char) {
+               } else if (single_char) {
                        gtk_clist_set_column_title(clist, pos, title);
                        continue;
                }
@@ -2002,12 +2067,28 @@ static void summary_set_column_titles(SummaryView *summaryview)
        }
 }
 
+void summary_reflect_prefs(void)
+{
+       SummaryView *summaryview = NULL;
+       if (!mainwindow_get_mainwindow())
+               return;
+       summaryview = mainwindow_get_mainwindow()->summaryview;
+       bold_style = bold_marked_style = bold_deleted_style = 
+               small_style = small_marked_style = small_deleted_style = NULL;
+       summary_set_fonts(summaryview);
+       summary_set_column_titles(summaryview);
+       summary_show(summaryview, summaryview->folder_item);
+}
+
 void summary_sort(SummaryView *summaryview,
                  FolderSortKey sort_key, FolderSortType sort_type)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
        GtkCListCompareFunc cmp_func = NULL;
+       g_signal_handlers_block_by_func(G_OBJECT(summaryview->ctree),
+                                      G_CALLBACK(summary_tree_expanded), summaryview);
+       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
 
        switch (sort_key) {
        case SORT_BY_MARK:
@@ -2052,7 +2133,7 @@ void summary_sort(SummaryView *summaryview,
        case SORT_BY_NONE:
                break;
        default:
-               return;
+               goto unlock;
        }
 
        summaryview->sort_key = sort_key;
@@ -2063,7 +2144,7 @@ void summary_sort(SummaryView *summaryview,
 
        /* allow fallback to don't sort */
        if (summaryview->sort_key == SORT_BY_NONE)
-               return;
+               goto unlock;
 
        if (cmp_func != NULL) {
                debug_print("Sorting summary...");
@@ -2086,6 +2167,10 @@ void summary_sort(SummaryView *summaryview,
                debug_print("done.\n");
                STATUSBAR_POP(summaryview->mainwin);
        }
+unlock:
+       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       g_signal_handlers_unblock_by_func(G_OBJECT(summaryview->ctree),
+                                      G_CALLBACK(summary_tree_expanded), summaryview);
 }
 
 gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
@@ -2112,7 +2197,8 @@ gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
        SET_TEXT(S_COL_SIZE);
        SET_TEXT(S_COL_DATE);
        SET_TEXT(S_COL_FROM);
-       SET_TEXT(S_COL_SUBJECT);
+       SET_TEXT(S_COL_TO);
+       /* SET_TEXT(S_COL_SUBJECT);  already set by node info */
 
 #undef SET_TEXT
 
@@ -2154,11 +2240,6 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
        if (prefs_common.use_addr_book)
                start_address_completion();
        
-       for (cur = mlist ; cur != NULL; cur = cur->next) {
-               msginfo = (MsgInfo *)cur->data;
-               msginfo->threadscore = msginfo->score;
-       }
-
        if (summaryview->threaded) {
                GNode *root, *gnode;
 
@@ -2226,11 +2307,13 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
 
        node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
 
-       while (prefs_common.bold_unread && node) {
-               GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
-               if (GTK_CTREE_ROW(node)->children)
-                       summary_set_row_marks(summaryview, node);
-               node = next;
+       if (prefs_common.bold_unread) {
+               while (node) {
+                       GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
+                       if (GTK_CTREE_ROW(node)->children)
+                               summary_set_row_marks(summaryview, node);
+                       node = next;
+               }
        }
 
        g_signal_handlers_unblock_by_func(G_OBJECT(ctree),
@@ -2242,6 +2325,9 @@ static gchar *summary_complete_address(const gchar *addr)
 {
        gint count;
        gchar *res, *tmp, *email_addr;
+       
+       if (addr == NULL)
+               return NULL;
 
        Xstrdup_a(email_addr, addr, return NULL);
        extract_address(email_addr);
@@ -2253,8 +2339,6 @@ static gchar *summary_complete_address(const gchar *addr)
        res = NULL;
        if (1 < (count = complete_address(email_addr))) {
                tmp = get_complete_address(1);
-/*     tmp = addressbook_lookup_name( email_addr );
-       if( tmp ) { */
                res = procheader_get_fromname(tmp);
                g_free(tmp);
        }
@@ -2266,16 +2350,20 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
                               MsgInfo *msginfo)
 {
        static gchar date_modified[80];
-       static gchar *to = NULL;
        static gchar col_score[11];
        static gchar buf[BUFFSIZE];
        gint *col_pos = summaryview->col_pos;
-       FolderType ftype = F_UNKNOWN;
-
-       text[col_pos[S_COL_MARK]]   = NULL;
-       text[col_pos[S_COL_STATUS]] = NULL;
-       text[col_pos[S_COL_MIME]]   = NULL;
-       text[col_pos[S_COL_LOCKED]] = NULL;
+       gchar *from_text = NULL, *to_text = NULL;
+       gboolean should_swap = FALSE;
+
+       text[col_pos[S_COL_FROM]]   = "";
+       text[col_pos[S_COL_TO]]     = "";
+       text[col_pos[S_COL_SUBJECT]]= "";
+       text[col_pos[S_COL_MARK]]   = "";
+       text[col_pos[S_COL_STATUS]] = "";
+       text[col_pos[S_COL_MIME]]   = "";
+       text[col_pos[S_COL_LOCKED]] = "";
+       text[col_pos[S_COL_DATE]]   = "";
        text[col_pos[S_COL_NUMBER]] = itos(msginfo->msgnum);
        text[col_pos[S_COL_SIZE]]   = to_human_readable(msginfo->size);
        text[col_pos[S_COL_SCORE]]  = itos_buf(col_score, msginfo->score);
@@ -2290,48 +2378,48 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
        else
                text[col_pos[S_COL_DATE]] = _("(No Date)");
 
-       text[col_pos[S_COL_FROM]] = msginfo->fromname ? msginfo->fromname :
-               _("(No From)");
-       
-       if (msginfo->folder && msginfo->folder->folder)
-               ftype = msginfo->folder->folder->klass->type; 
-               
-       if (ftype != F_NEWS && prefs_common.swap_from && msginfo->from && msginfo->to) {
+       if (prefs_common.swap_from && msginfo->from && msginfo->to) {
                gchar *addr = NULL;
+               
+               addr = g_strdup(msginfo->from);
 
-               Xstrdup_a(addr, msginfo->from, return);
-               extract_address(addr);
-               if (prefs_common.use_addr_book) {
+               if (addr) {
+                       extract_address(addr);
                        if (account_find_from_address(addr)) {
-                               addr = summary_complete_address(msginfo->to);
-                               g_free(to);
-                               to   = g_strconcat("-->", addr == NULL ? msginfo->to : addr, NULL);
-                               text[col_pos[S_COL_FROM]] = to;
-                               g_free(addr);
-                       }
-               } else {
-                       if (account_find_from_address(addr)) {
-                               g_free(to);
-                               to = g_strconcat("-->", msginfo->to, NULL);
-                               text[col_pos[S_COL_FROM]] = to;
+                               should_swap = TRUE;
                        }
+                       g_free(addr);
                }
        }
 
-       /*
-        * CLAWS: note that the "text[col_pos[S_COL_FROM]] != to" is really a hack, 
-        * checking whether the above block (which handles the special case of
-        * the --> in sent boxes) was executed.
-        */
-       if (text[col_pos[S_COL_FROM]] != to && prefs_common.use_addr_book && msginfo->from) {
-               gchar *from = summary_complete_address(msginfo->from);
-               if (from) {
-                       g_free(to);
-                       to = from;
-                       text[col_pos[S_COL_FROM]] = to;
-               }                       
+       if (!prefs_common.use_addr_book) {
+               from_text = msginfo->fromname ? 
+                               msginfo->fromname :
+                               _("(No From)");
+       } else {
+               gchar *tmp = summary_complete_address(msginfo->from);
+               from_text = tmp ? tmp : (msginfo->fromname ?
+                                        msginfo->fromname: 
+                                               _("(No From)"));
        }
-
+       
+       to_text = msginfo->to ? msginfo->to : 
+                  (msginfo->cc ? msginfo->cc :
+                    (msginfo->newsgroups ? msginfo->newsgroups : _("(No Recipient)")
+                    )
+                  );
+
+       if (!should_swap) {
+               text[col_pos[S_COL_FROM]] = from_text;
+               text[col_pos[S_COL_TO]] = to_text;
+       } else {
+               gchar *tmp = NULL;
+               tmp = g_strconcat("-->", to_text, NULL);
+               text[col_pos[S_COL_FROM]] = tmp;
+               tmp = g_strconcat("<--", from_text, NULL);
+               text[col_pos[S_COL_TO]] = tmp;
+       }
+       
        if (summaryview->simplify_subject_preg != NULL)
                text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? 
                        string_remove_match(buf, BUFFSIZE, msginfo->subject, 
@@ -2347,6 +2435,96 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row)
        summary_display_msg_full(summaryview, row, FALSE, FALSE);
 }
 
+static gboolean defer_change(gpointer data);
+typedef struct _ChangeData {
+       MsgInfo *info;
+       gint op; /* 0, 1, 2 for unset, set, change */
+       MsgPermFlags set_flags;
+       MsgTmpFlags  set_tmp_flags;
+       MsgPermFlags unset_flags;
+       MsgTmpFlags  unset_tmp_flags;
+} ChangeData;
+
+static void summary_msginfo_unset_flags(MsgInfo *msginfo, MsgPermFlags flags, MsgTmpFlags tmp_flags)
+{
+       if (!msginfo->folder || !msginfo->folder->processing_pending) {
+               debug_print("flags: doing unset now\n");
+               procmsg_msginfo_unset_flags(msginfo, flags, tmp_flags);
+       } else {
+               ChangeData *unset_data = g_new0(ChangeData, 1);
+               unset_data->info = msginfo;
+               unset_data->op = 0;
+               unset_data->unset_flags = flags;
+               unset_data->unset_tmp_flags = tmp_flags;
+               debug_print("flags: deferring unset\n");
+               g_timeout_add(100, defer_change, unset_data);
+       }
+}
+
+static void summary_msginfo_set_flags(MsgInfo *msginfo, MsgPermFlags flags, MsgTmpFlags tmp_flags)
+{
+       if (!msginfo->folder || !msginfo->folder->processing_pending) {
+               debug_print("flags: doing set now\n");
+               procmsg_msginfo_set_flags(msginfo, flags, tmp_flags);
+       } else {
+               ChangeData *set_data = g_new0(ChangeData, 1);
+               set_data->info = msginfo;
+               set_data->op = 1;
+               set_data->set_flags = flags;
+               set_data->set_tmp_flags = tmp_flags;
+               debug_print("flags: deferring set\n");
+               g_timeout_add(100, defer_change, set_data);
+       }
+}
+
+static void summary_msginfo_change_flags(MsgInfo *msginfo, 
+               MsgPermFlags add_flags, MsgTmpFlags add_tmp_flags,
+               MsgPermFlags rem_flags, MsgTmpFlags rem_tmp_flags)
+{
+       if (!msginfo->folder || !msginfo->folder->processing_pending) {
+               debug_print("flags: doing change now\n");
+               procmsg_msginfo_change_flags(msginfo, add_flags, add_tmp_flags,
+                       rem_flags, rem_tmp_flags);
+       } else {
+               ChangeData *change_data = g_new0(ChangeData, 1);
+               change_data->info = msginfo;
+               change_data->op = 2;
+               change_data->set_flags = add_flags;
+               change_data->set_tmp_flags = add_tmp_flags;
+               change_data->unset_flags = rem_flags;
+               change_data->unset_tmp_flags = rem_tmp_flags;
+               debug_print("flags: deferring change\n");
+               g_timeout_add(100, defer_change, change_data);
+       }
+}
+
+gboolean defer_change(gpointer data)
+{
+       ChangeData *chg = (ChangeData *)data;
+       if (chg->info->folder && chg->info->folder->processing_pending) {
+               debug_print("flags: trying later\n");
+               return TRUE; /* try again */
+       } else {
+               debug_print("flags: finally doing it\n");
+               switch(chg->op) {
+               case 0:
+                       procmsg_msginfo_unset_flags(chg->info, chg->unset_flags, chg->unset_tmp_flags);
+                       break;
+               case 1:
+                       procmsg_msginfo_set_flags(chg->info, chg->set_flags, chg->set_tmp_flags);
+                       break;
+               case 2:
+                       procmsg_msginfo_change_flags(chg->info, chg->set_flags, chg->set_tmp_flags,
+                               chg->unset_flags, chg->unset_tmp_flags);
+                       break;
+               default:
+                       g_warning("shouldn't happen\n");
+               }
+               g_free(chg);
+       }
+       return FALSE;
+}
+
 static void msginfo_mark_as_read (SummaryView *summaryview, MsgInfo *msginfo,
                                      GtkCTreeNode *row)
 {
@@ -2354,11 +2532,8 @@ static void msginfo_mark_as_read (SummaryView *summaryview, MsgInfo *msginfo,
        g_return_if_fail(msginfo != NULL);
        g_return_if_fail(row != NULL);
 
-       if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags) 
-       && procmsg_msg_has_marked_parent(msginfo))
-               summaryview->unreadmarked--;
        if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
-               procmsg_msginfo_unset_flags
+               summary_msginfo_unset_flags
                        (msginfo, MSG_NEW | MSG_UNREAD, 0);
                summary_set_row_marks(summaryview, row);
                gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
@@ -2504,9 +2679,10 @@ void summary_reedit(SummaryView *summaryview)
 
        if (!summaryview->selected) return;
        if (!summaryview->folder_item) return;
-       if (summaryview->folder_item->stype != F_OUTBOX &&
-           summaryview->folder_item->stype != F_DRAFT  &&
-           summaryview->folder_item->stype != F_QUEUE) return;
+       if (!folder_has_parent_of_type(summaryview->folder_item, F_OUTBOX)
+       &&  !folder_has_parent_of_type(summaryview->folder_item, F_DRAFT)
+       &&  !folder_has_parent_of_type(summaryview->folder_item, F_QUEUE))
+               return;
 
        msginfo = gtk_ctree_node_get_row_data(GTK_CTREE(summaryview->ctree),
                                              summaryview->selected);
@@ -2521,7 +2697,6 @@ gboolean summary_step(SummaryView *summaryview, GtkScrollType type)
        GtkCTreeNode *node;
 
        if (summary_is_locked(summaryview)) return FALSE;
-
        if (type == GTK_SCROLL_STEP_FORWARD) {
                node = gtkut_ctree_node_next(ctree, summaryview->selected);
                if (node)
@@ -2630,7 +2805,7 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
                                          forwardedxpm, forwardedxpmmask);
        } else {
                gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_STATUS],
-                                       NULL);
+                                       "");
        }
 
        if (prefs_common.bold_unread &&
@@ -2682,7 +2857,7 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
                                              &summaryview->color_important);
 #endif
        } else {
-               gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_MARK], NULL);
+               gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_MARK], "");
        }
 
        if (MSG_IS_LOCKED(flags)) {
@@ -2690,7 +2865,7 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
                                          lockedxpm, lockedxpmmask);
        }
        else {
-               gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_LOCKED], NULL);
+               gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_LOCKED], "");
        }
 
        if (MSG_IS_WITH_ATTACHMENT(flags) && MSG_IS_SIGNED(flags)) {
@@ -2709,7 +2884,7 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
                gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_MIME],
                                          clipxpm, clipxpmmask);
        } else {
-               gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_MIME], NULL);
+               gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_MIME], "");
        }
        if (!style)
                style = small_style;
@@ -2720,15 +2895,6 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
                summary_set_colorlabel_color(ctree, row, MSG_GET_COLORLABEL_VALUE(flags));
 }
 
-void summary_set_marks_selected(SummaryView *summaryview)
-{
-       GList *cur;
-
-       for (cur = GTK_CLIST(summaryview->ctree)->selection; cur != NULL;
-            cur = cur->next)
-               summary_set_row_marks(summaryview, GTK_CTREE_NODE(cur->data));
-}
-
 static void summary_mark_row(SummaryView *summaryview, GtkCTreeNode *row)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
@@ -2741,11 +2907,9 @@ static void summary_mark_row(SummaryView *summaryview, GtkCTreeNode *row)
                summaryview->moved--;
        if (MSG_IS_COPY(msginfo->flags))
                summaryview->copied--;
-       procmsg_update_unread_children (msginfo, TRUE);
 
        procmsg_msginfo_set_to_folder(msginfo, NULL);
-       procmsg_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_MOVE | MSG_COPY);
-       procmsg_msginfo_set_flags(msginfo, MSG_MARKED, 0);
+       summary_msginfo_change_flags(msginfo, MSG_MARKED, 0, MSG_DELETED, MSG_MOVE | MSG_COPY);
        summary_set_row_marks(summaryview, row);
        debug_print("Message %s/%d is marked\n", msginfo->folder->path, msginfo->msgnum);
 }
@@ -2768,8 +2932,8 @@ static void summary_lock_row(SummaryView *summaryview, GtkCTreeNode *row)
                changed = TRUE;
        }
        procmsg_msginfo_set_to_folder(msginfo, NULL);
-       procmsg_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_MOVE | MSG_COPY);
-       procmsg_msginfo_set_flags(msginfo, MSG_LOCKED, 0);
+       summary_msginfo_change_flags(msginfo, MSG_LOCKED, 0, MSG_DELETED, MSG_MOVE | MSG_COPY);
+       
        summary_set_row_marks(summaryview, row);
        debug_print("Message %d is locked\n", msginfo->msgnum);
 }
@@ -2783,7 +2947,7 @@ static void summary_unlock_row(SummaryView *summaryview, GtkCTreeNode *row)
        if (!MSG_IS_LOCKED(msginfo->flags))
                return;
        procmsg_msginfo_set_to_folder(msginfo, NULL);
-       procmsg_msginfo_unset_flags(msginfo, MSG_LOCKED, 0);
+       summary_msginfo_unset_flags(msginfo, MSG_LOCKED, 0);
        summary_set_row_marks(summaryview, row);
        debug_print("Message %d is unlocked\n", msginfo->msgnum);
 }
@@ -2793,14 +2957,13 @@ void summary_mark(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       folder_item_set_batch(summaryview->folder_item, TRUE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
                summary_mark_row(summaryview, GTK_CTREE_NODE(cur->data));
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       folder_item_set_batch(summaryview->folder_item, FALSE);
+       END_LONG_OPERATION(summaryview);
 
-       /* summary_step(summaryview, GTK_SCROLL_STEP_FORWARD); */
        summary_status_show(summaryview);
 }
 
@@ -2815,11 +2978,7 @@ static void summary_mark_row_as_read(SummaryView *summaryview,
        if(!(MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)))
                return;
 
-       if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
-       && procmsg_msg_has_marked_parent(msginfo))
-               summaryview->unreadmarked--;
-
-       procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0);
+       summary_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0);
        summary_set_row_marks(summaryview, row);
        debug_print("Message %d is marked as read\n",
                msginfo->msgnum);
@@ -2830,14 +2989,14 @@ void summary_mark_as_read(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       folder_item_set_batch(summaryview->folder_item, TRUE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
                summary_mark_row_as_read(summaryview,
                                         GTK_CTREE_NODE(cur->data));
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
-
+       folder_item_set_batch(summaryview->folder_item, FALSE);
+       END_LONG_OPERATION(summaryview);
+       
        summary_status_show(summaryview);
 }
 
@@ -2846,13 +3005,11 @@ void summary_msgs_lock(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
                summary_lock_row(summaryview,
                                         GTK_CTREE_NODE(cur->data));
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       END_LONG_OPERATION(summaryview);
        
        summary_status_show(summaryview);
 }
@@ -2862,13 +3019,11 @@ void summary_msgs_unlock(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
                summary_unlock_row(summaryview,
                                   GTK_CTREE_NODE(cur->data));
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       END_LONG_OPERATION(summaryview);
        
        summary_status_show(summaryview);
 }
@@ -2876,22 +3031,21 @@ void summary_msgs_unlock(SummaryView *summaryview)
 void summary_mark_all_read(SummaryView *summaryview)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-       GtkCList *clist = GTK_CLIST(summaryview->ctree);
        GtkCTreeNode *node;
 
-       gtk_clist_freeze(clist);
-       folder_item_update_freeze();
+       START_LONG_OPERATION(summaryview);
+       folder_item_set_batch(summaryview->folder_item, TRUE);
        for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); node != NULL;
             node = gtkut_ctree_node_next(ctree, node))
                summary_mark_row_as_read(summaryview, node);
+       folder_item_set_batch(summaryview->folder_item, FALSE);
        for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); node != NULL;
             node = gtkut_ctree_node_next(ctree, node)) {
                if (!GTK_CTREE_ROW(node)->expanded)
                        summary_set_row_marks(summaryview, node);
        }
-       folder_item_update_thaw();
-       gtk_clist_thaw(clist);
-
+       END_LONG_OPERATION(summaryview);
+       
        summary_status_show(summaryview);
 }
 
@@ -2904,15 +3058,11 @@ static void summary_mark_row_as_unread(SummaryView *summaryview,
        msginfo = gtk_ctree_node_get_row_data(ctree, row);
        if (MSG_IS_DELETED(msginfo->flags)) {
                procmsg_msginfo_set_to_folder(msginfo, NULL);
-               procmsg_msginfo_unset_flags(msginfo, MSG_DELETED, 0);
+               summary_msginfo_unset_flags(msginfo, MSG_DELETED, 0);
                summaryview->deleted--;
        }
 
-       if (!MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
-       && procmsg_msg_has_marked_parent(msginfo))
-               summaryview->unreadmarked++;
-
-       procmsg_msginfo_set_flags(msginfo, MSG_UNREAD, 0);
+       summary_msginfo_set_flags(msginfo, MSG_UNREAD, 0);
        debug_print("Message %d is marked as unread\n",
                msginfo->msgnum);
 
@@ -2924,13 +3074,14 @@ void summary_mark_as_unread(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       folder_item_set_batch(summaryview->folder_item, TRUE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; 
+               cur = cur->next)
                summary_mark_row_as_unread(summaryview,
                                           GTK_CTREE_NODE(cur->data));
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       folder_item_set_batch(summaryview->folder_item, FALSE);
+       END_LONG_OPERATION(summaryview);
        
        summary_status_show(summaryview);
 }
@@ -3002,15 +3153,13 @@ static void summary_delete_row(SummaryView *summaryview, GtkCTreeNode *row)
                summaryview->moved--;
        if (MSG_IS_COPY(msginfo->flags))
                summaryview->copied--;
-       procmsg_update_unread_children (msginfo, FALSE);
 
        procmsg_msginfo_set_to_folder(msginfo, NULL);
-       procmsg_msginfo_unset_flags(msginfo, MSG_MARKED, MSG_MOVE | MSG_COPY);
-       procmsg_msginfo_set_flags(msginfo, MSG_DELETED, 0);
+       summary_msginfo_change_flags(msginfo, MSG_DELETED, 0, MSG_MARKED, MSG_MOVE | MSG_COPY);
        summaryview->deleted++;
 
        if (!prefs_common.immediate_exec && 
-           summaryview->folder_item->stype != F_TRASH)
+           !folder_has_parent_of_type(summaryview->folder_item, F_TRASH))
                summary_set_row_marks(summaryview, row);
 
        debug_print("Message %s/%d is set to delete\n",
@@ -3052,59 +3201,82 @@ void summary_delete(SummaryView *summaryview)
        GList *cur;
        GtkCTreeNode *sel_last = NULL;
        GtkCTreeNode *node;
+       AlertValue aval;
+       MsgInfo *msginfo;
 
        if (!item) return;
 
        if (summary_is_locked(summaryview)) return;
 
-       /* if current folder is trash, ask for confirmation */
-       if (item->stype == F_TRASH) {
-               AlertValue aval;
-               MsgInfo *msginfo;
+       if (!summaryview->folder_item ||
+           FOLDER_TYPE(summaryview->folder_item->folder) == F_NEWS) return;
 
-               aval = alertpanel(_("Delete message(s)"),
-                                 _("Do you really want to delete message(s) from the trash?"),
-                                 GTK_STOCK_YES, GTK_STOCK_NO, NULL);
-               if (aval != G_ALERTDEFAULT) return;
+       aval = alertpanel(_("Delete message(s)"),
+                         _("Do you really want to delete selected message(s)?"),
+                         GTK_STOCK_YES, GTK_STOCK_NO, NULL);
+       if (aval != G_ALERTDEFAULT) return;
 
-               for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next) {
-                       GtkCTreeNode *row = GTK_CTREE_NODE(cur->data);
-                       msginfo = gtk_ctree_node_get_row_data(ctree, row);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; 
+            cur = cur->next) {
+               GtkCTreeNode *row = GTK_CTREE_NODE(cur->data);
+               msginfo = gtk_ctree_node_get_row_data(ctree, row);
+               if (msginfo->total_size != 0 && 
+                   msginfo->size != (off_t)msginfo->total_size)
                        partial_mark_for_delete(msginfo);
-               }
-       
        }
 
        main_window_cursor_wait(summaryview->mainwin);
 
        /* next code sets current row focus right. We need to find a row
         * that is not deleted. */
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree)); 
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next) {
+       START_LONG_OPERATION(summaryview);
+       folder_item_set_batch(summaryview->folder_item, TRUE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next) {
                sel_last = GTK_CTREE_NODE(cur->data);
                summary_delete_row(summaryview, sel_last);
        }
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       folder_item_set_batch(summaryview->folder_item, FALSE);
+       END_LONG_OPERATION(summaryview);
 
        node = summary_find_next_msg(summaryview, sel_last);
        if (!node)
                node = summary_find_prev_msg(summaryview, sel_last);
 
-       summary_select_node(summaryview, node, FALSE, FALSE);
+       summary_select_node(summaryview, node, prefs_common.always_show_msg, TRUE);
        
-       if (prefs_common.immediate_exec || item->stype == F_TRASH) {
+       if (prefs_common.immediate_exec || folder_has_parent_of_type(item, F_TRASH)) {
                summary_execute(summaryview);
                /* after deleting, the anchor may be at an invalid row
                 * so reset it to the node we found earlier */
                gtk_sctree_set_anchor_row(GTK_SCTREE(ctree), node);
        } else
                summary_status_show(summaryview);
+
                
        main_window_cursor_normal(summaryview->mainwin);
 }
 
+void summary_delete_trash(SummaryView *summaryview)
+{
+       FolderItem *to_folder = NULL;
+       PrefsAccount *ac;
+       if (!summaryview->folder_item ||
+           FOLDER_TYPE(summaryview->folder_item->folder) == F_NEWS) return;
+       
+       if (NULL != (ac = account_find_from_item(summaryview->folder_item)))
+               to_folder = account_get_special_folder(ac, F_TRASH);
+
+       if (to_folder == NULL)
+               to_folder = summaryview->folder_item->folder->trash;
+       
+       if (to_folder == NULL || to_folder == summaryview->folder_item
+           || folder_has_parent_of_type(summaryview->folder_item, F_TRASH))
+               summary_delete(summaryview);
+       else
+               summary_move_selected_to(summaryview, to_folder);
+}
+
+
 static void summary_unmark_row(SummaryView *summaryview, GtkCTreeNode *row)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
@@ -3117,10 +3289,9 @@ static void summary_unmark_row(SummaryView *summaryview, GtkCTreeNode *row)
                summaryview->moved--;
        if (MSG_IS_COPY(msginfo->flags))
                summaryview->copied--;
-       procmsg_update_unread_children (msginfo, FALSE);
 
        procmsg_msginfo_set_to_folder(msginfo, NULL);
-       procmsg_msginfo_unset_flags(msginfo, MSG_MARKED | MSG_DELETED, MSG_MOVE | MSG_COPY);
+       summary_msginfo_unset_flags(msginfo, MSG_MARKED | MSG_DELETED, MSG_MOVE | MSG_COPY);
        summary_set_row_marks(summaryview, row);
 
        debug_print("Message %s/%d is unmarked\n",
@@ -3132,15 +3303,13 @@ void summary_unmark(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree)); 
-
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       folder_item_set_batch(summaryview->folder_item, TRUE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
                summary_unmark_row(summaryview, GTK_CTREE_NODE(cur->data));
-
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
-
+       folder_item_set_batch(summaryview->folder_item, FALSE);
+       END_LONG_OPERATION(summaryview);
+       
        summary_status_show(summaryview);
 }
 
@@ -3162,11 +3331,13 @@ static void summary_move_row_to(SummaryView *summaryview, GtkCTreeNode *row,
        if (MSG_IS_COPY(msginfo->flags)) {
                summaryview->copied--;
        }
-       procmsg_msginfo_unset_flags(msginfo, MSG_MARKED | MSG_DELETED, MSG_COPY);
        if (!MSG_IS_MOVE(msginfo->flags)) {
-               procmsg_msginfo_set_flags(msginfo, 0, MSG_MOVE);
+               summary_msginfo_change_flags(msginfo, 0, MSG_MOVE, MSG_DELETED, MSG_COPY);
                summaryview->moved++;
+       } else {
+               summary_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_COPY);
        }
+       
        if (!prefs_common.immediate_exec) {
                summary_set_row_marks(summaryview, row);
        }
@@ -3190,22 +3361,18 @@ void summary_move_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                return;
        }
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree)); 
+       START_LONG_OPERATION(summaryview);
 
        for (cur = GTK_CLIST(summaryview->ctree)->selection;
-            cur != NULL; cur = cur->next)
+            cur != NULL && cur->data != NULL; cur = cur->next)
                summary_move_row_to
                        (summaryview, GTK_CTREE_NODE(cur->data), to_folder);
 
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
-
-       summary_step(summaryview, GTK_SCROLL_STEP_FORWARD);
+       END_LONG_OPERATION(summaryview);
 
-       if (prefs_common.immediate_exec)
+       if (prefs_common.immediate_exec) {
                summary_execute(summaryview);
-       else {
+       else {
                summary_status_show(summaryview);
        }
        
@@ -3213,7 +3380,7 @@ void summary_move_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                GtkCTreeNode *node = gtk_ctree_node_nth (GTK_CTREE(summaryview->ctree), 
                                                         GTK_CLIST(summaryview->ctree)->rows - 1);
                if (node)
-                       summary_select_node(summaryview, node, TRUE, TRUE);
+                       summary_select_node(summaryview, node, prefs_common.always_show_msg, TRUE);
        }
 
 }
@@ -3245,10 +3412,12 @@ static void summary_copy_row_to(SummaryView *summaryview, GtkCTreeNode *row,
        if (MSG_IS_MOVE(msginfo->flags)) {
                summaryview->moved--;
        }
-       procmsg_msginfo_unset_flags(msginfo, MSG_MARKED | MSG_DELETED, MSG_MOVE);
+       
        if (!MSG_IS_COPY(msginfo->flags)) {
-               procmsg_msginfo_set_flags(msginfo, 0, MSG_COPY);
+               summary_msginfo_change_flags(msginfo, 0, MSG_COPY, MSG_DELETED, MSG_MOVE);
                summaryview->copied++;
+       } else {
+               summary_msginfo_unset_flags(msginfo, MSG_DELETED, MSG_MOVE);
        }
        if (!prefs_common.immediate_exec) {
                summary_set_row_marks(summaryview, row);
@@ -3273,18 +3442,14 @@ void summary_copy_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                return;
        }
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree)); 
+       START_LONG_OPERATION(summaryview);
 
        for (cur = GTK_CLIST(summaryview->ctree)->selection;
-            cur != NULL; cur = cur->next)
+            cur != NULL && cur->data != NULL; cur = cur->next)
                summary_copy_row_to
                        (summaryview, GTK_CTREE_NODE(cur->data), to_folder);
 
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
-
-       summary_step(summaryview, GTK_SCROLL_STEP_FORWARD);
+       END_LONG_OPERATION(summaryview);
 
        if (prefs_common.immediate_exec)
                summary_execute(summaryview);
@@ -3323,23 +3488,18 @@ void summary_select_all(SummaryView *summaryview)
 {
        if (!summaryview->folder_item) return;
 
-       if (summaryview->folder_item->total_msgs >= 500) {
-               STATUSBAR_PUSH(summaryview->mainwin,
-                              _("Selecting all messages..."));
-               main_window_cursor_wait(summaryview->mainwin);
-       }
-
+       summary_lock(summaryview);
        gtk_clist_select_all(GTK_CLIST(summaryview->ctree));
-
-       if (summaryview->folder_item->total_msgs >= 500) {
-               STATUSBAR_POP(summaryview->mainwin);
-               main_window_cursor_normal(summaryview->mainwin);
-       }
+       summary_unlock(summaryview);
+       summary_status_show(summaryview);
 }
 
 void summary_unselect_all(SummaryView *summaryview)
 {
+       summary_lock(summaryview);
        gtk_sctree_unselect_all(GTK_SCTREE(summaryview->ctree));
+       summary_unlock(summaryview);
+       summary_status_show(summaryview);
 }
 
 void summary_select_thread(SummaryView *summaryview)
@@ -3400,7 +3560,7 @@ void summary_save_as(SummaryView *summaryview)
        if (is_file_exist(dest)) {
                aval = alertpanel(_("Append or Overwrite"),
                                  _("Append or overwrite existing file?"),
-                                 _("Append"), _("Overwrite"),
+                                 _("_Append"), _("_Overwrite"),
                                  GTK_STOCK_CANCEL);
                if (aval != 0 && aval != 1)
                        return;
@@ -3411,10 +3571,10 @@ void summary_save_as(SummaryView *summaryview)
 
        if ( aval==0 ) { /* append */
                if (append_file(src, dest, TRUE) < 0) 
-                       alertpanel_error(_("Can't save the file `%s'."), tmp);
+                       alertpanel_error(_("Can't save the file '%s'."), tmp);
        } else { /* overwrite */
                if (copy_file(src, dest, TRUE) < 0)
-                       alertpanel_error(_("Can't save the file `%s'."), tmp);
+                       alertpanel_error(_("Can't save the file '%s'."), tmp);
        }
        g_free(src);
        
@@ -3429,7 +3589,7 @@ void summary_save_as(SummaryView *summaryview)
                        if (!msginfo) break;
                        src = procmsg_get_message_file(msginfo);
                        if (append_file(src, dest, TRUE) < 0)
-                               alertpanel_error(_("Can't save the file `%s'."), tmp);
+                               alertpanel_error(_("Can't save the file '%s'."), tmp);
                }
                g_free(src);
        }
@@ -3437,37 +3597,78 @@ void summary_save_as(SummaryView *summaryview)
        g_free(tmp);
 }
 
+#ifdef USE_GNOMEPRINT
+static void print_mimeview(MimeView *mimeview) 
+{
+       if (!mimeview 
+       ||  !mimeview->textview
+       ||  !mimeview->textview->text)
+               alertpanel_warning(_("Cannot print: the message doesn't "
+                                    "contain text."));
+       else
+               gedit_print(GTK_TEXT_VIEW(mimeview->textview->text));
+}
+#endif
+
 void summary_print(SummaryView *summaryview)
 {
-       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
+#ifndef USE_GNOMEPRINT
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        MsgInfo *msginfo;
-       GList *cur;
-       gchar *cmdline;
+       gchar *cmdline = NULL;
        gchar *p;
+#endif
+       GList *cur;
 
        if (clist->selection == NULL) return;
-
+#ifndef USE_GNOMEPRINT
        cmdline = input_dialog(_("Print"),
                               _("Enter the print command line:\n"
-                                "(`%s' will be replaced with file name)"),
+                                "('%s' will be replaced with file name)"),
                               prefs_common.print_cmd);
        if (!cmdline) return;
        if (!(p = strchr(cmdline, '%')) || *(p + 1) != 's' ||
            strchr(p + 2, '%')) {
-               alertpanel_error(_("Print command line is invalid:\n`%s'"),
+               alertpanel_error(_("Print command line is invalid:\n'%s'"),
                                 cmdline);
                g_free(cmdline);
                return;
        }
-
-       for (cur = clist->selection; cur != NULL; cur = cur->next) {
+       for (cur = clist->selection; 
+            cur != NULL && cur->data != NULL; 
+            cur = cur->next) {
                msginfo = gtk_ctree_node_get_row_data
                        (ctree, GTK_CTREE_NODE(cur->data));
-               if (msginfo) procmsg_print_message(msginfo, cmdline);
+               if (msginfo) 
+                       procmsg_print_message(msginfo, cmdline);
        }
 
        g_free(cmdline);
+#else
+       for (cur = clist->selection; 
+            cur != NULL && cur->data != NULL; 
+            cur = cur->next) {
+               GtkCTreeNode *node = GTK_CTREE_NODE(cur->data);
+               if (node != summaryview->displayed) {
+                       MessageView *tmpview = messageview_create(
+                                               summaryview->mainwin);
+                       MsgInfo *msginfo = gtk_ctree_node_get_row_data(
+                                               GTK_CTREE(summaryview->ctree),
+                                               node);
+
+                       messageview_init(tmpview);
+                       tmpview->all_headers = summaryview->messageview->all_headers;
+                       if (msginfo && messageview_show(tmpview, msginfo, 
+                               tmpview->all_headers) >= 0) {
+                                       print_mimeview(tmpview->mimeview);
+                       }
+                       messageview_destroy(tmpview);
+               } else {
+                       print_mimeview(summaryview->messageview->mimeview);
+               }
+       }
+#endif
 }
 
 gboolean summary_execute(SummaryView *summaryview)
@@ -3476,6 +3677,7 @@ gboolean summary_execute(SummaryView *summaryview)
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
        GtkCTreeNode *node, *next;
        GtkCTreeNode *new_selected = NULL;
+       gint move_val = -1;
 
        if (!summaryview->folder_item) return FALSE;
 
@@ -3488,12 +3690,9 @@ gboolean summary_execute(SummaryView *summaryview)
                summary_unthread_for_exec(summaryview);
 
        folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       summary_execute_move(summaryview);
+       move_val = summary_execute_move(summaryview);
        summary_execute_copy(summaryview);
        summary_execute_delete(summaryview);
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
        
        node = GTK_CTREE_NODE(clist->row_list);
        for (; node != NULL; node = next) {
@@ -3511,7 +3710,7 @@ gboolean summary_execute(SummaryView *summaryview)
 
                if (!new_selected &&
                    gtkut_ctree_node_is_selected(ctree, node)) {
-                       gtk_sctree_unselect_all(GTK_SCTREE(ctree));
+                       summary_unselect_all(summaryview);
                        new_selected = summary_find_next_msg(summaryview, node);
                        if (!new_selected)
                                new_selected = summary_find_prev_msg
@@ -3521,15 +3720,23 @@ gboolean summary_execute(SummaryView *summaryview)
                gtk_ctree_remove_node(ctree, node);
        }
 
+       folder_item_update_thaw();
+       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+
        if (new_selected) {
+               summary_unlock(summaryview);
                gtk_sctree_select
                        (GTK_SCTREE(ctree),
-                        summaryview->displayed ? summaryview->displayed
-                        : new_selected);
+                        new_selected);
+               summary_lock(summaryview);
        }
 
-       if (summaryview->threaded)
+       if (summaryview->threaded) {
+               gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
                summary_thread_build(summaryview);
+               summary_thread_init(summaryview);
+               gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       }
 
        summaryview->selected = clist->selection ?
                GTK_CTREE_NODE(clist->selection->data) : NULL;
@@ -3546,29 +3753,31 @@ gboolean summary_execute(SummaryView *summaryview)
 
        gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0);
 
-       gtk_clist_thaw(clist);
-
        summary_unlock(summaryview);
+       
+       if (move_val < 0) 
+               summary_show(summaryview, summaryview->folder_item);
        return TRUE;
 }
 
-static void summary_execute_move(SummaryView *summaryview)
+static gint summary_execute_move(SummaryView *summaryview)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GSList *cur;
-
+       gint val = -1;
        /* search moving messages and execute */
        gtk_ctree_pre_recursive(ctree, NULL, summary_execute_move_func,
                                summaryview);
 
        if (summaryview->mlist) {
-               procmsg_move_messages(summaryview->mlist);
+               val = procmsg_move_messages(summaryview->mlist);
 
-               for (cur = summaryview->mlist; cur != NULL; cur = cur->next)
+               for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next)
                        procmsg_msginfo_free((MsgInfo *)cur->data);
                g_slist_free(summaryview->mlist);
                summaryview->mlist = NULL;
        }
+       return val;
 }
 
 static void summary_execute_move_func(GtkCTree *ctree, GtkCTreeNode *node,
@@ -3621,7 +3830,7 @@ static void summary_execute_copy_func(GtkCTree *ctree, GtkCTreeNode *node,
                summaryview->mlist =
                        g_slist_prepend(summaryview->mlist, msginfo);
 
-               procmsg_msginfo_unset_flags(msginfo, 0, MSG_COPY);
+               summary_msginfo_unset_flags(msginfo, 0, MSG_COPY);
                summary_set_row_marks(summaryview, node);
        }
 }
@@ -3629,24 +3838,18 @@ static void summary_execute_copy_func(GtkCTree *ctree, GtkCTreeNode *node,
 static void summary_execute_delete(SummaryView *summaryview)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-       FolderItem *trash;
        GSList *cur;
 
-       trash = summaryview->folder_item->folder->trash;
-
        /* search deleting messages and execute */
        gtk_ctree_pre_recursive
                (ctree, NULL, summary_execute_delete_func, summaryview);
 
        if (!summaryview->mlist) return;
 
-       if (trash == NULL || summaryview->folder_item == trash)
-               folder_item_remove_msgs(summaryview->folder_item,
-                                       summaryview->mlist);
-       else
-               folder_item_move_msgs(trash, summaryview->mlist);
+       folder_item_remove_msgs(summaryview->folder_item,
+                               summaryview->mlist);
 
-       for (cur = summaryview->mlist; cur != NULL; cur = cur->next)
+       for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next)
                procmsg_msginfo_free((MsgInfo *)cur->data);
 
        g_slist_free(summaryview->mlist);
@@ -3823,22 +4026,18 @@ static void summary_unthread_for_exec(SummaryView *summaryview)
        GtkCTreeNode *node;
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
 
-       summary_lock(summaryview);
-
        debug_print("Unthreading for execution...");
 
-       gtk_clist_freeze(GTK_CLIST(ctree));
+       START_LONG_OPERATION(summaryview);
 
        for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
             node != NULL; node = GTK_CTREE_NODE_NEXT(node)) {
                summary_unthread_for_exec_func(ctree, node, NULL);
        }
 
-       gtk_clist_thaw(GTK_CLIST(ctree));
+       END_LONG_OPERATION(summaryview);
 
        debug_print("done.\n");
-
-       summary_unlock(summaryview);
 }
 
 static void summary_unthread_for_exec_func(GtkCTree *ctree, GtkCTreeNode *node,
@@ -3935,7 +4134,7 @@ void summary_filter(SummaryView *summaryview, gboolean selected_only)
                GList *cur;
 
                for (cur = GTK_CLIST(summaryview->ctree)->selection;
-                    cur != NULL; cur = cur->next) {
+                    cur != NULL && cur->data != NULL; cur = cur->next) {
                        summary_filter_func(GTK_CTREE(summaryview->ctree),
                                            GTK_CTREE_NODE(cur->data),
                                            summaryview);
@@ -4086,8 +4285,8 @@ static void summary_set_row_colorlabel(SummaryView *summaryview, GtkCTreeNode *r
 
        msginfo = gtk_ctree_node_get_row_data(ctree, row);
 
-       procmsg_msginfo_unset_flags(msginfo, MSG_CLABEL_FLAG_MASK, 0);
-       procmsg_msginfo_set_flags(msginfo, MSG_COLORLABEL_TO_FLAGS(labelcolor), 0);
+       summary_msginfo_change_flags(msginfo, MSG_COLORLABEL_TO_FLAGS(labelcolor), 0, 
+                                       MSG_CLABEL_FLAG_MASK, 0);
 }
 
 void summary_set_colorlabel(SummaryView *summaryview, guint labelcolor,
@@ -4096,15 +4295,12 @@ void summary_set_colorlabel(SummaryView *summaryview, guint labelcolor,
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       main_window_cursor_wait(summaryview->mainwin);
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
                summary_set_row_colorlabel(summaryview,
                                           GTK_CTREE_NODE(cur->data), labelcolor);
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
-       main_window_cursor_normal(summaryview->mainwin);
+       END_LONG_OPERATION(summaryview);
 }
 
 static void summary_colorlabel_menu_item_activate_item_cb(GtkMenuItem *menu_item,
@@ -4133,7 +4329,7 @@ static void summary_colorlabel_menu_item_activate_item_cb(GtkMenuItem *menu_item
                          GINT_TO_POINTER(1));
 
        /* clear items. get item pointers. */
-       for (n = 0, cur = menu->children; cur != NULL; cur = cur->next) {
+       for (n = 0, cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
                if (GTK_IS_CHECK_MENU_ITEM(cur->data)) {
                        gtk_check_menu_item_set_active
                                (GTK_CHECK_MENU_ITEM(cur->data), FALSE);
@@ -4233,6 +4429,7 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
                summaryview->col_state[pos] = col_state[pos];
                type = col_state[pos].type;
                col_pos[type] = pos;
+               titles[pos] = "dummy";
        }
        col_state = summaryview->col_state;
 
@@ -4266,6 +4463,8 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
                                   prefs_common.summary_col_size[S_COL_SUBJECT]);
        gtk_clist_set_column_width(GTK_CLIST(ctree), col_pos[S_COL_FROM],
                                   prefs_common.summary_col_size[S_COL_FROM]);
+       gtk_clist_set_column_width(GTK_CLIST(ctree), col_pos[S_COL_TO],
+                                  prefs_common.summary_col_size[S_COL_TO]);
        gtk_clist_set_column_width(GTK_CLIST(ctree), col_pos[S_COL_DATE],
                                   prefs_common.summary_col_size[S_COL_DATE]);
        gtk_clist_set_column_width(GTK_CLIST(ctree), col_pos[S_COL_SIZE],
@@ -4307,6 +4506,7 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SIZE   , summary_size_clicked);
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_DATE   , summary_date_clicked);
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_FROM   , summary_from_clicked);
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TO     , summary_to_clicked);
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SUBJECT, summary_subject_clicked);
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SCORE,   summary_score_clicked);
        CLIST_BUTTON_SIGNAL_CONNECT(S_COL_LOCKED,  summary_locked_clicked);
@@ -4360,6 +4560,7 @@ void summary_set_column_order(SummaryView *summaryview)
        gtk_widget_destroy(summaryview->ctree);
 
        summaryview->ctree = ctree = summary_ctree_create(summaryview);
+       summary_set_fonts(summaryview);
        pixmap = gtk_image_new_from_pixmap(clipxpm, clipxpmmask);
        gtk_clist_set_column_widget(GTK_CLIST(ctree),
                                    summaryview->col_pos[S_COL_MIME], pixmap);
@@ -4374,6 +4575,7 @@ void summary_set_column_order(SummaryView *summaryview)
        summary_show(summaryview, item);
 
        summary_select_by_msgnum(summaryview, selected_msgnum);
+
        summaryview->displayed = summary_find_msg_by_msgnum(summaryview, displayed_msgnum);
        if (!summaryview->displayed)
                messageview_clear(summaryview->messageview);
@@ -4522,7 +4724,7 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                break;
        case GDK_Delete:
                BREAK_ON_MODIFIER_KEY();
-               summary_delete(summaryview);
+               summary_delete_trash(summaryview);
                break;
        default:
                break;
@@ -4550,11 +4752,19 @@ static void tog_searchbar_cb(GtkWidget *w, gpointer data)
        }
 }
 
+void summaryview_activate_quicksearch(SummaryView *summaryview) 
+{
+       gtk_toggle_button_set_active(
+               GTK_TOGGLE_BUTTON(summaryview->toggle_search), 
+               TRUE);
+       quicksearch_show(summaryview->quicksearch);
+}
+
 static void summary_open_row(GtkSCTree *sctree, SummaryView *summaryview)
 {
-       if (summaryview->folder_item->stype == F_OUTBOX ||
-           summaryview->folder_item->stype == F_DRAFT  ||
-           summaryview->folder_item->stype == F_QUEUE)
+       if (folder_has_parent_of_type(summaryview->folder_item, F_OUTBOX)
+       ||  folder_has_parent_of_type(summaryview->folder_item, F_DRAFT)
+       ||  folder_has_parent_of_type(summaryview->folder_item, F_QUEUE))
                summary_reedit(summaryview);
        else
                summary_open_msg(summaryview);
@@ -4566,11 +4776,13 @@ static void summary_tree_expanded(GtkCTree *ctree, GtkCTreeNode *node,
                                  SummaryView *summaryview)
 {
        summary_set_row_marks(summaryview, node);
-       while (prefs_common.bold_unread && node) {
-               GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
-               if (GTK_CTREE_ROW(node)->children)
-                       summary_set_row_marks(summaryview, node);
-               node = next;
+       if (prefs_common.bold_unread) {
+               while (node) {
+                       GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
+                       if (GTK_CTREE_ROW(node)->children)
+                               summary_set_row_marks(summaryview, node);
+                       node = next;
+               }
        }
 }
 
@@ -4586,12 +4798,13 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
        MsgInfo *msginfo;
        gboolean marked_unread = FALSE;
 
-       if (column == -1 && GTK_CLIST(ctree)->selection
-        && GTK_CLIST(ctree)->selection->next) {
-               /* multiple selection */
-               summary_status_show(summaryview);
+       if (summary_is_locked(summaryview)
+       ||  GTK_SCTREE(ctree)->selecting_range) {
+               return;
        }
 
+       summary_status_show(summaryview);
+
        if (GTK_CLIST(ctree)->selection &&
            GTK_CLIST(ctree)->selection->next) {
                summaryview->display_msg = FALSE;
@@ -4631,7 +4844,7 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
                break;
        case S_COL_LOCKED:
                if (MSG_IS_LOCKED(msginfo->flags)) {
-                       procmsg_msginfo_unset_flags(msginfo, MSG_LOCKED, 0);
+                       summary_msginfo_unset_flags(msginfo, MSG_LOCKED, 0);
                        summary_set_row_marks(summaryview, row);
                }
                else
@@ -4716,6 +4929,8 @@ static void summary_reply_cb(SummaryView *summaryview, guint action,
 static void summary_show_all_header_cb(SummaryView *summaryview,
                                       guint action, GtkWidget *widget)
 {
+       summaryview->messageview->all_headers =
+                       GTK_CHECK_MENU_ITEM(widget)->active;
        summary_display_msg_selected(summaryview,
                                     GTK_CHECK_MENU_ITEM(widget)->active);
 }
@@ -4743,9 +4958,6 @@ static void summary_sort_by_column_click(SummaryView *summaryview,
 {
        GtkCTreeNode *node = NULL;
        START_TIMING("summary_sort_by_column_click");
-       g_signal_handlers_block_by_func(G_OBJECT(summaryview->ctree),
-                                      G_CALLBACK(summary_tree_expanded), summaryview);
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
        if (summaryview->sort_key == sort_key)
                summary_sort(summaryview, sort_key,
                             summaryview->sort_type == SORT_ASCENDING
@@ -4753,17 +4965,15 @@ static void summary_sort_by_column_click(SummaryView *summaryview,
        else
                summary_sort(summaryview, sort_key, SORT_ASCENDING);
 
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
-       g_signal_handlers_unblock_by_func(G_OBJECT(summaryview->ctree),
-                                      G_CALLBACK(summary_tree_expanded), summaryview);
-
        node = GTK_CTREE_NODE(GTK_CLIST(summaryview->ctree)->row_list);
 
-       while (prefs_common.bold_unread && node) {
-               GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
-               if (GTK_CTREE_ROW(node)->children)
-                       summary_set_row_marks(summaryview, node);
-               node = next;
+       if (prefs_common.bold_unread) {
+               while (node) {
+                       GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
+                       if (GTK_CTREE_ROW(node)->children)
+                               summary_set_row_marks(summaryview, node);
+                       node = next;
+               }
        }
        END_TIMING();
 }
@@ -4803,6 +5013,11 @@ static void summary_from_clicked(GtkWidget *button, SummaryView *summaryview)
        summary_sort_by_column_click(summaryview, SORT_BY_FROM);
 }
 
+static void summary_to_clicked(GtkWidget *button, SummaryView *summaryview)
+{
+       summary_sort_by_column_click(summaryview, SORT_BY_TO);
+}
+
 static void summary_subject_clicked(GtkWidget *button,
                                    SummaryView *summaryview)
 {
@@ -4850,7 +5065,7 @@ static void summary_drag_data_get(GtkWidget        *widget,
                gchar *mail_list = NULL, *tmp1, *tmp2;
 
                for (cur = GTK_CLIST(ctree)->selection;
-                    cur != NULL; cur = cur->next) {
+                    cur != NULL && cur->data != NULL; cur = cur->next) {
                        msginfo = gtk_ctree_node_get_row_data
                                (ctree, GTK_CTREE_NODE(cur->data));
                        tmp2 = procmsg_get_message_file(msginfo);
@@ -4878,7 +5093,8 @@ static void summary_drag_data_get(GtkWidget        *widget,
                if (GTK_CLIST(summaryview->ctree)->selection)
                        gtk_selection_data_set(selection_data,
                                               selection_data->target, 8,
-                                              "Dummy", 6);
+                                              "Dummy-Summaryview", 
+                                              strlen("Dummy-Summaryview")+1);
        }
 }
 
@@ -4914,24 +5130,6 @@ CMP_FUNC_DEF(summary_cmp_by_num, msginfo1->msgnum - msginfo2->msgnum)
 CMP_FUNC_DEF(summary_cmp_by_size, msginfo1->size - msginfo2->size)
 CMP_FUNC_DEF(summary_cmp_by_date, msginfo1->date_t - msginfo2->date_t)
 
-#undef CMP_FUNC_DEF
-#define CMP_FUNC_DEF(func_name, var_name)                               \
-static gint func_name(GtkCList *clist,                                  \
-                     gconstpointer ptr1, gconstpointer ptr2)            \
-{                                                                       \
-       MsgInfo *msginfo1 = ((GtkCListRow *)ptr1)->data;                 \
-       MsgInfo *msginfo2 = ((GtkCListRow *)ptr2)->data;                 \
-                                                                        \
-       if (!msginfo1->var_name)                                         \
-               return (msginfo2->var_name != NULL);                     \
-       if (!msginfo2->var_name)                                         \
-               return -1;                                               \
-                                                                        \
-       return g_utf8_collate(msginfo1->var_name, msginfo2->var_name);   \
-}
-
-CMP_FUNC_DEF(summary_cmp_by_to, to);
-
 #undef CMP_FUNC_DEF
 
 static gint summary_cmp_by_subject(GtkCList *clist,
@@ -4972,6 +5170,28 @@ static gint summary_cmp_by_from(GtkCList *clist, gconstpointer ptr1,
        return g_utf8_collate(str1, str2);
 }
  
+static gint summary_cmp_by_to(GtkCList *clist, gconstpointer ptr1,
+                               gconstpointer ptr2)
+{
+       const gchar *str1, *str2;
+       const GtkCListRow *r1 = (const GtkCListRow *) ptr1;
+       const GtkCListRow *r2 = (const GtkCListRow *) ptr2;
+       const SummaryView *sv = g_object_get_data(G_OBJECT(clist), "summaryview");
+       
+       g_return_val_if_fail(sv, -1);
+       
+       str1 = GTK_CELL_TEXT(r1->cell[sv->col_pos[S_COL_TO]])->text;
+       str2 = GTK_CELL_TEXT(r2->cell[sv->col_pos[S_COL_TO]])->text;
+
+       if (!str1)
+               return str2 != NULL;
+       if (!str2)
+               return -1;
+       return g_utf8_collate(str1, str2);
+}
 static gint summary_cmp_by_simplified_subject
        (GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
 {
@@ -5013,7 +5233,7 @@ static gint summary_cmp_by_score(GtkCList *clist,
 
        /* if score are equal, sort by date */
 
-       diff = msginfo1->threadscore - msginfo2->threadscore;
+       diff = msginfo1->score - msginfo2->score;
        if (diff != 0)
                return diff;
        else
@@ -5035,14 +5255,14 @@ static void news_flag_crosspost(MsgInfo *msginfo)
 
        if (mff->account->mark_crosspost_read) {
                line = g_string_sized_new(128);
-               g_string_sprintf(line, "%s:%d", msginfo->folder->path, msginfo->msgnum);
+               g_string_printf(line, "%s:%d", msginfo->folder->path, msginfo->msgnum);
                debug_print("nfcp: checking <%s>", line->str);
                if (mff->newsart && 
                    g_hash_table_lookup_extended(mff->newsart, line->str, &key, &value)) {
                        debug_print(" <%s>", (gchar *)value);
                        if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
-                               procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0);
-                               procmsg_msginfo_set_flags(msginfo, mff->account->crosspost_col, 0);
+                               summary_msginfo_change_flags(msginfo, 
+                                       mff->account->crosspost_col, 0, MSG_NEW | MSG_UNREAD, 0);
                        }
                        g_hash_table_remove(mff->newsart, key);
                        g_free(key);
@@ -5059,11 +5279,7 @@ static void summary_ignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpoin
 
        msginfo = gtk_ctree_node_get_row_data(ctree, row);
 
-       if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
-               summaryview->unreadmarked--;
-
-       procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0);
-       procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0);
+       summary_msginfo_change_flags(msginfo, MSG_IGNORE_THREAD, 0, MSG_NEW | MSG_UNREAD, 0);
 
        summary_set_row_marks(summaryview, row);
        debug_print("Message %d is marked as ignore thread\n",
@@ -5075,16 +5291,14 @@ static void summary_ignore_thread(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       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_ignore_thread_func), 
                                        summaryview);
 
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
-       
+       END_LONG_OPERATION(summaryview);
+
        summary_status_show(summaryview);
 }
 
@@ -5095,10 +5309,7 @@ static void summary_unignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpo
 
        msginfo = gtk_ctree_node_get_row_data(ctree, row);
 
-       if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
-               summaryview->unreadmarked++;
-
-       procmsg_msginfo_unset_flags(msginfo, MSG_IGNORE_THREAD, 0);
+       summary_msginfo_unset_flags(msginfo, MSG_IGNORE_THREAD, 0);
 
        summary_set_row_marks(summaryview, row);
        debug_print("Message %d is marked as unignore thread\n",
@@ -5110,15 +5321,14 @@ static void summary_unignore_thread(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
 
-       folder_item_update_freeze();
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       START_LONG_OPERATION(summaryview);
+       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_unignore_thread_func), 
                                        summaryview);
 
-       folder_item_update_thaw();
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       END_LONG_OPERATION(summaryview);
+
        summary_status_show(summaryview);
 }
 
@@ -5141,7 +5351,7 @@ void summary_toggle_ignore_thread(SummaryView *summaryview)
        GList *cur;
        gint found_ignore = 0;
 
-       for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next)
+       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_ignore_thread_func),
                                        &found_ignore);
@@ -5179,12 +5389,8 @@ static gboolean processing_apply_func(GNode *node, gpointer data)
                STATUSBAR_PUSH(summaryview->mainwin, buf);
                g_free(buf);
 
-/*
-               mlist = item->folder->get_msg_list(item->folder, item,
-                                                  TRUE);
-*/             
                mlist = folder_item_get_msg_list(item);
-               for(cur = mlist ; cur != NULL ; cur = cur->next) {
+               for(cur = mlist ; cur != NULL && cur->data != NULL ; cur = cur->next) {
                        MsgInfo * msginfo;
                        
                        msginfo = (MsgInfo *) cur->data;
@@ -5205,7 +5411,7 @@ void processing_apply(SummaryView * summaryview)
 {
        GList * cur;
 
-       for (cur = folder_get_list() ; cur != NULL ; cur = g_list_next(cur)) {
+       for (cur = folder_get_list() ; cur != NULL && cur->data != NULL ; cur = g_list_next(cur)) {
                Folder *folder;
 
                folder = (Folder *) cur->data;
@@ -5217,10 +5423,15 @@ void processing_apply(SummaryView * summaryview)
 
 void summary_toggle_show_read_messages(SummaryView *summaryview)
 {
-       if (summaryview->folder_item->hide_read_msgs)
+       FolderItemUpdateData source;
+       if (summaryview->folder_item->hide_read_msgs)
                summaryview->folder_item->hide_read_msgs = 0;
        else
                summaryview->folder_item->hide_read_msgs = 1;
+
+       source.item = summaryview->folder_item;
+       source.update_flags = F_ITEM_UPDATE_NAME;
+       hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source);
        summary_show(summaryview, summaryview->folder_item);
 }
  
@@ -5288,7 +5499,7 @@ void summary_harvest_address(SummaryView *summaryview)
        MsgInfo *msginfo;
 
        msgList = NULL;
-       for( cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next ) {
+       for( cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next ) {
                msginfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(cur->data) );
                msgList = g_list_append( msgList, GUINT_TO_POINTER( msginfo->msgnum ) );
        }
@@ -5372,7 +5583,9 @@ static gboolean summary_update_msg(gpointer source, gpointer data)
        g_return_val_if_fail(summaryview != NULL, FALSE);
 
        if (msginfo_update->flags & MSGINFO_UPDATE_FLAGS) {
-               node = gtk_ctree_find_by_row_data(GTK_CTREE(summaryview->ctree), NULL, msginfo_update->msginfo);
+               node = gtk_ctree_find_by_row_data(
+                               GTK_CTREE(summaryview->ctree), NULL, 
+                               msginfo_update->msginfo);
 
                if (node) 
                        summary_set_row_marks(summaryview, node);
@@ -5433,3 +5646,18 @@ void summaryview_export_mbox_list(SummaryView *summaryview)
        g_free(mbox);
        
 }
+
+void summaryview_lock(SummaryView *summaryview, FolderItem *item)
+{
+       if (!summaryview || !summaryview->folder_item || !item) {
+               return;
+       }
+
+       if (summaryview->folder_item->folder == item->folder) {
+               gtk_widget_set_sensitive(summaryview->ctree, FALSE);
+       }
+}
+void summaryview_unlock(SummaryView *summaryview, FolderItem *item)
+{
+       gtk_widget_set_sensitive(summaryview->ctree, TRUE);
+}