2007-06-12 [colin] 2.9.2cvs57
[claws.git] / src / summaryview.c
index 6d1c07966caefadce11e848683d7879822d302f2..554a5c827b5acb02fcec31dbc49f469359c7b844 100644 (file)
@@ -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"
@@ -256,6 +257,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 +275,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);
@@ -351,7 +359,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,
@@ -404,7 +414,8 @@ 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] =
 {
@@ -559,10 +570,12 @@ SummaryView *summary_create(void)
        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;
@@ -570,6 +583,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);
        
@@ -586,13 +600,12 @@ SummaryView *summary_create(void)
        stat_box2 = gtk_hbox_new(FALSE, 0);
        gtk_widget_show(stat_box2);
        
-       search_tip = gtk_tooltips_new();
        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);
        
@@ -616,14 +629,27 @@ 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);
@@ -638,7 +664,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);
@@ -660,6 +688,9 @@ SummaryView *summary_create(void)
        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",
@@ -685,6 +716,9 @@ SummaryView *summary_create(void)
        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;
@@ -693,7 +727,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);
@@ -713,7 +751,8 @@ SummaryView *summary_create(void)
        else
                quicksearch_hide(quicksearch);
        
-       if (prefs_common.layout_mode == WIDE_MSGLIST_LAYOUT)
+       if (prefs_common.layout_mode == WIDE_MSGLIST_LAYOUT ||
+           prefs_common.layout_mode == SMALL_LAYOUT)
                gtk_widget_hide(summaryview->toggle_eventbox);
 
        return summaryview;
@@ -737,17 +776,23 @@ void summary_relayout(SummaryView *summaryview)
                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)
+               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);
-               gtk_widget_show(summaryview->toggle_eventbox);
+               if (prefs_common.layout_mode == SMALL_LAYOUT)
+                       gtk_widget_hide(summaryview->toggle_eventbox);
+               else
+                       gtk_widget_show(summaryview->toggle_eventbox);
+                       
                break;
        }
        gtk_widget_unref(summaryview->hbox_l);
@@ -790,9 +835,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;
@@ -833,16 +900,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;
@@ -994,9 +1064,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)
@@ -1237,79 +1313,64 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                        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);
@@ -1452,26 +1513,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;
@@ -2403,10 +2444,10 @@ static void summary_set_column_titles(SummaryView *summaryview)
                                        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]);
@@ -2583,7 +2624,7 @@ unlock:
        END_TIMING();
 }
 
-gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
+static gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
                                   GtkCTreeNode *cnode, gpointer data)
 {
        SummaryView *summaryview = (SummaryView *)data;
@@ -2639,7 +2680,7 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
        
        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();
@@ -3022,7 +3063,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);
@@ -3037,7 +3078,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);
@@ -3045,18 +3086,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)) {
@@ -3121,6 +3177,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)
@@ -3191,6 +3251,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,
@@ -3564,8 +3626,9 @@ 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 {
@@ -3576,7 +3639,7 @@ void summary_mark_as_spam(SummaryView *summaryview, guint action, GtkWidget *wid
                        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;
@@ -3762,9 +3825,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;
        }
 
@@ -4074,22 +4147,28 @@ void summary_unselect_all(SummaryView *summaryview)
 void summary_select_thread(SummaryView *summaryview, gboolean delete_thread)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-       GtkCTreeNode *node = summaryview->selected;
+       GtkCTreeNode *node = NULL;
        gboolean froze = FALSE;
+       GList *cur = NULL;
+       GList *copy = NULL;
+       if (!GTK_CLIST(summaryview->ctree)->selection) 
+               return;
 
-       if (!node) return;
-
-       while (GTK_CTREE_ROW(node)->parent != NULL)
-               node = GTK_CTREE_ROW(node)->parent;
 
        START_LONG_OPERATION(summaryview, FALSE);
-       if (node != summaryview->selected)
-               summary_select_node
-                       (summaryview, node,
-                        messageview_is_visible(summaryview->messageview),
-                        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)
@@ -4097,7 +4176,6 @@ void summary_select_thread(SummaryView *summaryview, gboolean delete_thread)
                else
                        summary_delete_trash(summaryview);
        }
-       END_LONG_OPERATION(summaryview);
        summary_status_show(summaryview);
 }
 
@@ -4119,14 +4197,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);
@@ -4692,12 +4769,12 @@ void summary_collapse_threads(SummaryView *summaryview)
        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 */
 {
@@ -4752,8 +4829,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;
@@ -4833,7 +4911,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,
@@ -5212,8 +5291,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);
@@ -5237,6 +5323,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,
@@ -5291,6 +5380,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)
 {
@@ -5298,7 +5397,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)
 {
@@ -5410,6 +5516,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:
@@ -5451,6 +5558,7 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
        case GDK_t:
        case GDK_l:
        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");
@@ -5494,10 +5602,11 @@ void summaryview_activate_quicksearch(SummaryView *summaryview, gboolean 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);
@@ -5546,6 +5655,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) {
@@ -5606,7 +5716,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;
@@ -5830,6 +5940,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,
@@ -5962,7 +6094,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,
@@ -6213,8 +6346,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);
@@ -6232,11 +6363,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), 
@@ -6245,6 +6372,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);
@@ -6375,7 +6511,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;
@@ -6389,6 +6562,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;
 }