2005-08-05 [paul] 1.9.13cvs14
[claws.git] / src / summaryview.c
index b61792b334dc95e89fb3fbe6ad2c6f379dc9cb91..994622c44e475fb37f10ff58fed5dc623d8e0587 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "main.h"
 #include "menu.h"
+#include "mbox.h"
 #include "mainwindow.h"
 #include "folderview.h"
 #include "summaryview.h"
@@ -84,6 +85,8 @@
 #include "folderutils.h"
 #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
@@ -402,7 +405,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>"},
@@ -462,6 +466,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;
@@ -611,40 +630,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);
@@ -670,12 +660,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);
@@ -869,13 +894,6 @@ 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) {
@@ -883,7 +901,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                
                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)
@@ -905,7 +923,7 @@ 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))
@@ -938,7 +956,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                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)) {
+               for(cur = mlist ; cur != NULL && cur->data != NULL ; cur = g_slist_next(cur)) {
                        MsgInfo * msginfo = (MsgInfo *) cur->data;
 
                        if (msginfo->score > kill_score)
@@ -951,7 +969,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        }
 #endif
         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 (!msginfo->hidden)
@@ -978,7 +996,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 */
@@ -989,33 +1009,36 @@ 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_UNREAD:
+                               node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    MSG_UNREAD, FALSE);
+                               break;
+                       case SELECTONENTRY_NEW:
+                               node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    MSG_NEW, FALSE);
+                               break;
+                       default:
+                               node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    0, FALSE);
+               }
+
                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 ||
-                   prefs_common.always_show_msg) {
-                       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);
@@ -1035,6 +1058,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
 #undef CURRENTLY_DISPLAYED
 
+
 void summary_clear_list(SummaryView *summaryview)
 {
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
@@ -1143,7 +1167,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);
@@ -1200,7 +1224,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},
@@ -1302,7 +1327,8 @@ void summary_select_next_unread(SummaryView *summaryview)
        
        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;
        }
 
@@ -1387,7 +1413,7 @@ void summary_select_next_new(SummaryView *summaryview)
                val = alertpanel(_("No more new messages"),
                                 _("No new message found. "
                                   "Go to next folder?"),
-                                GTK_STOCK_YES, _("Search again"),
+                                GTK_STOCK_YES, _("_Search again"),
                                 GTK_STOCK_NO);
                if (val == G_ALERTDEFAULT) {
                        g_signal_stop_emission_by_name(G_OBJECT(ctree),"key_press_event");
@@ -1535,11 +1561,13 @@ 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;
        }
 }
 
@@ -1832,7 +1860,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));
@@ -2001,6 +2029,16 @@ static void summary_set_column_titles(SummaryView *summaryview)
        }
 }
 
+void summary_reflect_prefs(void)
+{
+       SummaryView *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)
 {
@@ -2129,10 +2167,11 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        MsgInfo *msginfo;
-               GtkCTreeNode *node = NULL;
+       GtkCTreeNode *node = NULL;
        GHashTable *msgid_table;
        GHashTable *subject_table;
        GSList * cur;
+       START_TIMING("summary_set_ctree_from_list");
        
        if (!mlist) return;
 
@@ -2152,7 +2191,7 @@ 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) {
+       for (cur = mlist ; cur != NULL && cur->data != NULL; cur = cur->next) {
                msginfo = (MsgInfo *)cur->data;
                msginfo->threadscore = msginfo->score;
        }
@@ -2233,7 +2272,7 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
 
        g_signal_handlers_unblock_by_func(G_OBJECT(ctree),
                                       G_CALLBACK(summary_tree_expanded), summaryview);
-
+       END_TIMING();
 }
 
 static gchar *summary_complete_address(const gchar *addr)
@@ -2519,7 +2558,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)
@@ -2721,10 +2759,11 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
 void summary_set_marks_selected(SummaryView *summaryview)
 {
        GList *cur;
-
-       for (cur = GTK_CLIST(summaryview->ctree)->selection; cur != NULL;
+       summary_lock(summaryview);
+       for (cur = GTK_CLIST(summaryview->ctree)->selection; cur != NULL && cur->data != NULL;
             cur = cur->next)
                summary_set_row_marks(summaryview, GTK_CTREE_NODE(cur->data));
+       summary_unlock(summaryview);
 }
 
 static void summary_mark_row(SummaryView *summaryview, GtkCTreeNode *row)
@@ -2739,7 +2778,6 @@ 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);
@@ -2791,14 +2829,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);
 }
 
@@ -2828,14 +2865,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);
 }
 
@@ -2844,13 +2881,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);
 }
@@ -2860,13 +2895,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);
 }
@@ -2874,22 +2907,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);
 }
 
@@ -2922,13 +2954,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);
 }
@@ -3000,7 +3033,6 @@ 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);
@@ -3050,47 +3082,50 @@ 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. */
+       summary_lock(summaryview);
        folder_item_update_freeze();
        gtk_clist_freeze(GTK_CLIST(summaryview->ctree)); 
-       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) {
                sel_last = GTK_CTREE_NODE(cur->data);
                summary_delete_row(summaryview, sel_last);
        }
        folder_item_update_thaw();
        gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       summary_unlock(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) {
                summary_execute(summaryview);
@@ -3103,6 +3138,22 @@ void summary_delete(SummaryView *summaryview)
        main_window_cursor_normal(summaryview->mainwin);
 }
 
