2007-08-19 [paul] 2.10.0cvs132
[claws.git] / src / summaryview.c
index 7db4bd6e0802fbac341651d391eabb12ac2185dd..53affb1cb56343a0deb78856d393959526bce7f8 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2006 Hiroyuki Yamamoto and the Sylpheed-Claws team
+ * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -13,8 +13,8 @@
  * GNU General Public License for more details.
  *
  * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 
  */
 
 #include "defs.h"
@@ -59,6 +59,7 @@
 #include "sourcewindow.h"
 #include "prefs_common.h"
 #include "prefs_summary_column.h"
+#include "prefs_summary_open.h"
 #include "prefs_filtering.h"
 #include "account.h"
 #include "compose.h"
 #include "folderutils.h"
 #include "quicksearch.h"
 #include "partial_download.h"
+#include "tags.h"
 #include "timing.h"
 #include "gedit-print.h"
 #include "log.h"
+#include "edittags.h"
 #include "manual.h"
 
 #define SUMMARY_COL_MARK_WIDTH         10
@@ -122,6 +125,8 @@ static GdkPixmap *forwardedxpm;
 static GdkBitmap *forwardedxpmmask;
 static GdkPixmap *ignorethreadxpm;
 static GdkBitmap *ignorethreadxpmmask;
+static GdkPixmap *watchthreadxpm;
+static GdkBitmap *watchthreadxpmmask;
 static GdkPixmap *lockedxpm;
 static GdkBitmap *lockedxpmmask;
 static GdkPixmap *spamxpm;
@@ -182,7 +187,7 @@ static void summary_status_show             (SummaryView            *summaryview);
 static void summary_set_column_titles  (SummaryView            *summaryview);
 static void summary_set_ctree_from_list        (SummaryView            *summaryview,
                                         GSList                 *mlist);
-static void summary_set_header         (SummaryView            *summaryview,
+static inline void summary_set_header  (SummaryView            *summaryview,
                                         gchar                  *text[],
                                         MsgInfo                *msginfo);
 static void summary_display_msg                (SummaryView            *summaryview,
@@ -194,6 +199,11 @@ static void summary_display_msg_full       (SummaryView            *summaryview,
 static void summary_set_row_marks      (SummaryView            *summaryview,
                                         GtkCTreeNode           *row);
 
+static gboolean summary_set_row_tag    (SummaryView            *summaryview, 
+                                        GtkCTreeNode           *row, 
+                                        gboolean                refresh,
+                                        gboolean                set, 
+                                        gint                    id);
 /* message handling */
 static void summary_mark_row           (SummaryView            *summaryview,
                                         GtkCTreeNode           *row);
@@ -249,6 +259,14 @@ static void summary_colorlabel_menu_item_activate_item_cb
                                           gpointer      data);
 static void summary_colorlabel_menu_create(SummaryView *summaryview,
                                           gboolean  refresh);
+static void summary_tags_menu_item_activate_cb
+                                         (GtkWidget    *widget,
+                                          gpointer      data);
+static void summary_tags_menu_item_activate_item_cb
+                                         (GtkMenuItem  *label_menu_item,
+                                          gpointer      data);
+static void summary_tags_menu_create(SummaryView       *summaryview,
+                                          gboolean  refresh);
 
 static GtkWidget *summary_ctree_create (SummaryView    *summaryview);
 
@@ -256,6 +274,15 @@ static GtkWidget *summary_ctree_create     (SummaryView    *summaryview);
 static gint summary_toggle_pressed     (GtkWidget              *eventbox,
                                         GdkEventButton         *event,
                                         SummaryView            *summaryview);
+#ifdef MAEMO
+static void summary_toggle_multiple_pressed
+                                       (GtkWidget              *widget,
+                                        SummaryView            *summaryview);
+#endif
+static gint summary_folder_eventbox_pressed    
+                                       (GtkWidget              *eventbox,
+                                        GdkEventButton         *event,
+                                        SummaryView            *summaryview);
 static gboolean summary_button_pressed (GtkWidget              *ctree,
                                         GdkEventButton         *event,
                                         SummaryView            *summaryview);
@@ -265,8 +292,6 @@ static gboolean summary_button_released     (GtkWidget              *ctree,
 static gboolean summary_key_pressed    (GtkWidget              *ctree,
                                         GdkEventKey            *event,
                                         SummaryView            *summaryview);
-static void summary_open_row           (GtkSCTree              *sctree,
-                                        SummaryView            *summaryview);
 static void summary_tree_expanded      (GtkCTree               *ctree,
                                         GtkCTreeNode           *node,
                                         SummaryView            *summaryview);
@@ -326,6 +351,8 @@ static void summary_score_clicked   (GtkWidget              *button,
                                         SummaryView            *summaryview);
 static void summary_locked_clicked     (GtkWidget              *button,
                                         SummaryView            *summaryview);
+static void summary_tags_clicked       (GtkWidget              *button,
+                                        SummaryView            *summaryview);
 
 static void summary_start_drag         (GtkWidget        *widget, 
                                         int button,
@@ -351,7 +378,9 @@ static gboolean summary_drag_motion_cb(GtkWidget      *widget,
                                          gint            y,
                                          guint           time,
                                          SummaryView    *summaryview);
-
+static void summary_drag_end(GtkWidget *widget,
+                                         GdkDragContext *drag_context,
+                                         SummaryView    *summaryview);
 /* custom compare functions for sorting */
 
 static gint summary_cmp_by_mark                (GtkCList               *clist,
@@ -372,6 +401,9 @@ static gint summary_cmp_by_size             (GtkCList               *clist,
 static gint summary_cmp_by_date                (GtkCList               *clist,
                                         gconstpointer           ptr1,
                                         gconstpointer           ptr2);
+static gint summary_cmp_by_thread_date (GtkCList               *clist,
+                                        gconstpointer           ptr1,
+                                        gconstpointer           ptr2);
 static gint summary_cmp_by_from                (GtkCList               *clist,
                                         gconstpointer           ptr1,
                                         gconstpointer           ptr2);
@@ -394,6 +426,9 @@ static gint summary_cmp_by_subject  (GtkCList               *clist,
 static gint summary_cmp_by_locked      (GtkCList               *clist,
                                         gconstpointer           ptr1, 
                                         gconstpointer           ptr2);
+static gint summary_cmp_by_tags                (GtkCList               *clist,
+                                        gconstpointer           ptr1, 
+                                        gconstpointer           ptr2);
 
 static void quicksearch_execute_cb     (QuickSearch    *quicksearch,
                                         gpointer        data);
@@ -404,32 +439,39 @@ static void summary_find_answers  (SummaryView    *summaryview,
                                         MsgInfo        *msg);
 
 static gboolean summary_update_msg     (gpointer source, gpointer data);
-static gboolean summary_update_folder_item_name(gpointer source, gpointer data);
+static gboolean summary_update_folder_item_hook(gpointer source, gpointer data);
+static gboolean summary_update_folder_hook(gpointer source, gpointer data);
 
 GtkTargetEntry summary_drag_types[2] =
 {
        {"text/uri-list", 0, TARGET_MAIL_URI_LIST},
-       {"sylpheed-claws/internal", GTK_TARGET_SAME_APP, TARGET_DUMMY}
+       {"claws-mail/internal", GTK_TARGET_SAME_APP, TARGET_DUMMY}
 };
 
 static GtkItemFactoryEntry summary_popup_entries[] =
 {
        {N_("/_Reply"),                 "<control>R", summary_reply_cb, COMPOSE_REPLY, NULL},
+#ifndef MAEMO
        {N_("/Repl_y to"),              NULL, NULL,             0, "<Branch>"},
        {N_("/Repl_y to/_all"),         "<shift><control>R", summary_reply_cb,  COMPOSE_REPLY_TO_ALL, NULL},
        {N_("/Repl_y to/_sender"),      NULL, summary_reply_cb, COMPOSE_REPLY_TO_SENDER, NULL},
        {N_("/Repl_y to/mailing _list"),
                                        "<control>L", summary_reply_cb, COMPOSE_REPLY_TO_LIST, NULL},
-       {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
+       {"/---",                        NULL, NULL,             0, "<Separator>"},
+#endif
        {N_("/_Forward"),               "<control><alt>F", summary_reply_cb, COMPOSE_FORWARD_INLINE, NULL},
+#ifndef MAEMO
        {N_("/For_ward as attachment"), NULL, summary_reply_cb, COMPOSE_FORWARD_AS_ATTACH, NULL},
        {N_("/Redirect"),               NULL, summary_reply_cb, COMPOSE_REDIRECT, NULL},
-       {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
+#endif
+       {"/---",                        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_("/Move to _trash"),         "<control>D", summary_delete_trash,     0, NULL},
+#ifndef MAEMO
        {N_("/_Delete..."),             NULL, summary_delete, 0, NULL},
-       {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
+#endif
+       {"/---",                        NULL, NULL,             0, "<Separator>"},
        {N_("/_Mark"),                  NULL, NULL,             0, "<Branch>"},
        {N_("/_Mark/_Mark"),            NULL, summary_mark,     0, NULL},
        {N_("/_Mark/_Unmark"),          NULL, summary_unmark,   0, NULL},
@@ -439,6 +481,8 @@ static GtkItemFactoryEntry summary_popup_entries[] =
        {N_("/_Mark/Mark all read"),    NULL, summary_mark_all_read, 0, NULL},
        {N_("/_Mark/Ignore thread"),    NULL, summary_ignore_thread, 0, NULL},
        {N_("/_Mark/Unignore thread"),  NULL, summary_unignore_thread, 0, NULL},
+       {N_("/_Mark/Watch thread"),     NULL, summary_watch_thread, 0, NULL},
+       {N_("/_Mark/Unwatch thread"),   NULL, summary_unwatch_thread, 0, NULL},
        {N_("/_Mark/---"),              NULL, NULL, 0, "<Separator>"},
        {N_("/_Mark/Mark as _spam"),    NULL, summary_mark_as_spam, 1, NULL},
        {N_("/_Mark/Mark as _ham"),     NULL, summary_mark_as_spam, 0, NULL},
@@ -446,10 +490,13 @@ static GtkItemFactoryEntry summary_popup_entries[] =
        {N_("/_Mark/Lock"),             NULL, summary_msgs_lock, 0, NULL},
        {N_("/_Mark/Unlock"),           NULL, summary_msgs_unlock, 0, NULL},
        {N_("/Color la_bel"),           NULL, NULL,             0, NULL},
+       {N_("/Ta_gs"),                  NULL, NULL,             0, NULL},
 
-       {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
+       {"/---",                        NULL, NULL,             0, "<Separator>"},
+#ifndef MAEMO
        {N_("/Add sender to address boo_k"),
                                        NULL, summary_add_address_cb, 0, NULL},
+#endif
        {N_("/Create f_ilter rule"),    NULL, NULL,             0, "<Branch>"},
        {N_("/Create f_ilter rule/_Automatically"),
                                        NULL, summary_create_filter_cb, FILTER_BY_AUTO, NULL},
@@ -459,6 +506,7 @@ static GtkItemFactoryEntry summary_popup_entries[] =
                                        NULL, summary_create_filter_cb, FILTER_BY_TO, NULL},
        {N_("/Create f_ilter rule/by _Subject"),
                                        NULL, summary_create_filter_cb, FILTER_BY_SUBJECT, NULL},
+#ifndef MAEMO
        {N_("/Create processing rule"), NULL, NULL,             0, "<Branch>"},
        {N_("/Create processing rule/_Automatically"),
                                        NULL, summary_create_processing_cb, FILTER_BY_AUTO, NULL},
@@ -468,15 +516,20 @@ static GtkItemFactoryEntry summary_popup_entries[] =
                                        NULL, summary_create_processing_cb, FILTER_BY_TO, NULL},
        {N_("/Create processing rule/by _Subject"),
                                        NULL, summary_create_processing_cb, FILTER_BY_SUBJECT, NULL},
-       {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
+#endif
+       {"/---",                        NULL, NULL,             0, "<Separator>"},
        {N_("/_View"),                  NULL, NULL,             0, "<Branch>"},
        {N_("/_View/Open in new _window"),
                                        "<control><alt>N", summary_open_msg,    0, NULL},
        {N_("/_View/Message _source"),  "<control>U", summary_view_source, 0, NULL},
+#ifndef MAEMO
        {N_("/_View/All _headers"),     "<control>H", summary_show_all_header_cb, 0, "<ToggleItem>"},
-       {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
+#endif
+       {"/---",                        NULL, NULL,             0, "<Separator>"},
        {N_("/_Save as..."),            "<control>S", summary_save_as,   0, NULL},
+#ifndef MAEMO
        {N_("/_Print..."),              "<control>P", summary_print,   0, NULL},
+#endif
 };  /* see also list in menu_connect_identical_items() in menu.c if this changes */
 
 static const gchar *const col_label[N_SUMMARY_COLS] = {
@@ -491,14 +544,41 @@ static const gchar *const col_label[N_SUMMARY_COLS] = {
        N_("#"),        /* S_COL_NUMBER  */
        N_("Score"),    /* S_COL_SCORE   */
        "",             /* S_COL_LOCKED  */
+       N_("Tags"),     /* S_COL_TAGS    */
 };
 
+void summary_freeze(SummaryView *summaryview)
+{
+       if (summaryview)
+               gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
+}
+
+void summary_thaw(SummaryView *summaryview)
+{
+       if (summaryview)
+               gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+}
+
+void summary_grab_focus(SummaryView *summaryview)
+{
+       if (summaryview)
+               gtk_widget_grab_focus(summaryview->ctree);
+}
+
+GtkWidget *summary_get_main_widget(SummaryView *summaryview)
+{
+       if (summaryview)
+               return summaryview->ctree;
+       else
+               return NULL;
+}
+
 #define START_LONG_OPERATION(summaryview,force_freeze) {       \
        summary_lock(summaryview);                              \
        main_window_cursor_wait(summaryview->mainwin);          \
        if (force_freeze || sc_g_list_bigger(GTK_CLIST(summaryview->ctree)->selection, 1)) {\
                froze = TRUE;                                           \
-               gtk_clist_freeze(GTK_CLIST(summaryview->ctree));        \
+               summary_freeze(summaryview);    \
        }                                                       \
        folder_item_update_freeze();                            \
        inc_lock();                                             \
@@ -509,7 +589,7 @@ static const gchar *const col_label[N_SUMMARY_COLS] = {
        inc_unlock();                                           \
        folder_item_update_thaw();                              \
        if (froze)                                              \
-               gtk_clist_thaw(GTK_CLIST(summaryview->ctree));  \
+               summary_thaw(summaryview);      \
        main_window_cursor_normal(summaryview->mainwin);        \
        summary_unlock(summaryview);                            \
        summaryview->msginfo_update_callback_id =               \
@@ -525,15 +605,20 @@ SummaryView *summary_create(void)
        GtkWidget *ctree;
        GtkWidget *hbox;
        GtkWidget *hbox_l;
+       GtkWidget *stat_box;
+       GtkWidget *stat_box2;
+       GtkWidget *stat_vbox;
        GtkWidget *statlabel_folder;
        GtkWidget *statlabel_select;
        GtkWidget *statlabel_msgs;
        GtkWidget *hbox_spc;
        GtkWidget *toggle_eventbox;
+#ifdef MAEMO
+       GtkWidget *multiple_sel_togbtn;
+#endif
        GtkWidget *toggle_arrow;
        GtkWidget *popupmenu;
        GtkWidget *toggle_search;
-       GtkTooltips *search_tip;
        GtkItemFactory *popupfactory;
        gint n_entries;
        QuickSearch *quicksearch;
@@ -541,6 +626,7 @@ SummaryView *summary_create(void)
        debug_print("Creating summary view...\n");
        summaryview = g_new0(SummaryView, 1);
 
+       summaryview->tips = gtk_tooltips_new();
 #define SUMMARY_VBOX_SPACING 3
        vbox = gtk_vbox_new(FALSE, SUMMARY_VBOX_SPACING);
        
@@ -548,21 +634,33 @@ SummaryView *summary_create(void)
        hbox = gtk_hbox_new(FALSE, 0);
        gtk_widget_show(hbox);
 
-       search_tip = gtk_tooltips_new();
+       stat_vbox = gtk_vbox_new(FALSE, 0);
+       gtk_widget_show(stat_vbox);
+
+       stat_box = gtk_hbox_new(FALSE, 0);
+       gtk_widget_show(stat_box);
+       
+       stat_box2 = gtk_hbox_new(FALSE, 0);
+       gtk_widget_show(stat_box2);
+       
        toggle_search = gtk_toggle_button_new();
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle_search),
                                     prefs_common.show_searchbar);
        gtk_widget_show(toggle_search);
 
-       gtk_tooltips_set_tip(GTK_TOOLTIPS(search_tip),
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(summaryview->tips),
                             toggle_search,
                             _("Toggle quick search bar"), NULL);
        
        gtk_box_pack_start(GTK_BOX(hbox), toggle_search, FALSE, FALSE, 2);      
 
+       gtk_box_pack_start(GTK_BOX(hbox), stat_vbox, TRUE, TRUE, 0);    
+       gtk_box_pack_start(GTK_BOX(stat_vbox), stat_box, TRUE, TRUE, 0);        
+       gtk_box_pack_start(GTK_BOX(stat_vbox), stat_box2, TRUE, TRUE, 0);       
+
        hbox_l = gtk_hbox_new(FALSE, 0);
        gtk_widget_show(hbox_l);
-       gtk_box_pack_start(GTK_BOX(hbox), hbox_l, TRUE, TRUE, 0);
+       gtk_box_pack_start(GTK_BOX(stat_box), hbox_l, TRUE, TRUE, 0);
  
        statlabel_folder = gtk_label_new("");
        gtk_widget_show(statlabel_folder);
@@ -574,18 +672,31 @@ SummaryView *summary_create(void)
        /* toggle view button */
        toggle_eventbox = gtk_event_box_new();
        gtk_widget_show(toggle_eventbox);
+       
        gtk_box_pack_end(GTK_BOX(hbox), toggle_eventbox, FALSE, FALSE, 4);
+
        toggle_arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
        gtk_widget_show(toggle_arrow);
        gtk_container_add(GTK_CONTAINER(toggle_eventbox), toggle_arrow);
        g_signal_connect(G_OBJECT(toggle_eventbox), "button_press_event",
                         G_CALLBACK(summary_toggle_pressed),
                         summaryview);
-       
+
+#ifdef MAEMO
+       multiple_sel_togbtn = gtk_toggle_button_new();
+       gtk_widget_show(multiple_sel_togbtn);
+       gtk_box_pack_end(GTK_BOX(hbox), multiple_sel_togbtn, FALSE, FALSE, 4);
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(summaryview->tips),
+                            multiple_sel_togbtn,
+                            _("Toggle multiple selection"), NULL);
+       g_signal_connect(G_OBJECT(multiple_sel_togbtn), "toggled",
+                        G_CALLBACK(summary_toggle_multiple_pressed),
+                        summaryview);
+#endif
        
        statlabel_msgs = gtk_label_new("");
        gtk_widget_show(statlabel_msgs);
-       gtk_box_pack_end(GTK_BOX(hbox), statlabel_msgs, FALSE, FALSE, 4);
+       gtk_box_pack_end(GTK_BOX(stat_box), statlabel_msgs, FALSE, FALSE, 4);
 
        hbox_spc = gtk_hbox_new(FALSE, 0);
        gtk_widget_show(hbox_spc);
@@ -596,7 +707,9 @@ SummaryView *summary_create(void)
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
                                       GTK_POLICY_AUTOMATIC,
                                       GTK_POLICY_AUTOMATIC);
+#ifndef MAEMO
        gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
+#endif
        gtk_widget_set_size_request(vbox,
                             prefs_common.summaryview_width,
                             prefs_common.summaryview_height);
@@ -611,12 +724,16 @@ SummaryView *summary_create(void)
        gtk_container_add(GTK_CONTAINER(scrolledwin), ctree);
 
        /* status label */
+       gtk_widget_show_all(stat_vbox);
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
 
        /* quick search */
        quicksearch = quicksearch_new();
        gtk_box_pack_start(GTK_BOX(vbox), quicksearch_get_widget(quicksearch), FALSE, FALSE, 0);
 
+#ifdef MAEMO
+       gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
+#endif
        quicksearch_set_execute_callback(quicksearch, quicksearch_execute_cb, summaryview);
 
        g_signal_connect (G_OBJECT(toggle_search), "toggled",
@@ -634,11 +751,17 @@ SummaryView *summary_create(void)
        summaryview->ctree = ctree;
        summaryview->hbox = hbox;
        summaryview->hbox_l = hbox_l;
+       summaryview->hbox_spc = hbox_spc;
+       summaryview->stat_box = stat_box;
+       summaryview->stat_box2 = stat_box2;
        summaryview->statlabel_folder = statlabel_folder;
        summaryview->statlabel_select = statlabel_select;
        summaryview->statlabel_msgs = statlabel_msgs;
        summaryview->toggle_eventbox = toggle_eventbox;
        summaryview->toggle_arrow = toggle_arrow;
+#ifdef MAEMO
+       summaryview->multiple_sel_togbtn = multiple_sel_togbtn;
+#endif
        summaryview->toggle_search = toggle_search;
        summaryview->popupmenu = popupmenu;
        summaryview->popupfactory = popupfactory;
@@ -647,7 +770,11 @@ SummaryView *summary_create(void)
                hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, summary_update_msg, (gpointer) summaryview);
        summaryview->folder_item_update_callback_id =
                hooks_register_hook(FOLDER_ITEM_UPDATE_HOOKLIST,
-                               summary_update_folder_item_name,
+                               summary_update_folder_item_hook,
+                               (gpointer) summaryview);
+       summaryview->folder_update_callback_id =
+               hooks_register_hook(FOLDER_UPDATE_HOOKLIST,
+                               summary_update_folder_hook,
                                (gpointer) summaryview);
 
        summaryview->target_list = gtk_target_list_new(summary_drag_types, 2);
@@ -667,9 +794,62 @@ SummaryView *summary_create(void)
        else
                quicksearch_hide(quicksearch);
        
+       if (prefs_common.layout_mode == WIDE_MSGLIST_LAYOUT ||
+           prefs_common.layout_mode == SMALL_LAYOUT)
+               gtk_widget_hide(summaryview->toggle_eventbox);
+
        return summaryview;
 }
 
+void summary_relayout(SummaryView *summaryview)
+{
+       gtk_widget_realize(summaryview->stat_box);
+
+       gtk_widget_ref(summaryview->hbox_l);
+       gtk_widget_ref(summaryview->statlabel_msgs);
+       
+       gtkut_container_remove(GTK_CONTAINER(summaryview->hbox_l->parent), summaryview->hbox_l);
+       gtkut_container_remove(GTK_CONTAINER(summaryview->statlabel_msgs->parent), summaryview->statlabel_msgs);
+
+       switch (prefs_common.layout_mode) {
+       case NORMAL_LAYOUT:
+       case WIDE_LAYOUT:
+       case WIDE_MSGLIST_LAYOUT:
+               gtk_box_pack_start(GTK_BOX(summaryview->stat_box), summaryview->hbox_l, TRUE, TRUE, 0);
+               gtk_box_pack_end(GTK_BOX(summaryview->stat_box), summaryview->statlabel_msgs, FALSE, FALSE, 4);
+               gtk_widget_show_all(summaryview->stat_box);
+               gtk_widget_show_all(summaryview->stat_box2);
+               if (prefs_common.layout_mode == WIDE_MSGLIST_LAYOUT ||
+                   prefs_common.layout_mode == SMALL_LAYOUT)
+                       gtk_widget_hide(summaryview->toggle_eventbox);
+               else
+                       gtk_widget_show(summaryview->toggle_eventbox);
+               break;
+       case VERTICAL_LAYOUT:
+       case SMALL_LAYOUT:
+               gtk_box_pack_start(GTK_BOX(summaryview->stat_box), summaryview->hbox_l, TRUE, TRUE, 0);
+               gtk_box_pack_start(GTK_BOX(summaryview->stat_box2), summaryview->statlabel_msgs, FALSE, FALSE, 4);
+               gtk_widget_show_all(summaryview->stat_box);
+               gtk_widget_show_all(summaryview->stat_box2);
+               if (prefs_common.layout_mode == SMALL_LAYOUT) {
+                       gtk_widget_hide(summaryview->toggle_eventbox);
+                       gtk_widget_hide(summaryview->statlabel_msgs);
+               } else {
+                       gtk_widget_show(summaryview->toggle_eventbox);
+                       gtk_widget_show(summaryview->statlabel_msgs);
+               }
+                       
+               break;
+       }
+       gtk_widget_unref(summaryview->hbox_l);
+       gtk_widget_unref(summaryview->statlabel_msgs);
+       quicksearch_relayout(summaryview->quicksearch);
+       if (prefs_common.show_searchbar)
+               quicksearch_show(summaryview->quicksearch);
+       else
+               quicksearch_hide(summaryview->quicksearch);
+}
+
 static void summary_set_fonts(SummaryView *summaryview)
 {
        PangoFontDescription *font_desc;
@@ -705,9 +885,31 @@ static void summary_set_fonts(SummaryView *summaryview)
        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);
+       /* ici */
        pango_font_description_free(font_desc);
 }
 
+static void summary_set_folder_pixmap(SummaryView *summaryview, StockPixmap icon)
+{
+       GtkWidget *pixmap; 
+       if (!summaryview->folder_pixmap_eventbox) {
+               summaryview->folder_pixmap_eventbox = gtk_event_box_new();
+               gtk_widget_show(summaryview->folder_pixmap_eventbox);
+               gtk_box_pack_start(GTK_BOX(summaryview->hbox_l), summaryview->folder_pixmap_eventbox, FALSE, FALSE, 4);
+               gtk_box_reorder_child(GTK_BOX(summaryview->hbox_l), summaryview->folder_pixmap_eventbox, 0); /* search_toggle before */
+               g_signal_connect(G_OBJECT(summaryview->folder_pixmap_eventbox), "button_press_event",
+                        G_CALLBACK(summary_folder_eventbox_pressed),
+                        summaryview);
+       }
+       if (summaryview->folder_pixmap)
+               gtk_widget_destroy(summaryview->folder_pixmap);
+
+       pixmap = stock_pixmap_widget(summaryview->hbox_l, icon);
+       gtk_container_add(GTK_CONTAINER(summaryview->folder_pixmap_eventbox), pixmap);
+       gtk_widget_show(pixmap);
+       summaryview->folder_pixmap = pixmap; 
+}
+
 void summary_init(SummaryView *summaryview)
 {
        GtkWidget *pixmap;
@@ -731,6 +933,8 @@ void summary_init(SummaryView *summaryview)
                         &lockedxpm, &lockedxpmmask);
        stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_IGNORETHREAD,
                         &ignorethreadxpm, &ignorethreadxpmmask);
+       stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_WATCHTHREAD,
+                        &watchthreadxpm, &watchthreadxpmmask);
        stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_CLIP_KEY,
                         &clipkeyxpm, &clipkeyxpmmask);
        stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_KEY,
@@ -748,16 +952,19 @@ void summary_init(SummaryView *summaryview)
 
        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);
-       gtk_box_reorder_child(GTK_BOX(summaryview->hbox_l), pixmap, 0);
-       gtk_widget_show(pixmap);
-       summaryview->folder_pixmap = pixmap;
+       summary_set_folder_pixmap(summaryview, STOCK_PIXMAP_DIR_OPEN);
 
        pixmap = stock_pixmap_widget(summaryview->hbox, STOCK_PIXMAP_QUICKSEARCH);
        gtk_container_add (GTK_CONTAINER(summaryview->toggle_search), pixmap);
        gtk_widget_show(pixmap);
        summaryview->quick_search_pixmap = pixmap;
+       
+#ifdef MAEMO
+       pixmap = stock_pixmap_widget(summaryview->hbox, STOCK_PIXMAP_SELECTION);
+       gtk_container_add(GTK_CONTAINER(summaryview->multiple_sel_togbtn), pixmap);
+       gtk_widget_show(pixmap);
+       summaryview->multiple_sel_image = pixmap;
+#endif
 
        /* Init summaryview prefs */
        summaryview->sort_key = SORT_BY_NONE;
@@ -769,6 +976,7 @@ void summary_init(SummaryView *summaryview)
        summary_clear_list(summaryview);
        summary_set_column_titles(summaryview);
        summary_colorlabel_menu_create(summaryview, FALSE);
+       summary_tags_menu_create(summaryview, FALSE);
        main_create_mailing_list_menu (summaryview->mainwin, NULL);     
        summary_set_menu_sensitive(summaryview);
 
@@ -793,7 +1001,7 @@ static void summary_switch_from_to(SummaryView *summaryview, FolderItem *item)
        
        if (!item)
                return;
-       if(FOLDER_SHOWS_TO_HDR(item))
+       if (FOLDER_SHOWS_TO_HDR(item))
                show_to = TRUE;
        else
                show_from = TRUE;
@@ -886,7 +1094,7 @@ static gboolean summary_check_consistency(FolderItem *item, GSList *mlist)
 gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-       GtkCTreeNode *node;
+       GtkCTreeNode *node = NULL;
        GSList *mlist = NULL;
        gchar *buf;
        gboolean is_refresh;
@@ -909,9 +1117,15 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
        is_refresh = (item == summaryview->folder_item) ? TRUE : FALSE;
 
-       if (!is_refresh)
+       if (!is_refresh) {
                main_create_mailing_list_menu (summaryview->mainwin, NULL);
-
+               if (prefs_common.layout_mode == SMALL_LAYOUT) {
+                       if (item) {
+                               mainwindow_enter_folder(summaryview->mainwin);
+                               gtk_widget_grab_focus(summaryview->ctree);
+                       }
+               }
+       }
        if (!prefs_common.summary_quicksearch_sticky
         && !prefs_common.summary_quicksearch_recurse
         && !quicksearch_is_running(summaryview->quicksearch)
@@ -954,7 +1168,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                        folder_update_op_count();
        }
        
-       gtk_clist_freeze(GTK_CLIST(ctree));
+       summary_freeze(summaryview);
 
        summary_clear_list(summaryview);
 
@@ -963,13 +1177,13 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                g_free(buf);
                debug_print("empty folder (%p %s %p %d)\n\n",
                                item, 
-                               item?item->path:"NULL",
+                               (item && item->path)?item->path:"(null)",
                                item?folder_item_parent(item):0x0,
                                item?item->no_select:FALSE);
                summary_set_hide_read_msgs_menu(summaryview, FALSE);
                summary_clear_all(summaryview);
                summaryview->folder_item = item;
-               gtk_clist_thaw(GTK_CLIST(ctree));
+               summary_thaw(summaryview);
                summary_unlock(summaryview);
                inc_unlock();
                if (item && quicksearch_is_running(summaryview->quicksearch)) {
@@ -1041,33 +1255,37 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
        if (quicksearch_is_active(summaryview->quicksearch)) {
                GSList *not_killed;
+               gint interval = quicksearch_is_fast(summaryview->quicksearch) ? 5000:100;
                START_TIMING("quicksearch");
                gint num = 0, total = summaryview->folder_item->total_msgs;
                statusbar_print_all(_("Searching in %s... \n"), 
                        summaryview->folder_item->path ? 
                        summaryview->folder_item->path : "(null)");
                not_killed = NULL;
+               folder_item_update_freeze();
                for (cur = mlist ; cur != NULL && cur->data != NULL ; cur = g_slist_next(cur)) {
                        MsgInfo * msginfo = (MsgInfo *) cur->data;
 
-                       statusbar_progress_all(num++,total, 50);
+                       statusbar_progress_all(num++,total, interval);
 
                        if (!msginfo->hidden && quicksearch_match(summaryview->quicksearch, msginfo))
                                not_killed = g_slist_prepend(not_killed, msginfo);
                        else
                                procmsg_msginfo_free(msginfo);
-                       GTK_EVENTS_FLUSH();
+                       if (num % interval == 0)
+                               GTK_EVENTS_FLUSH();
                        if (!quicksearch_is_active(summaryview->quicksearch)) {
                                break;
                        }
                }
+               folder_item_update_thaw();
                statusbar_progress_all(0,0,0);
                statusbar_pop_all();
                
                hidden_removed = TRUE;
                if (!quicksearch_is_active(summaryview->quicksearch)) {
                        debug_print("search cancelled!\n");
-                       gtk_clist_thaw(GTK_CLIST(ctree));
+                       summary_thaw(summaryview);
                        STATUSBAR_POP(summaryview->mainwin);
                        main_window_cursor_normal(summaryview->mainwin);
                        summary_unlock(summaryview);
@@ -1113,103 +1331,99 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        }
 
        if (is_refresh) {
-               summaryview->last_displayed = summaryview->displayed;
-               summaryview->displayed =
-                       summary_find_msg_by_msgnum(summaryview,
-                                                  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 */
-                       node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                            MSG_UNREAD, FALSE);
-                       if (node == NULL && GTK_CLIST(ctree)->row_list != NULL)
+               if (!quicksearch_is_in_typing(summaryview->quicksearch)) {
+                       summaryview->last_displayed = summaryview->displayed;
+                       summaryview->displayed =
+                               summary_find_msg_by_msgnum(summaryview,
+                                                          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 */
+                               node = summary_find_next_flagged_msg(summaryview, NULL,
+                                                                    MSG_UNREAD, 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);
+                               summary_unlock(summaryview);
+                               summary_select_node(summaryview, node, FALSE, TRUE);
+                               summary_lock(summaryview);
+                       }
+               } else {
+                       /* just select first/last */
+                       if (GTK_CLIST(ctree)->row_list != NULL)
                                node = gtk_ctree_node_nth
                                        (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);
+                       gtk_sctree_select(GTK_SCTREE(ctree), node);
+                       gtk_ctree_node_moveto(ctree, node, 0, 0.5, 0);
                }
        } else {
-               switch (prefs_common.select_on_entry) {
-                       case SELECTONENTRY_MNU:
-                               node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_MARKED, FALSE);
-                               if (node == NULL)
-                                       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);
+               /* backward compat */
+               int i = 0;
+               gboolean set = FALSE, stop = FALSE;
+               for (i = 0; i < 6; i++) {
+                       EntryAction act = prefs_common.summary_select_prio[i];
+
+                       if (act != ACTION_UNSET) {
+                               set = TRUE;
                                break;
-                       case SELECTONENTRY_MUN:
+                       }
+               }
+               if (!set)
+                       prefs_summary_open_set_defaults();
+
+               for (i = 0; i < 6 && node == NULL; i++) {
+                       EntryAction act = prefs_common.summary_select_prio[i];
+                       
+                       switch(act) {
+                       case ACTION_MARKED:
                                node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_MARKED, FALSE);
-                               if (node == NULL)
-                                       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);
+                                            MSG_MARKED, FALSE);
                                break;
-                       case SELECTONENTRY_NMU:
+                       case ACTION_NEW:
                                node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_NEW, FALSE);
-                               if (node == NULL)
-                                       node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_MARKED, FALSE);
-                               if (node == NULL)
-                                       node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_UNREAD, FALSE);
+                                            MSG_NEW, FALSE);
                                break;