+void summary_delete_trash(SummaryView *summaryview)
+{
+       FolderItem *to_folder;
+
+       if (!summaryview->folder_item ||
+           FOLDER_TYPE(summaryview->folder_item->folder) == F_NEWS) return;
+
+       to_folder = summaryview->folder_item->folder->trash;
+       
+       if (to_folder == NULL || to_folder == summaryview->folder_item)
+               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);
@@ -3115,7 +3166,6 @@ 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);
@@ -3130,15 +3180,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);
 }
 
@@ -3151,6 +3199,9 @@ static void summary_move_row_to(SummaryView *summaryview, GtkCTreeNode *row,
        g_return_if_fail(to_folder != NULL);
 
        msginfo = gtk_ctree_node_get_row_data(ctree, row);
+       if (MSG_IS_LOCKED(msginfo->flags))
+               return;
+
        procmsg_msginfo_set_to_folder(msginfo, to_folder);
        if (MSG_IS_DELETED(msginfo->flags))
                summaryview->deleted--;
@@ -3185,22 +3236,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));
+       END_LONG_OPERATION(summaryview);
 
-       summary_step(summaryview, GTK_SCROLL_STEP_FORWARD);
-
-       if (prefs_common.immediate_exec)
+       if (prefs_common.immediate_exec) {
                summary_execute(summaryview);
-       else {
+       else {
                summary_status_show(summaryview);
        }
        
@@ -3208,7 +3255,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);
        }
 
 }
@@ -3268,18 +3315,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);
@@ -3318,23 +3361,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)
@@ -3406,10 +3444,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);
        
@@ -3424,7 +3462,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);
        }
@@ -3434,35 +3472,63 @@ void summary_save_as(SummaryView *summaryview)
 
 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;
+#else
+       gboolean first = TRUE;
+       GList *tmplist;
+#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);
        }
 
        g_free(cmdline);
+       
+#else
+       tmplist = g_list_copy(clist->selection);
+       summary_unselect_all(summaryview);
+       for (cur = tmplist; cur != NULL && cur->data != NULL; cur = cur->next) {
+               GtkCTreeNode *node = GTK_CTREE_NODE(cur->data);
+               summary_select_node(summaryview, node, TRUE, TRUE);
+               if (!summaryview->messageview->mimeview 
+               ||  !summaryview->messageview->mimeview->textview
+               ||  !summaryview->messageview->mimeview->textview->text)
+                       alertpanel_warning(_("Cannot print: the message doesn't "
+                                            "contain text."));
+               gedit_print(
+                       GTK_TEXT_VIEW(summaryview->messageview->mimeview
+                                       ->textview->text));
+       }
+       for (cur = tmplist; cur != NULL && cur->data != NULL; cur = cur->next) {
+               GtkCTreeNode *node = GTK_CTREE_NODE(cur->data);
+               gtk_sctree_select_with_state(
+                       GTK_SCTREE(clist), node, first ? 0:GDK_CONTROL_MASK);
+               first = FALSE;
+       }
+       g_list_free(tmplist);
+#endif
 }
 
 gboolean summary_execute(SummaryView *summaryview)
@@ -3483,12 +3549,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);
        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) {
@@ -3506,7 +3569,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
@@ -3516,15 +3579,24 @@ 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);
+               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;
@@ -3541,8 +3613,6 @@ gboolean summary_execute(SummaryView *summaryview)
 
        gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0);
 
-       gtk_clist_thaw(clist);
-
        summary_unlock(summaryview);
        return TRUE;
 }
@@ -3559,7 +3629,7 @@ static void summary_execute_move(SummaryView *summaryview)
        if (summaryview->mlist) {
                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;
@@ -3624,24 +3694,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);
@@ -3930,7 +3994,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);
@@ -4091,15 +4155,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,
@@ -4128,7 +4189,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);
@@ -4369,6 +4430,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);
@@ -4517,7 +4579,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;
@@ -4581,12 +4643,12 @@ 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)) {
+               return;
        }
 
+       summary_status_show(summaryview);
+
        if (GTK_CLIST(ctree)->selection &&
            GTK_CLIST(ctree)->selection->next) {
                summaryview->display_msg = FALSE;
@@ -4711,6 +4773,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);
 }
@@ -4736,12 +4800,31 @@ static void summary_create_processing_cb(SummaryView *summaryview,
 static void summary_sort_by_column_click(SummaryView *summaryview,
                                         FolderSortKey sort_key)
 {
+       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
                             ? SORT_DESCENDING : SORT_ASCENDING);
        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;
+       }
+       END_TIMING();
 }
 
 static void summary_mark_clicked(GtkWidget *button, SummaryView *summaryview)
@@ -4826,7 +4909,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);
@@ -5051,16 +5134,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);
 }
 
@@ -5086,15 +5167,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);
 }
 
@@ -5117,7 +5197,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);
@@ -5155,12 +5235,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;
@@ -5181,7 +5257,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;
@@ -5264,7 +5340,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 ) );
        }
@@ -5409,3 +5485,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);
+}