-                       case SELECTONENTRY_NUM:
+                       case ACTION_UNREAD:
                                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);
-                               if (node == NULL)
-                                       node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_MARKED, FALSE);
+                                            MSG_UNREAD, FALSE);
                                break;
-                       case SELECTONENTRY_UNM:
-                               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);
-                               if (node == NULL)
-                                       node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_MARKED, FALSE);
+                       case ACTION_LAST_OPENED:
+                               if (summaryview->folder_item) {
+                                       node = summary_find_msg_by_msgnum(summaryview, 
+                                                       summaryview->folder_item->last_seen);
+                               }
                                break;
-                       case SELECTONENTRY_UMN:
-                               node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_UNREAD, FALSE);
-                               if (node == NULL)
-                                       node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_MARKED, FALSE);
-                               if (node == NULL)
-                                       node = summary_find_next_flagged_msg(summaryview, NULL,
-                                                                    MSG_NEW, FALSE);
+                       case ACTION_LAST_LIST:
+                               if (GTK_CLIST(ctree)->row_list != NULL) {
+                                       node = gtk_ctree_node_nth
+                                               (ctree,
+                                                item->sort_type == SORT_DESCENDING
+                                                ? 0 : GTK_CLIST(ctree)->rows - 1);
+                               }
                                break;
-                       default:
+                       case ACTION_NOTHING:
+                       case ACTION_UNSET:
                                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);
+                               stop = TRUE;
+                               break;
+                       }
+                       
+                       if (stop || node)
+                               break;
                }
+
                summary_unlock(summaryview);
-               summary_select_node(summaryview, node,
+               if (node)
+                       summary_select_node(summaryview, node,
                                    prefs_common.always_show_msg,
                                    TRUE);
                summary_lock(summaryview);
@@ -1219,7 +1433,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        summary_set_menu_sensitive(summaryview);
        toolbar_main_set_sensitive(summaryview->mainwin);
        
-       gtk_clist_thaw(GTK_CLIST(ctree));
+       summary_thaw(summaryview);
        debug_print("\n");
        STATUSBAR_PUSH(summaryview->mainwin, _("Done."));
        STATUSBAR_POP(summaryview->mainwin);
@@ -1238,7 +1452,7 @@ void summary_clear_list(SummaryView *summaryview)
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
        gint optimal_width;
 
-       gtk_clist_freeze(clist);
+       summary_freeze(summaryview);
 
        gtk_ctree_pre_recursive(GTK_CTREE(summaryview->ctree),
                                NULL, summary_free_msginfo_func, NULL);
@@ -1274,7 +1488,7 @@ void summary_clear_list(SummaryView *summaryview)
                         optimal_width);
        }
 
-       gtk_clist_thaw(clist);
+       summary_thaw(summaryview);
 }
 
 void summary_clear_all(SummaryView *summaryview)
@@ -1352,26 +1566,6 @@ GSList *summary_get_selected_msg_list(SummaryView *summaryview)
        return mlist;
 }
 
-GSList *summary_get_msg_list(SummaryView *summaryview)
-{
-       GSList *mlist = NULL;
-       GtkCTree *ctree;
-       GtkCTreeNode *node;
-       MsgInfo *msginfo;
-
-       ctree = GTK_CTREE(summaryview->ctree);
-
-       for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
-            node != NULL; node = gtkut_ctree_node_next(ctree, node)) {
-               msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(node);
-               mlist = g_slist_prepend(mlist, msginfo);
-       }
-
-       mlist = g_slist_reverse(mlist);
-
-       return mlist;
-}
-
 void summary_set_menu_sensitive(SummaryView *summaryview)
 {
        GtkItemFactory *ifactory = summaryview->popupfactory;
@@ -1385,19 +1579,25 @@ void summary_set_menu_sensitive(SummaryView *summaryview)
                SensitiveCond cond;
        } entry[] = {
                {"/Reply"                       , M_HAVE_ACCOUNT|M_TARGET_EXIST},
+#ifndef MAEMO
                {"/Reply to"                    , M_HAVE_ACCOUNT|M_TARGET_EXIST},
                {"/Reply to/all"                , M_HAVE_ACCOUNT|M_TARGET_EXIST},
                {"/Reply to/sender"             , M_HAVE_ACCOUNT|M_TARGET_EXIST},
                {"/Reply to/mailing list"       , M_HAVE_ACCOUNT|M_TARGET_EXIST},
+#endif
 
                {"/Forward"                     , M_HAVE_ACCOUNT|M_TARGET_EXIST},
+#ifndef MAEMO
                {"/Forward as attachment"       , M_HAVE_ACCOUNT|M_TARGET_EXIST},
                {"/Redirect"                    , M_HAVE_ACCOUNT|M_TARGET_EXIST},
+#endif
 
                {"/Move..."                     , M_TARGET_EXIST|M_ALLOW_DELETE|M_NOT_NEWS},
                {"/Copy..."                     , M_TARGET_EXIST|M_EXEC},
                {"/Move to trash"               , M_TARGET_EXIST|M_ALLOW_DELETE|M_NOT_NEWS},
+#ifndef MAEMO
                {"/Delete..."                   , M_TARGET_EXIST|M_ALLOW_DELETE},
+#endif
 
                {"/Mark"                        , M_TARGET_EXIST},
                {"/Mark/Mark"                   , M_TARGET_EXIST},
@@ -1411,17 +1611,26 @@ void summary_set_menu_sensitive(SummaryView *summaryview)
                {"/Mark/Mark as spam"           , M_TARGET_EXIST|M_CAN_LEARN_SPAM},
                {"/Mark/Mark as ham"            , M_TARGET_EXIST|M_CAN_LEARN_SPAM},
                {"/Color label"                 , M_TARGET_EXIST},
+               {"/Tags"                        , M_TARGET_EXIST},
 
+#ifndef MAEMO
                {"/Add sender to address book"  , M_SINGLE_TARGET_EXIST},
+#endif
                {"/Create filter rule"          , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
+#ifndef MAEMO
                {"/Create processing rule"      , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
+#endif
 
                {"/View"                        , M_SINGLE_TARGET_EXIST},
                {"/View/Open in new window"     , M_SINGLE_TARGET_EXIST},
                {"/View/Message source"         , M_SINGLE_TARGET_EXIST},
+#ifndef MAEMO
                {"/View/All headers"            , M_SINGLE_TARGET_EXIST},
+#endif
                {"/Save as..."                  , M_TARGET_EXIST},
+#ifndef MAEMO
                {"/Print..."                    , M_TARGET_EXIST},
+#endif
                {NULL, 0}
        };
 
@@ -1436,6 +1645,7 @@ void summary_set_menu_sensitive(SummaryView *summaryview)
 
 
        summary_lock(summaryview);
+#ifndef MAEMO
        menuitem = gtk_item_factory_get_widget(ifactory, "/View/All headers");
        if (summaryview->messageview 
        &&  summaryview->messageview->mimeview
@@ -1443,6 +1653,7 @@ void summary_set_menu_sensitive(SummaryView *summaryview)
                gtk_check_menu_item_set_active
                        (GTK_CHECK_MENU_ITEM(menuitem),
                         summaryview->messageview->mimeview->textview->show_all_headers);
+#endif
        summary_unlock(summaryview);
 }
 
@@ -2053,7 +2264,7 @@ void summary_attract_by_subject(SummaryView *summaryview)
                       _("Attracting messages by subject..."));
 
        main_window_cursor_wait(summaryview->mainwin);
-       gtk_clist_freeze(clist);
+       summary_freeze(summaryview);
 
        subject_table = g_hash_table_new(attract_hash_func,
                                         attract_compare_func);
@@ -2092,7 +2303,7 @@ void summary_attract_by_subject(SummaryView *summaryview)
 
        gtk_ctree_node_moveto(ctree, summaryview->selected, 0, 0.5, 0);
 
-       gtk_clist_thaw(clist);
+       summary_thaw(summaryview);
 
        debug_print("done.\n");
        STATUSBAR_POP(summaryview->mainwin);
@@ -2241,22 +2452,48 @@ static void summary_status_show(SummaryView *summaryview)
                itstr = g_strdup("");
        }
                
-       str = g_strconcat(n_selected ? itos(n_selected) : "",
-                                       itstr, sel, spc, del, mv, cp, NULL);
-       gtk_label_set_text(GTK_LABEL(summaryview->statlabel_select), str);
-       g_free(str);
-       g_free(sel);
-       g_free(del);
-       g_free(mv);
-       g_free(cp);
-       g_free(itstr);
-
-       str = g_strdup_printf(_("%d new, %d unread, %d total (%s)"),
-
-                                     n_new, n_unread, n_total,
-                                     to_human_readable(n_size));
-       gtk_label_set_text(GTK_LABEL(summaryview->statlabel_msgs), str);
-       g_free(str);
+       if (prefs_common.layout_mode != SMALL_LAYOUT) {
+               str = g_strconcat(n_selected ? itos(n_selected) : "",
+                                               itstr, sel, spc, del, mv, cp, NULL);
+               g_free(sel);
+               g_free(del);
+               g_free(mv);
+               g_free(cp);
+               g_free(itstr);
+               
+               gtk_label_set_text(GTK_LABEL(summaryview->statlabel_select), str);
+               g_free(str);
+
+               str = g_strdup_printf(_("%d new, %d unread, %d total (%s)"),
+
+                                             n_new, n_unread, n_total,
+                                             to_human_readable(n_size));
+
+               gtk_label_set_text(GTK_LABEL(summaryview->statlabel_msgs), str);
+               g_free(str);
+       } else {
+               gchar *ssize, *tsize;
+               if (n_selected) {
+                       ssize = g_strdup(to_human_readable(sel_size));
+                       tsize = g_strdup(to_human_readable(n_size));
+                       str = g_strdup_printf(_("%d/%d selected (%s/%s), %d unread"),
+                               n_selected, n_total, ssize, tsize, n_unread);
+                       g_free(ssize);
+                       g_free(tsize);
+               } else
+                       str = g_strdup_printf(_("%d new, %d unread, %d total (%s)"),
+                               n_new, n_unread, n_total, to_human_readable(n_size));
+               g_free(sel);
+               g_free(del);
+               g_free(mv);
+               g_free(cp);
+               g_free(itstr);
+               
+               gtk_label_set_text(GTK_LABEL(summaryview->statlabel_select), str);
+               g_free(str);
+       }
+
+       summary_set_menu_sensitive(summaryview);
        toolbar_main_set_sensitive(summaryview->mainwin);
 }
 
@@ -2283,7 +2520,8 @@ static void summary_set_column_titles(SummaryView *summaryview)
                SORT_BY_SIZE,
                SORT_BY_NUMBER,
                SORT_BY_SCORE,
-               SORT_BY_LOCKED
+               SORT_BY_LOCKED,
+               SORT_BY_TAGS
        };
 
        for (pos = 0; pos < N_SUMMARY_COLS; pos++) {
@@ -2300,12 +2538,13 @@ static void summary_set_column_titles(SummaryView *summaryview)
                case S_COL_DATE:
                case S_COL_NUMBER:
                        if(type == S_COL_FROM && item != NULL &&
-                                       FOLDER_SHOWS_TO_HDR(item))
+                                       FOLDER_SHOWS_TO_HDR(item) &&
+                                       !summaryview->col_state[summaryview->col_pos[S_COL_TO]].visible)
                                type = S_COL_TO;
-                       if (prefs_common.trans_hdr)
+                       if(type == S_COL_NUMBER)
                                title = gettext(col_label[type]);
                        else
-                               title = col_label[type];
+                               title = prefs_common_translated_header_name(col_label[type]);
                        break;
                default:
                        title = gettext(col_label[type]);
@@ -2337,6 +2576,9 @@ static void summary_set_column_titles(SummaryView *summaryview)
 
                hbox  = gtk_hbox_new(FALSE, 4);
                label = gtk_label_new(title);
+#ifdef MAEMO
+       gtk_widget_set_size_request(hbox, -1, 20);
+#endif
 
                if (justify == GTK_JUSTIFY_RIGHT)
                        gtk_box_pack_end(GTK_BOX(hbox), label,
@@ -2363,6 +2605,37 @@ static void summary_set_column_titles(SummaryView *summaryview)
        }
 }
 
+void summary_reflect_tags_changes(SummaryView *summaryview)
+{
+       GtkMenuShell *menu;
+       GList *cur;
+       GtkCTreeNode *node;
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       gboolean froze = FALSE;
+       gboolean redisplay = FALSE;
+
+       /* re-create colorlabel submenu */
+       menu = GTK_MENU_SHELL(summaryview->tags_menu);
+       g_return_if_fail(menu != NULL);
+
+       /* clear items. get item pointers. */
+       for (cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
+               gtk_menu_item_remove_submenu(GTK_MENU_ITEM(cur->data));
+       }
+       summary_tags_menu_create(summaryview, TRUE);
+
+       START_LONG_OPERATION(summaryview, TRUE);
+       for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); node != NULL;
+            node = gtkut_ctree_node_next(ctree, node)) {
+               redisplay |= summary_set_row_tag(summaryview,
+                                          node, TRUE, FALSE, 0);
+       }
+       END_LONG_OPERATION(summaryview);
+       if (redisplay)
+               summary_redisplay_msg(summaryview);
+}
+
+
 void summary_reflect_prefs(void)
 {
        static gchar *last_font = NULL;
@@ -2387,7 +2660,10 @@ void summary_reflect_prefs(void)
        }
 
        summary_set_column_titles(summaryview);
-       summary_show(summaryview, summaryview->folder_item);
+       summary_relayout(summaryview);
+       
+       if (summaryview->folder_item)
+               summary_show(summaryview, summaryview->folder_item);
 }
 
 void summary_sort(SummaryView *summaryview,
@@ -2399,7 +2675,7 @@ void summary_sort(SummaryView *summaryview,
        START_TIMING("");
        g_signal_handlers_block_by_func(G_OBJECT(summaryview->ctree),
                                       G_CALLBACK(summary_tree_expanded), summaryview);
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
+       summary_freeze(summaryview);
 
        switch (sort_key) {
        case SORT_BY_MARK:
@@ -2420,6 +2696,9 @@ void summary_sort(SummaryView *summaryview,
        case SORT_BY_DATE:
                cmp_func = (GtkCListCompareFunc)summary_cmp_by_date;
                break;
+       case SORT_BY_THREAD_DATE:
+               cmp_func = (GtkCListCompareFunc)summary_cmp_by_thread_date;
+               break;
        case SORT_BY_FROM:
                cmp_func = (GtkCListCompareFunc)summary_cmp_by_from;
                break;
@@ -2441,6 +2720,9 @@ void summary_sort(SummaryView *summaryview,
        case SORT_BY_LOCKED:
                cmp_func = (GtkCListCompareFunc)summary_cmp_by_locked;
                break;
+       case SORT_BY_TAGS:
+               cmp_func = (GtkCListCompareFunc)summary_cmp_by_tags;
+               break;
        case SORT_BY_NONE:
                break;
        default:
@@ -2463,7 +2745,6 @@ void summary_sort(SummaryView *summaryview,
 
                main_window_cursor_wait(summaryview->mainwin);
 
-                gtk_clist_freeze(clist);
                gtk_clist_set_compare_func(clist, cmp_func);
 
                gtk_clist_set_sort_type(clist, (GtkSortType)sort_type);
@@ -2472,19 +2753,43 @@ void summary_sort(SummaryView *summaryview,
                gtk_ctree_node_moveto(ctree, summaryview->selected, 0, 0.5, 0);
 
                main_window_cursor_normal(summaryview->mainwin);
-                gtk_clist_thaw(clist);
 
                debug_print("done.\n");
                STATUSBAR_POP(summaryview->mainwin);
        }
 unlock:
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       summary_thaw(summaryview);
        g_signal_handlers_unblock_by_func(G_OBJECT(summaryview->ctree),
                                       G_CALLBACK(summary_tree_expanded), summaryview);
        END_TIMING();
 }
 
-gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
+static gboolean summary_update_thread_age(GNode *node, gpointer data)
+{
+       MsgInfo *msginfo = node->data;
+       time_t *most_recent = (time_t *)data;
+
+       if (msginfo->date_t > *most_recent) {
+               *most_recent = msginfo->date_t;
+       }
+       return FALSE;
+}      
+
+static void summary_find_thread_age(GNode *gnode)
+{
+       MsgInfo *msginfo = (MsgInfo *)gnode->data;
+       time_t most_recent;
+
+       if (!msginfo)
+               return;
+       most_recent = msginfo->thread_date = msginfo->date_t;
+
+       g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1, summary_update_thread_age, &most_recent);
+
+       msginfo->thread_date = most_recent;
+}
+
+static gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
                                   GtkCTreeNode *cnode, gpointer data)
 {
        SummaryView *summaryview = (SummaryView *)data;
@@ -2515,6 +2820,8 @@ gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
                SET_TEXT(S_COL_FROM);
        if (summaryview->col_state[summaryview->col_pos[S_COL_TO]].visible)
                SET_TEXT(S_COL_TO);
+       if (summaryview->col_state[summaryview->col_pos[S_COL_TAGS]].visible)
+               SET_TEXT(S_COL_TAGS);
 
 #undef SET_TEXT
 
@@ -2534,13 +2841,13 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
        MsgInfo *msginfo;
        GtkCTreeNode *node = NULL;
        GHashTable *msgid_table;
-       GHashTable *subject_table;
+       GHashTable *subject_table = NULL;
        GSList * cur;
        START_TIMING("");
        
        if (!mlist) return;
 
-       debug_print("\tSetting summary from message data...");
+       debug_print("\tSetting summary from message data...\n");
        STATUSBAR_PUSH(summaryview->mainwin,
                       _("Setting summary from message data..."));
        gdk_flush();
@@ -2550,8 +2857,13 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
 
        msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
        summaryview->msgid_table = msgid_table;
-       subject_table = g_hash_table_new(g_str_hash, g_str_equal);
-       summaryview->subject_table = subject_table;
+
+       if (prefs_common.thread_by_subject) {
+               subject_table = g_hash_table_new(g_str_hash, g_str_equal);
+               summaryview->subject_table = subject_table;
+       } else {
+               summaryview->subject_table = NULL;
+       }
 
        if (prefs_common.use_addr_book)
                start_address_completion(NULL);
@@ -2561,8 +2873,10 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
                START_TIMING("threaded");
                root = procmsg_get_thread_tree(mlist);
 
+               
                for (gnode = root->children; gnode != NULL;
                     gnode = gnode->next) {
+                       summary_find_thread_age(gnode);
                        node = gtk_sctree_insert_gnode
                                (ctree, NULL, node, gnode,
                                 summary_insert_gnode_func, summaryview);
@@ -2592,7 +2906,8 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
                                g_hash_table_insert(msgid_table,
                                                    msginfo->msgid, node);
 
-                       subject_table_insert(subject_table,
+                       if (prefs_common.thread_by_subject)
+                               subject_table_insert(subject_table,
                                             msginfo->subject,
                                             node);
                }
@@ -2619,7 +2934,8 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
        if (debug_get_mode()) {
                debug_print("\tmsgid hash table size = %d\n",
                            g_hash_table_size(msgid_table));
-               debug_print("\tsubject hash table size = %d\n",
+               if (prefs_common.thread_by_subject)
+                       debug_print("\tsubject hash table size = %d\n",
                            g_hash_table_size(subject_table));
        }
 
@@ -2669,14 +2985,14 @@ static gchar *summary_complete_address(const gchar *addr)
        return res;
 }
 
-static void summary_set_header(SummaryView *summaryview, gchar *text[],
+static inline void summary_set_header(SummaryView *summaryview, gchar *text[],
                               MsgInfo *msginfo)
 {
        static gchar date_modified[80];
        static gchar col_score[11];
-       static gchar buf[BUFFSIZE];
+       static gchar buf[BUFFSIZE], tmp1[BUFFSIZE], tmp2[BUFFSIZE], tmp3[BUFFSIZE];
        gint *col_pos = summaryview->col_pos;
-       gchar *from_text = NULL, *to_text = NULL;
+       gchar *from_text = NULL, *to_text = NULL, *tags_text = NULL;
        gboolean should_swap = FALSE;
 
        text[col_pos[S_COL_FROM]]   = "";
@@ -2687,6 +3003,7 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
        text[col_pos[S_COL_MIME]]   = "";
        text[col_pos[S_COL_LOCKED]] = "";
        text[col_pos[S_COL_DATE]]   = "";
+       text[col_pos[S_COL_TAGS]]   = "";
        if (summaryview->col_state[summaryview->col_pos[S_COL_NUMBER]].visible)
                text[col_pos[S_COL_NUMBER]] = itos(msginfo->msgnum);
        else
@@ -2703,6 +3020,19 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
        else
                text[col_pos[S_COL_SCORE]] = "";
 
+       if (summaryview->col_state[summaryview->col_pos[S_COL_TAGS]].visible) {
+               tags_text = procmsg_msginfo_get_tags_str(msginfo);
+               if (!tags_text) {
+                       text[col_pos[S_COL_TAGS]] = "-";
+               } else {
+                       strncpy2(tmp1, tags_text, sizeof(tmp1));
+                       tmp1[sizeof(tmp1)-1]='\0';
+                       g_free(tags_text);
+                       text[col_pos[S_COL_TAGS]] = tmp1;
+               }
+       } else
+               text[col_pos[S_COL_TAGS]] = "";
+
        /* slow! */
        if (summaryview->col_state[summaryview->col_pos[S_COL_DATE]].visible) {
                if (msginfo->date_t) {
@@ -2736,7 +3066,6 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
                                msginfo->fromname :
                                _("(No From)");
        } else {
-               gchar buf[BUFFSIZE];
                gchar *tmp = summary_complete_address(msginfo->from);
                if (tmp) {
                        strncpy2(buf, tmp, sizeof(buf));
@@ -2759,15 +3088,14 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[],
        if (!should_swap) {
                text[col_pos[S_COL_FROM]] = from_text;
        } else {
-               gchar tmp[BUFFSIZE];
-               snprintf(tmp, BUFFSIZE-1, "--> %s", to_text);
-               tmp[BUFFSIZE-1]='\0';
-               text[col_pos[S_COL_FROM]] = tmp;
+               snprintf(tmp2, BUFFSIZE-1, "--> %s", to_text);
+               tmp2[BUFFSIZE-1]='\0';
+               text[col_pos[S_COL_FROM]] = tmp2;
        }
        
        if (summaryview->simplify_subject_preg != NULL)
                text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? 
-                       string_remove_match(buf, BUFFSIZE, msginfo->subject, 
+                       string_remove_match(tmp3, BUFFSIZE, msginfo->subject, 
                                        summaryview->simplify_subject_preg) : 
                        _("(No Subject)");
        else 
@@ -2888,7 +3216,6 @@ static void msginfo_mark_as_read (SummaryView *summaryview, MsgInfo *msginfo,
 typedef struct  {
        MsgInfo *msginfo;
        SummaryView *summaryview;
-       GtkCTreeNode *row;
 } MarkAsReadData;
 
 static int msginfo_mark_as_read_timeout(void *data)
@@ -2899,7 +3226,7 @@ static int msginfo_mark_as_read_timeout(void *data)
        
        if (mdata->msginfo == summary_get_selected_msg(mdata->summaryview))
                msginfo_mark_as_read(mdata->summaryview, mdata->msginfo,
-                                    mdata->row); 
+                                    mdata->summaryview->selected); 
 
        g_free(mdata);
 
@@ -2917,7 +3244,7 @@ static void summary_display_msg_full(SummaryView *summaryview,
        if (!new_window) {
                if (summaryview->displayed == row)
                        return;
-               else
+               else if (summaryview->messageview)
                        summaryview->messageview->filtered = FALSE;
        }                       
        g_return_if_fail(row != NULL);
@@ -2932,7 +3259,7 @@ static void summary_display_msg_full(SummaryView *summaryview,
        
        g_return_if_fail(msginfo);
 
-       if (new_window) {
+       if (new_window && prefs_common.layout_mode != SMALL_LAYOUT) {
                MessageView *msgview;
 
                msgview = messageview_create_with_new_window(summaryview->mainwin);
@@ -2940,18 +3267,33 @@ static void summary_display_msg_full(SummaryView *summaryview,
        } else {
                MessageView *msgview;
 
-               msgview = summaryview->messageview;
-               summaryview->last_displayed = summaryview->displayed;
-               summaryview->displayed = row;
-               if (!messageview_is_visible(msgview)) {
-                       main_window_toggle_message_view(summaryview->mainwin);
-                       GTK_EVENTS_FLUSH();
+               if (prefs_common.layout_mode == SMALL_LAYOUT) {
+                       if (summaryview->ext_messageview == NULL)
+                               summaryview->ext_messageview = messageview_create_with_new_window(summaryview->mainwin);
+                       else
+                               gtkut_window_popup(summaryview->ext_messageview->window);
+                       msgview = summaryview->ext_messageview;
+                       summaryview->last_displayed = summaryview->displayed;
+                       summaryview->displayed = row;
+                       val = messageview_show(msgview, msginfo, all_headers);
+                       if (GTK_CLIST(msgview->mimeview->ctree)->row_list == NULL)
+                               gtk_widget_grab_focus(summaryview->ctree);
+                       gtkut_ctree_node_move_if_on_the_edge(ctree, row,
+                               GTK_CLIST(summaryview->ctree)->focus_row);
+               } else {
+                       msgview = summaryview->messageview;
+                       summaryview->last_displayed = summaryview->displayed;
+                       summaryview->displayed = row;
+                       if (!messageview_is_visible(msgview)) {
+                               main_window_toggle_message_view(summaryview->mainwin);
+                               GTK_EVENTS_FLUSH();
+                       }
+                       val = messageview_show(msgview, msginfo, all_headers);
+                       if (GTK_CLIST(msgview->mimeview->ctree)->row_list == NULL)
+                               gtk_widget_grab_focus(summaryview->ctree);
+                       gtkut_ctree_node_move_if_on_the_edge(ctree, row,
+                               GTK_CLIST(summaryview->ctree)->focus_row);
                }
-               val = messageview_show(msgview, msginfo, all_headers);
-               if (GTK_CLIST(msgview->mimeview->ctree)->row_list == NULL)
-                       gtk_widget_grab_focus(summaryview->ctree);
-               gtkut_ctree_node_move_if_on_the_edge(ctree, row,
-                       GTK_CLIST(summaryview->ctree)->focus_row);
        }
 
        if (val == 0 && MSG_IS_UNREAD(msginfo->flags)) {
@@ -2959,8 +3301,7 @@ static void summary_display_msg_full(SummaryView *summaryview,
                        MarkAsReadData *data = g_new0(MarkAsReadData, 1);
                        data->summaryview = summaryview;
                        data->msginfo = msginfo;
-                       data->row = row;
-                       gtk_timeout_add(prefs_common.mark_as_read_delay * 1000,
+                       g_timeout_add(prefs_common.mark_as_read_delay * 1000,
                                msginfo_mark_as_read_timeout, data);
                } else if (new_window || !prefs_common.mark_as_read_on_new_window) {
                        msginfo_mark_as_read(summaryview, msginfo, row);
@@ -3001,9 +3342,8 @@ void summary_open_msg(SummaryView *summaryview)
        
        /* CLAWS: if separate message view, don't open a new window
         * but rather use the current separated message view */
-       summary_display_msg_full(summaryview, summaryview->selected,
-                                prefs_common.sep_msg ? FALSE : TRUE, 
-                                FALSE);
+       summary_display_msg_full(summaryview, summaryview->selected, 
+                                TRUE, FALSE);
 }
 
 void summary_view_source(SummaryView * summaryview)
@@ -3018,6 +3358,10 @@ void summary_view_source(SummaryView * summaryview)
        msginfo = gtk_ctree_node_get_row_data(ctree, summaryview->selected);
        source_window_show_msg(srcwin, msginfo);
        source_window_show(srcwin);
+#ifdef MAEMO
+       maemo_window_full_screen_if_needed(GTK_WINDOW(srcwin->window));
+       maemo_connect_key_press_to_mainwindow(GTK_WINDOW(srcwin->window));
+#endif
 }
 
 void summary_reedit(SummaryView *summaryview)
@@ -3088,6 +3432,8 @@ gboolean summary_step(SummaryView *summaryview, GtkScrollType type)
 
 void summary_toggle_view(SummaryView *summaryview)
 {
+       if (prefs_common.layout_mode == SMALL_LAYOUT)
+               return;
        if (!messageview_is_visible(summaryview->messageview) &&
            summaryview->selected)
                summary_display_msg(summaryview,
@@ -3154,6 +3500,9 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row)
        if (MSG_IS_IGNORE_THREAD(flags)) {
                gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_STATUS],
                                          ignorethreadxpm, ignorethreadxpmmask);
+       } else if (MSG_IS_WATCH_THREAD(flags)) {
+               gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_STATUS],
+                                         watchthreadxpm, watchthreadxpmmask);
        } else if (MSG_IS_SPAM(flags)) {
                gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_STATUS],
                                          spamxpm, spamxpmmask);
@@ -3350,8 +3699,7 @@ static void summary_mark_row_as_read(SummaryView *summaryview,
                msginfo->msgnum);
 }
 
-void summary_mark_as_read
-(SummaryView *summaryview)
+void summary_mark_as_read(SummaryView *summaryview)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
@@ -3462,17 +3810,20 @@ void summary_mark_as_spam(SummaryView *summaryview, guint action, GtkWidget *wid
                                continue;
                        if (is_spam) {
                                summary_msginfo_change_flags(msginfo, MSG_SPAM, 0, MSG_NEW|MSG_UNREAD, 0);
-                               if (procmsg_spam_get_folder() != summaryview->folder_item) {
-                                       summary_move_row_to(summaryview, row, procmsg_spam_get_folder());
+                               if (procmsg_spam_get_folder(msginfo) != summaryview->folder_item) {
+                                       summary_move_row_to(summaryview, row,
+                                                       procmsg_spam_get_folder(msginfo));
                                        moved = TRUE;
                                }
                        } else {
                                summary_msginfo_unset_flags(msginfo, MSG_SPAM, 0);
                        }
+                       summaryview->display_msg = prefs_common.always_show_msg;
+       
                        summary_set_row_marks(summaryview, row);
                }
        } else {
-               log_error(_("An error happened while learning.\n"));
+               log_error(LOG_PROTOCOL, _("An error happened while learning.\n"));
        }
 
        prefs_common.immediate_exec = immediate_exec;
@@ -3616,7 +3967,6 @@ static void summary_delete_row(SummaryView *summaryview, GtkCTreeNode *row)
 void summary_cancel(SummaryView *summaryview)
 {
        MsgInfo * msginfo;
-       GtkCList *clist = GTK_CLIST(summaryview->ctree);
 
        msginfo = gtk_ctree_node_get_row_data(GTK_CTREE(summaryview->ctree),
                                              summaryview->selected);
@@ -3631,12 +3981,12 @@ void summary_cancel(SummaryView *summaryview)
 
        summary_lock(summaryview);
 
-       gtk_clist_freeze(clist);
+       summary_freeze(summaryview);
 
        summary_update_status(summaryview);
        summary_status_show(summaryview);
 
-       gtk_clist_thaw(clist);
+       summary_thaw(summaryview);
 
        summary_unlock(summaryview);
 }
@@ -3659,9 +4009,19 @@ void summary_delete(SummaryView *summaryview)
        if (!summaryview->folder_item) return;
 
        if (!prefs_common.live_dangerously) {
+               gchar *buf = NULL;
+               int num = g_list_length(GTK_CLIST(summaryview->ctree)->selection);
+               if (num == 1)
+                       buf = g_strdup_printf(_(
+                               "Do you really want to delete the selected message?"));
+               else
+                       buf = g_strdup_printf(_(
+                               "Do you really want to delete the %d selected messages?"), 
+                               num);
                aval = alertpanel(_("Delete message(s)"),
-                                 _("Do you really want to delete selected message(s)?"),
+                                 buf,
                                  GTK_STOCK_CANCEL, "+"GTK_STOCK_DELETE, NULL);
+               g_free(buf);
                if (aval != G_ALERTALTERNATE) return;
        }
 
@@ -3817,6 +4177,12 @@ void summary_move_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                return;
        }
 
+       if (to_folder->no_select) {
+               alertpanel_error(_("The destination folder can only be used to "
+                                  "store subfolders."));
+               return;
+       }
+
        START_LONG_OPERATION(summaryview, FALSE); 
 
        for (cur = GTK_CLIST(summaryview->ctree)->selection;
@@ -3908,6 +4274,12 @@ void summary_copy_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                return;
        }
 
+       if (to_folder->no_select) {
+               alertpanel_error(_("The destination folder can only be used to "
+                                  "store subfolders."));
+               return;
+       }
+
        START_LONG_OPERATION(summaryview, FALSE);
 
        for (cur = GTK_CLIST(summaryview->ctree)->selection;
@@ -3968,24 +4340,38 @@ void summary_unselect_all(SummaryView *summaryview)
        summary_status_show(summaryview);
 }
 
-void summary_select_thread(SummaryView *summaryview)
+void summary_select_thread(SummaryView *summaryview, gboolean delete_thread)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-       GtkCTreeNode *node = summaryview->selected;
-
-       if (!node) return;
+       GtkCTreeNode *node = NULL;
+       gboolean froze = FALSE;
+       GList *cur = NULL;
+       GList *copy = NULL;
+       if (!GTK_CLIST(summaryview->ctree)->selection) 
+               return;
 
-       while (GTK_CTREE_ROW(node)->parent != NULL)
-               node = GTK_CTREE_ROW(node)->parent;
 
-       if (node != summaryview->selected)
-               summary_select_node
-                       (summaryview, node,
-                        messageview_is_visible(summaryview->messageview),
-                        FALSE);
+       START_LONG_OPERATION(summaryview, FALSE);
+       copy = g_list_copy(GTK_CLIST(summaryview->ctree)->selection);
+       for (cur = copy; cur != NULL && cur->data != NULL;
+            cur = cur->next) {
+               node = GTK_CTREE_NODE(cur->data);
+               if (!node)
+                       continue;
+               while (GTK_CTREE_ROW(node)->parent != NULL)
+                       node = GTK_CTREE_ROW(node)->parent;
 
-       gtk_ctree_select_recursive(ctree, node);
+               gtk_ctree_select_recursive(ctree, node);
+       }
+       g_list_free(copy);
+       END_LONG_OPERATION(summaryview);
 
+       if (delete_thread) {
+               if (FOLDER_TYPE(summaryview->folder_item->folder) == F_NEWS)
+                       summary_delete(summaryview);
+               else
+                       summary_delete_trash(summaryview);
+       }
        summary_status_show(summaryview);
 }
 
@@ -4007,14 +4393,13 @@ void summary_save_as(SummaryView *summaryview)
                Xstrdup_a(filename, msginfo->subject, return);
                subst_for_filename(filename);
        }
-       if (g_getenv ("G_BROKEN_FILENAMES") &&
-           filename && !g_utf8_validate(filename, -1, NULL)) {
+       if (filename && !g_utf8_validate(filename, -1, NULL)) {
                gchar *oldstr = filename;
                filename = conv_codeset_strdup(filename,
                                               conv_get_locale_charset_str(),
                                               CS_UTF_8);
                if (!filename) {
-                       g_warning("summary_save_as(): faild to convert character set.");
+                       g_warning("summary_save_as(): failed to convert character set.");
                        filename = g_strdup(oldstr);
                }
                dest = filesel_select_file_save(_("Save as"), filename);
@@ -4073,6 +4458,17 @@ void summary_print(SummaryView *summaryview)
        gchar *p;
 #endif
        GList *cur;
+       gchar *msg = g_strdup_printf(_("You are about to print %d "
+                                      "messages, one by one. Do you "
+                                      "want to continue?"), 
+                                      g_list_length(clist->selection));
+       if (g_list_length(clist->selection) > 9
+       &&  alertpanel(_("Warning"), msg, GTK_STOCK_CANCEL, "+" GTK_STOCK_YES, NULL)
+           != G_ALERTALTERNATE) {
+               g_free(msg);
+               return;
+       }
+       g_free(msg);
 
        if (clist->selection == NULL) return;
 #ifndef USE_GNOMEPRINT
@@ -4106,7 +4502,15 @@ void summary_print(SummaryView *summaryview)
                MsgInfo *msginfo = gtk_ctree_node_get_row_data(
                                        GTK_CTREE(summaryview->ctree),
                                        node);
-               messageview_print(msginfo, summaryview->messageview->all_headers);
+               gint sel_start = -1, sel_end = -1, partnum = 0;
+               
+               if (node == summaryview->displayed) {
+                       partnum = mimeview_get_selected_part_num(summaryview->messageview->mimeview);
+                       textview_get_selection_offsets(summaryview->messageview->mimeview->textview,
+                               &sel_start, &sel_end);
+               } 
+               messageview_print(msginfo, summaryview->messageview->all_headers,
+                       sel_start, sel_end, partnum);
        }
 #endif
 }
@@ -4124,7 +4528,7 @@ gboolean summary_execute(SummaryView *summaryview)
        if (summary_is_locked(summaryview)) return FALSE;
        summary_lock(summaryview);
 
-       gtk_clist_freeze(clist);
+       summary_freeze(summaryview);
 
        main_window_cursor_wait(summaryview->mainwin);
 
@@ -4186,7 +4590,7 @@ gboolean summary_execute(SummaryView *summaryview)
                summary_thread_init(summaryview);
        }
 
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       summary_thaw(summaryview);
 
        summaryview->selected = clist->selection ?
                GTK_CTREE_NODE(clist->selection->data) : NULL;
@@ -4256,7 +4660,8 @@ static void summary_execute_move_func(GtkCTree *ctree, GtkCTreeNode *node,
                                                msginfo->msgid))
                        g_hash_table_remove(summaryview->msgid_table,
                                            msginfo->msgid);
-               if (msginfo->subject && *msginfo->subject && 
+               if (prefs_common.thread_by_subject &&
+                   msginfo->subject && *msginfo->subject && 
                    node == subject_table_lookup(summaryview->subject_table,
                                                 msginfo->subject)) {
                        subject_table_remove(summaryview->subject_table,
@@ -4350,7 +4755,8 @@ static void summary_execute_delete_func(GtkCTree *ctree, GtkCTreeNode *node,
                        g_hash_table_remove(summaryview->msgid_table,
                                            msginfo->msgid);
                }       
-               if (msginfo->subject && *msginfo->subject && 
+               if (prefs_common.thread_by_subject &&
+                   msginfo->subject && *msginfo->subject && 
                    node == subject_table_lookup(summaryview->subject_table,
                                                 msginfo->subject)) {
                        subject_table_remove(summaryview->subject_table,
@@ -4378,7 +4784,7 @@ void summary_thread_build(SummaryView *summaryview)
 
        g_signal_handlers_block_by_func(G_OBJECT(ctree),
                                       G_CALLBACK(summary_tree_expanded), summaryview);
-       gtk_clist_freeze(GTK_CLIST(ctree));
+       summary_freeze(summaryview);
 
        node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
        while (node) {
@@ -4417,7 +4823,7 @@ void summary_thread_build(SummaryView *summaryview)
 
        gtkut_ctree_set_focus_row(ctree, summaryview->selected);
 
-       gtk_clist_thaw(GTK_CLIST(ctree));
+       summary_thaw(summaryview);
        g_signal_handlers_unblock_by_func(G_OBJECT(ctree),
                                         G_CALLBACK(summary_tree_expanded), summaryview);
 
@@ -4531,7 +4937,7 @@ void summary_expand_threads(SummaryView *summaryview)
 
        g_signal_handlers_block_by_func(G_OBJECT(ctree),
                                       G_CALLBACK(summary_tree_expanded), summaryview);
-       gtk_clist_freeze(GTK_CLIST(ctree));
+       summary_freeze(summaryview);
 
        while (node) {
                if (GTK_CTREE_ROW(node)->children) {
@@ -4541,7 +4947,7 @@ void summary_expand_threads(SummaryView *summaryview)
                node = GTK_CTREE_NODE_NEXT(node);
        }
 
-       gtk_clist_thaw(GTK_CLIST(ctree));
+       summary_thaw(summaryview);
        g_signal_handlers_unblock_by_func(G_OBJECT(ctree),
                                         G_CALLBACK(summary_tree_expanded), summaryview);
 
@@ -4555,7 +4961,7 @@ void summary_collapse_threads(SummaryView *summaryview)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GtkCTreeNode *node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
 
-       gtk_clist_freeze(GTK_CLIST(ctree));
+       summary_freeze(summaryview);
 
        while (node) {
                if (GTK_CTREE_ROW(node)->children)
@@ -4563,19 +4969,19 @@ void summary_collapse_threads(SummaryView *summaryview)
                node = GTK_CTREE_ROW(node)->sibling;
        }
 
-       gtk_clist_thaw(GTK_CLIST(ctree));
+       summary_thaw(summaryview);
        
        summaryview->thread_collapsed = TRUE;
 
        gtk_ctree_node_moveto(ctree, summaryview->selected, 0, 0.5, 0);
 }
 
-void account_rules_radio_button_toggled_cb(GtkToggleButton *btn, gpointer data)
+static void account_rules_radio_button_toggled_cb(GtkToggleButton *btn, gpointer data)
 {
        prefs_common.apply_per_account_filtering_rules = GPOINTER_TO_INT(data);
 }
 
-gboolean summary_filter_get_mode(void)
+static gboolean summary_filter_get_mode(void)
 /* ask what to do w/ them: skip them, apply them regardless to the account,
    use the current account */
 {
@@ -4598,7 +5004,7 @@ gboolean summary_filter_get_mode(void)
                                                        _("Apply these rules regardless of the account they belong to"));
        account_rules_user_current = gtk_radio_button_new_with_label_from_widget
                                                        (GTK_RADIO_BUTTON(account_rules_skip),
-                                                       _("Use current account for these rules"));
+                                                       _("Apply these rules if they apply to the current account"));
        gtk_box_pack_start (GTK_BOX (vbox), account_rules_skip, FALSE, FALSE, 0);
        gtk_box_pack_start (GTK_BOX (vbox), account_rules_force, FALSE, FALSE, 0);
        gtk_box_pack_start (GTK_BOX (vbox), account_rules_user_current, FALSE, FALSE, 0);
@@ -4630,8 +5036,9 @@ gboolean summary_filter_get_mode(void)
                        _("Filtering"),
                        _("There are some filtering rules that belong to an account.\n"
                          "Please choose what to do with these rules:"),
-                       GTK_STOCK_CANCEL, _("+_Filter"), NULL, TRUE, vbox);
-       if ((val & ~G_ALERTDISABLE) == G_ALERTDEFAULT) {
+                       GTK_STOCK_CANCEL, _("_Filter"), NULL, TRUE, G_ALERTALTERNATE, vbox);
+
+       if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE) {
                return FALSE;
        } else if (val & G_ALERTDISABLE)
                prefs_common.ask_apply_per_account_filtering_rules = FALSE;
@@ -4660,7 +5067,7 @@ void summary_filter(SummaryView *summaryview, gboolean selected_only)
        STATUSBAR_PUSH(summaryview->mainwin, _("Filtering..."));
        main_window_cursor_wait(summaryview->mainwin);
 
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
+       summary_freeze(summaryview);
 
        if (selected_only) {
                GList *cur;
@@ -4684,7 +5091,7 @@ void summary_filter(SummaryView *summaryview, gboolean selected_only)
        }
        g_slist_free(mlist);
 
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       summary_thaw(summaryview);
 
        folder_item_update_thaw();
        debug_print("done.\n");
@@ -4711,7 +5118,8 @@ static void summary_filter_func(MsgInfo *msginfo)
        if (hooks_invoke(MAIL_MANUAL_FILTERING_HOOKLIST, &mail_filtering_data))
                return;
 
-       filter_message_by_msginfo(filtering_rules, msginfo, NULL);
+       filter_message_by_msginfo(filtering_rules, msginfo, NULL,
+                       FILTERING_MANUALLY, NULL);
 }
 
 void summary_msginfo_filter_open(FolderItem * item, MsgInfo *msginfo,
@@ -4815,9 +5223,9 @@ void summary_set_colorlabel_color(GtkCTree *ctree, GtkCTreeNode *node,
                style->fg[GTK_STATE_NORMAL] = color;
                /* get the average of label color and selected fg color
                   for visibility */
-               style->fg[GTK_STATE_SELECTED].red   = (color.red   + ctree_style->fg[GTK_STATE_SELECTED].red  ) / 2;
-               style->fg[GTK_STATE_SELECTED].green = (color.green + ctree_style->fg[GTK_STATE_SELECTED].green) / 2;
-               style->fg[GTK_STATE_SELECTED].blue  = (color.blue  + ctree_style->fg[GTK_STATE_SELECTED].blue ) / 2;
+               style->fg[GTK_STATE_SELECTED].red   = (color.red   + 3*ctree_style->fg[GTK_STATE_SELECTED].red  ) / 4;
+               style->fg[GTK_STATE_SELECTED].green = (color.green + 3*ctree_style->fg[GTK_STATE_SELECTED].green) / 4;
+               style->fg[GTK_STATE_SELECTED].blue  = (color.blue  + 3*ctree_style->fg[GTK_STATE_SELECTED].blue ) / 4;
        }
 
        gtk_ctree_node_set_row_style(ctree, node, style);
@@ -4851,6 +5259,71 @@ void summary_set_colorlabel(SummaryView *summaryview, guint labelcolor,
        END_LONG_OPERATION(summaryview);
 }
 
+static gboolean summary_set_row_tag(SummaryView *summaryview, GtkCTreeNode *row, gboolean refresh, gboolean set, gint id)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       MsgInfo *msginfo;
+       gchar *tags_str = NULL;
+       msginfo = gtk_ctree_node_get_row_data(ctree, row);
+       g_return_val_if_fail(msginfo, FALSE);
+
+       procmsg_msginfo_update_tags(msginfo, set, id);
+       
+       
+       if (summaryview->col_state[summaryview->col_pos[S_COL_TAGS]].visible) {
+               tags_str = procmsg_msginfo_get_tags_str(msginfo);
+               gtk_ctree_node_set_text(ctree, row, 
+                               summaryview->col_pos[S_COL_TAGS],
+                               tags_str?tags_str:"-");
+               g_free(tags_str);
+       }
+
+       summary_set_row_marks(summaryview, row);
+       if (row == summaryview->displayed) {
+               return TRUE;
+       }
+       return FALSE;
+}
+
+void summary_set_tag(SummaryView *summaryview, gint tag_id,
+                           GtkWidget *widget)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GList *cur;
+       gboolean set = tag_id > 0;
+       gint real_id = set? tag_id:-tag_id;
+       gboolean froze = FALSE;
+       gboolean redisplay = FALSE;
+       START_LONG_OPERATION(summaryview, FALSE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next) {
+               redisplay |= summary_set_row_tag(summaryview,
+                                          GTK_CTREE_NODE(cur->data), FALSE, set, real_id);
+       }
+       END_LONG_OPERATION(summaryview);
+       if (redisplay)
+               summary_redisplay_msg(summaryview);
+}
+
+static void summary_tags_menu_item_activate_cb(GtkWidget *widget,
+                                                    gpointer data)
+{
+       gint id = GPOINTER_TO_INT(data);
+       gboolean set = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+       SummaryView *summaryview;
+
+       summaryview = g_object_get_data(G_OBJECT(widget), "summaryview");
+       g_return_if_fail(summaryview != NULL);
+
+       /* "dont_toggle" state set? */
+       if (g_object_get_data(G_OBJECT(summaryview->tags_menu),
+                               "dont_toggle"))
+               return;
+
+       if (!set)
+               id = -id;
+       summary_set_tag(summaryview, id, NULL);
+}
+
 static void summary_colorlabel_menu_item_activate_item_cb(GtkMenuItem *menu_item,
                                                          gpointer data)
 {
@@ -4968,6 +5441,176 @@ static void summary_colorlabel_menu_create(SummaryView *summaryview, gboolean re
        summaryview->colorlabel_menu = menu;
 }
 
+static void summary_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
+                                                         gpointer data)
+{
+       GtkMenuShell *menu;
+       GList *cur;
+       GList *sel;
+       GHashTable *menu_table = g_hash_table_new_full(
+                                       g_direct_hash,
+                                       g_direct_equal,
+                                       NULL, NULL);
+       GHashTable *menu_allsel_table = g_hash_table_new_full(
+                                       g_direct_hash,
+                                       g_direct_equal,
+                                       NULL, NULL);
+       gint sel_len;
+       SummaryView *summaryview = (SummaryView *)data;
+       g_return_if_fail(summaryview != NULL);
+
+       sel = GTK_CLIST(summaryview->ctree)->selection;
+       if (!sel) return;
+
+       menu = GTK_MENU_SHELL(summaryview->tags_menu);
+       g_return_if_fail(menu != NULL);
+
+       /* NOTE: don't return prematurely because we set the "dont_toggle"
+        * state for check menu items */
+       g_object_set_data(G_OBJECT(menu), "dont_toggle",
+                         GINT_TO_POINTER(1));
+
+       /* clear items. get item pointers. */
+       for (cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
+               if (GTK_IS_CHECK_MENU_ITEM(cur->data)) {
+                       gint id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cur->data),
+                               "tag_id"));
+                       gtk_check_menu_item_set_active
+                               (GTK_CHECK_MENU_ITEM(cur->data), FALSE);
+                               
+                       g_hash_table_insert(menu_table, GINT_TO_POINTER(id), GTK_CHECK_MENU_ITEM(cur->data));
+                       g_hash_table_insert(menu_allsel_table, GINT_TO_POINTER(id), GINT_TO_POINTER(0));
+               }
+       }
+
+       /* iterate all messages and set the state of the appropriate
+        * items */
+       sel_len = 0;
+       for (; sel != NULL; sel = sel->next) {
+               MsgInfo *msginfo;
+               GSList *tags = NULL;
+               gint id;
+               GtkCheckMenuItem *item;
+               msginfo = gtk_ctree_node_get_row_data
+                       (GTK_CTREE(summaryview->ctree),
+                        GTK_CTREE_NODE(sel->data));
+               sel_len++;
+               if (msginfo) {
+                       tags =  msginfo->tags;
+                       if (!tags)
+                               continue;
+
+                       for (; tags; tags = tags->next) {
+                               gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, tags->data));
+                               id = GPOINTER_TO_INT(tags->data);
+                               item = g_hash_table_lookup(menu_table, GINT_TO_POINTER(tags->data));
+                               if (item && !item->active) {
+                                       gtk_check_menu_item_set_active
+                                               (item, TRUE);
+                               }
+                               num_checked++;
+                               g_hash_table_replace(menu_allsel_table, tags->data, GINT_TO_POINTER(num_checked));
+                       }
+               }
+       }
+
+       for (cur = menu->children; cur != NULL && cur->data != NULL; cur = cur->next) {
+               if (GTK_IS_CHECK_MENU_ITEM(cur->data)) {
+                       gint id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cur->data),
+                               "tag_id"));
+                       gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, GINT_TO_POINTER(id)));
+                       if (num_checked < sel_len && num_checked > 0)
+                               gtk_check_menu_item_set_inconsistent(GTK_CHECK_MENU_ITEM(cur->data), TRUE);
+                       else
+                               gtk_check_menu_item_set_inconsistent(GTK_CHECK_MENU_ITEM(cur->data), FALSE);
+               }
+       }
+       g_hash_table_destroy(menu_table);
+       g_hash_table_destroy(menu_allsel_table);
+       /* reset "dont_toggle" state */
+       g_object_set_data(G_OBJECT(menu), "dont_toggle",
+                         GINT_TO_POINTER(0));
+
+}
+
+static void summary_tags_menu_item_apply_tags_activate_cb(GtkWidget *widget,
+                                                    gpointer data)
+{
+       SummaryView *summaryview;
+
+       summaryview = g_object_get_data(G_OBJECT(widget), "summaryview");
+       g_return_if_fail(summaryview != NULL);
+
+       /* "dont_toggle" state set? */
+       if (g_object_get_data(G_OBJECT(summaryview->tags_menu),
+                               "dont_toggle"))
+               return;
+       
+       tag_apply_open(summary_get_selection(summaryview));     
+}
+
+static void summary_tags_menu_create(SummaryView *summaryview, gboolean refresh)
+{
+       GtkWidget *label_menuitem;
+       GtkWidget *menu;
+       GtkWidget *item;
+       GSList *cur = tags_get_list();
+       GSList *orig = cur;
+       gboolean existing_tags = FALSE;
+
+       label_menuitem = gtk_item_factory_get_item(summaryview->popupfactory,
+                                                  "/Tags");
+       g_signal_connect(G_OBJECT(label_menuitem), "activate",
+                        G_CALLBACK(summary_tags_menu_item_activate_item_cb),
+                          summaryview);
+
+       gtk_widget_show(label_menuitem);
+
+       menu = gtk_menu_new();
+
+       /* create tags menu items */
+       for (; cur; cur = cur->next) {
+               gint id = GPOINTER_TO_INT(cur->data);
+               const gchar *tag = tags_get_tag(id);
+
+               item = gtk_check_menu_item_new_with_label(tag);
+               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+               g_signal_connect(G_OBJECT(item), "activate",
+                                G_CALLBACK(summary_tags_menu_item_activate_cb),
+                                GINT_TO_POINTER(id));
+               g_object_set_data(G_OBJECT(item), "summaryview",
+                                 summaryview);
+               g_object_set_data(G_OBJECT(item), "tag_id",
+                                 GINT_TO_POINTER(id));
+               gtk_widget_show(item);
+               existing_tags = TRUE;
+       }
+       if (existing_tags) {
+               /* separator */
+               item = gtk_menu_item_new();
+               gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+               gtk_widget_show(item);
+       }
+
+       item = gtk_menu_item_new_with_label(_("Apply tags..."));
+       gtk_widget_add_accelerator(item, "activate", 
+                  summaryview->popupfactory->accel_group, 
+                  GDK_T, GDK_CONTROL_MASK|GDK_SHIFT_MASK,
+                  GTK_ACCEL_LOCKED | GTK_ACCEL_VISIBLE);
+       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       g_signal_connect(G_OBJECT(item), "activate",
+                        G_CALLBACK(summary_tags_menu_item_apply_tags_activate_cb),
+                        NULL);
+       g_object_set_data(G_OBJECT(item), "summaryview",
+                         summaryview);
+       gtk_widget_show(item);
+
+       g_slist_free(orig);
+       gtk_widget_show(menu);
+       gtk_menu_item_set_submenu(GTK_MENU_ITEM(label_menuitem), menu);
+       summaryview->tags_menu = menu;
+}
+
 static gboolean summary_popup_menu(GtkWidget *widget, gpointer data)
 {
        SummaryView *summaryview = (SummaryView *)data;
@@ -5001,6 +5644,9 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
        ctree = gtk_sctree_new_with_titles
                (N_SUMMARY_COLS, col_pos[S_COL_SUBJECT], titles);
 
+       if (prefs_common.show_col_headers == FALSE)
+               gtk_clist_column_titles_hide(GTK_CLIST(ctree));
+
        gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_EXTENDED);
        gtk_clist_set_column_justification(GTK_CLIST(ctree), col_pos[S_COL_MARK],
                                           GTK_JUSTIFY_CENTER);
@@ -5038,6 +5684,8 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
                                   prefs_common.summary_col_size[S_COL_NUMBER]);
        gtk_clist_set_column_width(GTK_CLIST(ctree), col_pos[S_COL_SCORE],
                                   prefs_common.summary_col_size[S_COL_SCORE]);
+       gtk_clist_set_column_width(GTK_CLIST(ctree), col_pos[S_COL_TAGS],
+                                  prefs_common.summary_col_size[S_COL_TAGS]);
 
        if (prefs_common.enable_dotted_lines) {
                gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_DOTTED);
@@ -5080,6 +5728,7 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
        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);
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TAGS,    summary_tags_clicked);
 
 #undef CLIST_BUTTON_SIGNAL_CONNECT
 
@@ -5090,8 +5739,15 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
        g_signal_connect(G_OBJECT(ctree), "button_press_event",
                         G_CALLBACK(summary_button_pressed),
                         summaryview);
+#ifndef MAEMO
        g_signal_connect(G_OBJECT(ctree), "popup-menu",
                         G_CALLBACK(summary_popup_menu), summaryview);
+#else
+       gtk_widget_tap_and_hold_setup(GTK_WIDGET(ctree), NULL, NULL,
+                       GTK_TAP_AND_HOLD_NONE | GTK_TAP_AND_HOLD_NO_INTERNALS);
+       g_signal_connect(G_OBJECT(ctree), "tap-and-hold",
+                        G_CALLBACK(summary_popup_menu), summaryview);
+#endif
        g_signal_connect(G_OBJECT(ctree), "button_release_event",
                         G_CALLBACK(summary_button_released),
                         summaryview);
@@ -5115,6 +5771,9 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
        g_signal_connect(G_OBJECT(ctree), "drag_data_get",
                         G_CALLBACK(summary_drag_data_get),
                         summaryview);
+       g_signal_connect(G_OBJECT(ctree), "drag_end",
+                        G_CALLBACK(summary_drag_end),
+                        summaryview);
 
        gtk_drag_dest_set(ctree, GTK_DEST_DEFAULT_ALL & ~GTK_DEST_DEFAULT_HIGHLIGHT,
                          summary_drag_types, 2,
@@ -5169,6 +5828,16 @@ void summary_set_column_order(SummaryView *summaryview)
 
 /* callback functions */
 
+static gint summary_folder_eventbox_pressed(GtkWidget *eventbox, GdkEventButton *event,
+                                           SummaryView *summaryview)
+{
+       if (event) {
+               gtk_widget_grab_focus(summaryview->folderview->ctree);
+               mainwindow_exit_folder(summaryview->mainwin);
+       }
+       return TRUE;
+}
+
 static gint summary_toggle_pressed(GtkWidget *eventbox, GdkEventButton *event,
                                   SummaryView *summaryview)
 {
@@ -5176,7 +5845,14 @@ static gint summary_toggle_pressed(GtkWidget *eventbox, GdkEventButton *event,
                summary_toggle_view(summaryview);
        return TRUE;
 }
-
+#ifdef MAEMO
+static void summary_toggle_multiple_pressed(GtkWidget *widget,
+                                  SummaryView *summaryview)
+{
+       GTK_SCTREE(summaryview->ctree)->force_additive_sel = 
+               gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+}
+#endif
 static gboolean summary_button_pressed(GtkWidget *ctree, GdkEventButton *event,
                                       SummaryView *summaryview)
 {
@@ -5239,6 +5915,8 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                switch (event->keyval) {
                case GDK_space:         /* Page down or go to the next */
                        handled = TRUE;
+                       if (event->state & GDK_CONTROL_MASK) 
+                               event->state &= ~GDK_CONTROL_MASK;
                        if (event->state & GDK_SHIFT_MASK) 
                                mimeview_scroll_page(messageview->mimeview, TRUE);
                        else {
@@ -5261,6 +5939,7 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                        mimeview_scroll_page(messageview->mimeview, TRUE);
                        break;
                case GDK_Return:        /* Scroll up/down one line */
+               case GDK_KP_Enter:
                        handled = TRUE;
                        if (summaryview->displayed != summaryview->selected) {
                                summary_display_msg(summaryview,
@@ -5286,6 +5965,7 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                /* FALLTHROUGH */       
        case GDK_Escape:
                gtk_widget_grab_focus(summaryview->folderview->ctree);
+               mainwindow_exit_folder(summaryview->mainwin);
                return TRUE;
        case GDK_Home:
        case GDK_End:
@@ -5326,7 +6006,9 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
        case GDK_y:
        case GDK_t:
        case GDK_l:
+       case GDK_o:
        case GDK_c:
+       case GDK_a:
                if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) == 0) {
                        g_signal_stop_emission_by_name(G_OBJECT(widget), 
                                        "key_press_event");
@@ -5360,15 +6042,21 @@ static void tog_searchbar_cb(GtkWidget *w, gpointer data)
        }
 }
 
-void summaryview_activate_quicksearch(SummaryView *summaryview) 
+void summaryview_activate_quicksearch(SummaryView *summaryview, gboolean show
 {
+       prefs_common.show_searchbar = show;
        gtk_toggle_button_set_active(
                GTK_TOGGLE_BUTTON(summaryview->toggle_search), 
-               TRUE);
-       quicksearch_show(summaryview->quicksearch);
+               show);
+       if (show) {
+               quicksearch_show(summaryview->quicksearch);
+       } else {
+               quicksearch_hide(summaryview->quicksearch);
+               summary_grab_focus(summaryview);
+       }
 }
 
-static void summary_open_row(GtkSCTree *sctree, SummaryView *summaryview)
+void summary_open_row(GtkSCTree *sctree, SummaryView *summaryview)
 {
        if (FOLDER_SHOWS_TO_HDR(summaryview->folder_item))
                summary_reedit(summaryview);
@@ -5417,6 +6105,7 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
 
        if (summary_is_locked(summaryview)
        && !GTK_SCTREE(ctree)->selecting_range
+       && summaryview->messageview
        && summaryview->messageview->mimeview
        && summaryview->messageview->mimeview->type == MIMEVIEW_TEXT
        && summaryview->messageview->mimeview->textview->loading) {
@@ -5477,7 +6166,7 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
                                if (procmsg_spam_learner_learn(msginfo, NULL, FALSE) == 0)
                                        summary_msginfo_unset_flags(msginfo, MSG_SPAM, 0);
                                else
-                                       log_error(_("An error happened while learning.\n"));
+                                       log_error(LOG_PROTOCOL, _("An error happened while learning.\n"));
                } else if (!MSG_IS_REPLIED(msginfo->flags) &&
                         !MSG_IS_FORWARDED(msginfo->flags)) {
                        marked_unread = TRUE;
@@ -5611,7 +6300,7 @@ static void summary_sort_by_column_click(SummaryView *summaryview,
 
        node = GTK_CTREE_NODE(GTK_CLIST(summaryview->ctree)->row_list);
 
-       gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
+       summary_freeze(summaryview);
        if (prefs_common.bold_unread) {
                while (node) {
                        GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
@@ -5620,7 +6309,7 @@ static void summary_sort_by_column_click(SummaryView *summaryview,
                        node = next;
                }
        }
-       gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+       summary_thaw(summaryview);
        END_TIMING();
 }
 
@@ -5688,6 +6377,12 @@ static void summary_locked_clicked(GtkWidget *button,
        summary_sort_by_column_click(summaryview, SORT_BY_LOCKED);
 }
 
+static void summary_tags_clicked(GtkWidget *button,
+                                  SummaryView *summaryview)
+{
+       summary_sort_by_column_click(summaryview, SORT_BY_TAGS);
+}
+
 static void summary_start_drag(GtkWidget *widget, gint button, GdkEvent *event,
                               SummaryView *summaryview)
 {
@@ -5701,6 +6396,28 @@ static void summary_start_drag(GtkWidget *widget, gint button, GdkEvent *event,
        context = gtk_drag_begin(widget, summaryview->target_list,
                                 GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_DEFAULT, button, event);
        gtk_drag_set_icon_default(context);
+       if (prefs_common.layout_mode == SMALL_LAYOUT) {
+               GtkWidget *paned = GTK_WIDGET_PTR(summaryview)->parent;
+               if (paned && GTK_IS_PANED(paned)) {
+                       mainwindow_reset_paned(GTK_PANED(paned));
+               }
+       }
+}
+
+static gboolean summary_return_to_list(void *data)
+{
+       SummaryView *summaryview = (SummaryView *)data;
+       mainwindow_enter_folder(summaryview->mainwin);
+       return FALSE;
+}
+
+static void summary_drag_end      (GtkWidget       *widget, 
+                                  GdkDragContext   *drag_context,
+                                   SummaryView             *summaryview)
+{
+       if (prefs_common.layout_mode == SMALL_LAYOUT) {
+               g_timeout_add(250, summary_return_to_list, summaryview);
+       }
 }
 
 static void summary_drag_data_get(GtkWidget        *widget,
@@ -5833,7 +6550,8 @@ static gint func_name(GtkCList *clist,                                     \
 CMP_FUNC_DEF(summary_cmp_by_mark,
             MSG_IS_MARKED(msginfo1->flags) - MSG_IS_MARKED(msginfo2->flags))
 CMP_FUNC_DEF(summary_cmp_by_status,
-            MSG_IS_UNREAD(msginfo1->flags) - MSG_IS_UNREAD(msginfo2->flags))
+            (-(MSG_IS_SPAM(msginfo1->flags))+(MSG_IS_UNREAD(msginfo1->flags)<<1)+(MSG_IS_NEW(msginfo1->flags)<<2)) 
+            - (-(MSG_IS_SPAM(msginfo2->flags))+(MSG_IS_UNREAD(msginfo2->flags)<<1)+(MSG_IS_NEW(msginfo2->flags)<<2)) )
 CMP_FUNC_DEF(summary_cmp_by_mime,
             MSG_IS_WITH_ATTACHMENT(msginfo1->flags) - MSG_IS_WITH_ATTACHMENT(msginfo2->flags))
 CMP_FUNC_DEF(summary_cmp_by_label,
@@ -5864,6 +6582,20 @@ static gint summary_cmp_by_subject(GtkCList *clist,
                (msginfo1->subject, msginfo2->subject);
 }
 
+static gint summary_cmp_by_thread_date(GtkCList *clist,
+                                  gconstpointer ptr1,
+                                  gconstpointer ptr2)
+{
+       MsgInfo *msginfo1 = ((GtkCListRow *)ptr1)->data;
+       MsgInfo *msginfo2 = ((GtkCListRow *)ptr2)->data;
+       gint thread_diff = msginfo1->thread_date - msginfo2->thread_date;
+       
+       if (msginfo1->thread_date > 0 && msginfo2->thread_date > 0)
+               return thread_diff;
+       else 
+               return msginfo1->date_t - msginfo2->date_t;
+}
+
 static gint summary_cmp_by_from(GtkCList *clist, gconstpointer ptr1,
                                gconstpointer ptr2)
 {
@@ -5908,6 +6640,29 @@ static gint summary_cmp_by_to(GtkCList *clist, gconstpointer ptr1,
        return g_utf8_collate(str1, str2);
 }
  
+static gint summary_cmp_by_tags(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");
+       gint res;
+       g_return_val_if_fail(sv, -1);
+       
+       str1 = GTK_CELL_TEXT(r1->cell[sv->col_pos[S_COL_TAGS]])->text;
+       str2 = GTK_CELL_TEXT(r2->cell[sv->col_pos[S_COL_TAGS]])->text;
+
+       if (!str1)
+               return str2 != NULL;
+       if (!str2)
+               return -1;
+       res = g_utf8_collate(str1, str2);
+       return (res != 0)? res: summary_cmp_by_date(clist, ptr1, ptr2);
+}
 static gint summary_cmp_by_simplified_subject
        (GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
 {
@@ -5964,6 +6719,7 @@ static void summary_ignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpoin
        msginfo = gtk_ctree_node_get_row_data(ctree, row);
        g_return_if_fail(msginfo);
 
+       summary_msginfo_unset_flags(msginfo, MSG_WATCH_THREAD, 0);
        summary_msginfo_change_flags(msginfo, MSG_IGNORE_THREAD, 0, MSG_NEW | MSG_UNREAD, 0);
 
        summary_set_row_marks(summaryview, row);
@@ -6050,6 +6806,100 @@ void summary_toggle_ignore_thread(SummaryView *summaryview)
                summary_ignore_thread(summaryview);
 }
 
+static void summary_watch_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpointer data)
+{
+       SummaryView *summaryview = (SummaryView *) data;
+       MsgInfo *msginfo;
+
+       msginfo = gtk_ctree_node_get_row_data(ctree, row);
+       g_return_if_fail(msginfo);
+
+       summary_msginfo_change_flags(msginfo, MSG_WATCH_THREAD, 0, MSG_IGNORE_THREAD, 0);
+
+       summary_set_row_marks(summaryview, row);
+       debug_print("Message %d is marked as watch thread\n",
+           msginfo->msgnum);
+}
+
+void summary_watch_thread(SummaryView *summaryview)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GList *cur;
+       gboolean froze = FALSE;
+
+       START_LONG_OPERATION(summaryview, FALSE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+               gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data), 
+                                       GTK_CTREE_FUNC(summary_watch_thread_func), 
+                                       summaryview);
+
+       END_LONG_OPERATION(summaryview);
+
+       summary_status_show(summaryview);
+}
+
+static void summary_unwatch_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpointer data)
+{
+       SummaryView *summaryview = (SummaryView *) data;
+       MsgInfo *msginfo;
+
+       msginfo = gtk_ctree_node_get_row_data(ctree, row);
+       g_return_if_fail(msginfo);
+
+       summary_msginfo_unset_flags(msginfo, MSG_WATCH_THREAD, 0);
+
+       summary_set_row_marks(summaryview, row);
+       debug_print("Message %d is marked as unwatch thread\n",
+           msginfo->msgnum);
+}
+
+void summary_unwatch_thread(SummaryView *summaryview)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GList *cur;
+       gboolean froze = FALSE;
+
+       START_LONG_OPERATION(summaryview, FALSE);
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+               gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data), 
+                                       GTK_CTREE_FUNC(summary_unwatch_thread_func), 
+                                       summaryview);
+
+       END_LONG_OPERATION(summaryview);
+
+       summary_status_show(summaryview);
+}
+
+static void summary_check_watch_thread_func
+               (GtkCTree *ctree, GtkCTreeNode *row, gpointer data)
+{
+       MsgInfo *msginfo;
+       gint *found_watch = (gint *) data;
+
+       if (*found_watch) return;
+       else {
+               msginfo = gtk_ctree_node_get_row_data(ctree, row);
+               *found_watch = msginfo && MSG_IS_WATCH_THREAD(msginfo->flags);
+       }               
+}
+
+void summary_toggle_watch_thread(SummaryView *summaryview)
+{
+       GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+       GList *cur;
+       gint found_watch = 0;
+
+       for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+               gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data),
+                                       GTK_CTREE_FUNC(summary_check_watch_thread_func),
+                                       &found_watch);
+
+       if (found_watch) 
+               summary_unwatch_thread(summaryview);
+       else 
+               summary_watch_thread(summaryview);
+}
+
 void summary_toggle_show_read_messages(SummaryView *summaryview)
 {
        FolderItemUpdateData source;
@@ -6084,8 +6934,6 @@ void summary_reflect_prefs_pixmap_theme(SummaryView *summaryview)
        GtkWidget *ctree = summaryview->ctree;
        GtkWidget *pixmap; 
 
-       gtk_widget_destroy(summaryview->folder_pixmap);
-
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_MARK, &markxpm, &markxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_DELETED, &deletedxpm, &deletedxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_NEW, &newxpm, &newxpmmask);
@@ -6095,6 +6943,7 @@ void summary_reflect_prefs_pixmap_theme(SummaryView *summaryview)
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_CLIP, &clipxpm, &clipxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_LOCKED, &lockedxpm, &lockedxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_IGNORETHREAD, &ignorethreadxpm, &ignorethreadxpmmask);
+       stock_pixmap_gdk(ctree, STOCK_PIXMAP_WATCHTHREAD, &watchthreadxpm, &watchthreadxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_CLIP_KEY, &clipkeyxpm, &clipkeyxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_KEY, &keyxpm, &keyxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_GPG_SIGNED, &gpgsignedxpm, &gpgsignedxpmmask);
@@ -6103,11 +6952,7 @@ void summary_reflect_prefs_pixmap_theme(SummaryView *summaryview)
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_MOVED, &movedxpm, &movedxpmmask);
        stock_pixmap_gdk(ctree, STOCK_PIXMAP_COPIED, &copiedxpm, &copiedxpmmask);
 
-       pixmap = stock_pixmap_widget(summaryview->hbox, STOCK_PIXMAP_DIR_OPEN);
-       gtk_box_pack_start(GTK_BOX(summaryview->hbox), pixmap, FALSE, FALSE, 4);
-       gtk_box_reorder_child(GTK_BOX(summaryview->hbox), pixmap, 1); /* search_toggle before */
-       gtk_widget_show(pixmap);
-       summaryview->folder_pixmap = pixmap; 
+       summary_set_folder_pixmap(summaryview, STOCK_PIXMAP_DIR_OPEN);
 
        pixmap = stock_pixmap_widget(summaryview->hbox, STOCK_PIXMAP_QUICKSEARCH);
        gtk_container_remove (GTK_CONTAINER(summaryview->toggle_search), 
@@ -6116,6 +6961,15 @@ void summary_reflect_prefs_pixmap_theme(SummaryView *summaryview)
        gtk_widget_show(pixmap);
        summaryview->quick_search_pixmap = pixmap;
 
+#ifdef MAEMO
+       pixmap = stock_pixmap_widget(summaryview->hbox, STOCK_PIXMAP_SELECTION);
+       gtk_container_remove (GTK_CONTAINER(summaryview->multiple_sel_togbtn), 
+                             summaryview->multiple_sel_image);
+       gtk_container_add(GTK_CONTAINER(summaryview->multiple_sel_togbtn), pixmap);
+       gtk_widget_show(pixmap);
+       summaryview->multiple_sel_togbtn = pixmap;
+#endif
+
        folderview_unselect(summaryview->folderview);
        folderview_select(summaryview->folderview, summaryview->folder_item);
        summary_set_column_titles(summaryview);
@@ -6180,6 +7034,8 @@ static regex_t *summary_compile_simplify_regexp(gchar *simplify_subject_regexp)
 
 void summary_set_prefs_from_folderitem(SummaryView *summaryview, FolderItem *item)
 {
+       FolderSortKey sort_key;
+       FolderSortType sort_type;
        g_return_if_fail(summaryview != NULL);
        g_return_if_fail(item != NULL);
 
@@ -6194,8 +7050,13 @@ void summary_set_prefs_from_folderitem(SummaryView *summaryview, FolderItem *ite
                summaryview->simplify_subject_preg = summary_compile_simplify_regexp(item->prefs->simplify_subject_regexp);
 
        /* Sorting */
-       summaryview->sort_key = item->sort_key;
-       summaryview->sort_type = item->sort_type;
+       sort_key = item->sort_key;
+       sort_type = item->sort_type;
+
+       folder_get_sort_type(item->folder, &sort_key, &sort_type);
+
+       summaryview->sort_key = sort_key;
+       summaryview->sort_type = sort_type;
 
        /* Threading */
        summaryview->threaded = item->threaded;
@@ -6239,7 +7100,44 @@ static gboolean summary_update_msg(gpointer source, gpointer data)
        return FALSE;
 }
 
-static gboolean summary_update_folder_item_name(gpointer source, gpointer data)
+void summary_update_unread(SummaryView *summaryview, FolderItem *removed_item)
+{
+       guint new, unread, unreadmarked, marked, total;
+       static gboolean tips_initialized = FALSE;
+
+       if (prefs_common.layout_mode != SMALL_LAYOUT) {
+               if (tips_initialized) {
+                       summary_set_folder_pixmap(summaryview, STOCK_PIXMAP_DIR_OPEN);
+                       gtk_tooltips_set_tip(GTK_TOOLTIPS(summaryview->tips),
+                            summaryview->folder_pixmap_eventbox,
+                            NULL, NULL);
+                       tips_initialized = FALSE;
+               } 
+               return;
+       }
+       folder_count_total_msgs(&new, &unread, &unreadmarked, &marked, &total);
+       if (removed_item) {
+               total -= removed_item->total_msgs;
+               new -= removed_item->new_msgs;
+               unread -= removed_item->unread_msgs;
+       }
+       
+       if (new > 0 || unread > 0) {
+               tips_initialized = TRUE;
+               summary_set_folder_pixmap(summaryview, STOCK_PIXMAP_DIR_OPEN_HRM);
+               gtk_tooltips_set_tip(GTK_TOOLTIPS(summaryview->tips),
+                            summaryview->folder_pixmap_eventbox,
+                            _("Go back to the folder list (You have unread messages)"), NULL);
+       } else {
+               tips_initialized = TRUE;
+               summary_set_folder_pixmap(summaryview, STOCK_PIXMAP_DIR_OPEN);
+               gtk_tooltips_set_tip(GTK_TOOLTIPS(summaryview->tips),
+                            summaryview->folder_pixmap_eventbox,
+                            _("Go back to the folder list"), NULL);
+       }
+}
+
+static gboolean summary_update_folder_item_hook(gpointer source, gpointer data)
 {
        FolderItemUpdateData *hookdata = (FolderItemUpdateData *)source;
        SummaryView *summaryview = (SummaryView *)data;
@@ -6253,6 +7151,20 @@ static gboolean summary_update_folder_item_name(gpointer source, gpointer data)
                gtk_label_set_text(GTK_LABEL(summaryview->statlabel_folder), name);
                g_free(name);
        }
+       summary_update_unread(summaryview, NULL);
+
+       return FALSE;
+}
+
+static gboolean summary_update_folder_hook(gpointer source, gpointer data)
+{
+       FolderUpdateData *hookdata;
+       SummaryView *summaryview = (SummaryView *)data;
+       hookdata = source;
+       if (hookdata->update_flags & FOLDER_REMOVE_FOLDERITEM)
+               summary_update_unread(summaryview, hookdata->item);
+       else
+               summary_update_unread(summaryview, NULL);
 
        return FALSE;
 }