Show header pane only when enabled
[claws.git] / src / messageview.c
index 4dead34e1cd690347ad7bb7dce17918372c4f27c..f822909b9078be76c71074e0ad7b785edc5a1eee 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2013 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
@@ -39,7 +39,6 @@
 #include "filesel.h"
 #include "foldersel.h"
 #include "sourcewindow.h"
-#include "addressbook.h"
 #include "alertpanel.h"
 #include "inputdialog.h"
 #include "mainwindow.h"
 #include "hooks.h"
 #include "filtering.h"
 #include "partial_download.h"
-#include "gedit-print.h"
 #include "uri_opener.h"
 #include "inc.h"
 #include "log.h"
+#include "privacy.h"
 #include "combobox.h"
 #include "printing.h"
 #include "quoted-printable.h"
 #include "version.h"
 #include "statusbar.h"
-
+#include "folder_item_prefs.h"
+#include "avatars.h"
+#ifndef USE_NEW_ADDRBOOK
+       #include "addressbook.h"
+#else
+       #include "addressadd.h"
+       #include "addressbook-dbus.h"
+#endif
 static GList *messageview_list = NULL;
 
 static gint messageview_delete_cb      (GtkWidget              *widget,
@@ -75,11 +81,9 @@ static gint messageview_delete_cb    (GtkWidget              *widget,
                                         MessageView            *messageview);
 static void messageview_size_allocate_cb(GtkWidget     *widget,
                                         GtkAllocation  *allocation);
-#ifndef MAEMO
 static gboolean key_pressed            (GtkWidget      *widget,
                                         GdkEventKey    *event,
                                         MessageView    *messageview);
-#endif
 static void return_receipt_show                (NoticeView     *noticeview, 
                                         MsgInfo        *msginfo);      
 static void return_receipt_send_clicked (NoticeView    *noticeview, 
@@ -94,10 +98,8 @@ static void partial_recv_unmark_clicked (NoticeView  *noticeview,
                                          MsgInfo        *msginfo);
 static void save_as_cb                 (GtkAction      *action,
                                         gpointer        data);
-#if GTK_CHECK_VERSION(2,10,0) && !defined(USE_GNOMEPRINT)
 static void page_setup_cb              (GtkAction      *action,
                                         gpointer        data);
-#endif
 static void print_cb                   (GtkAction      *action,
                                         gpointer        data);
 static void close_cb                   (GtkAction      *action,
@@ -129,7 +131,9 @@ static void prev_labeled_cb         (GtkAction      *action,
                                         gpointer        data);
 static void next_labeled_cb            (GtkAction      *action,
                                         gpointer        data);
-static void last_read_cb               (GtkAction      *action,
+static void prev_history_cb            (GtkAction      *action,
+                                        gpointer        data);
+static void next_history_cb            (GtkAction      *action,
                                         gpointer        data);
 static void parent_cb                  (GtkAction      *action,
                                         gpointer        data);
@@ -138,6 +142,15 @@ static void goto_unread_folder_cb  (GtkAction      *action,
 static void goto_folder_cb             (GtkAction      *action,
                                         gpointer        data);
 
+static void scroll_prev_line_cb         (GtkAction      *action,
+                                         gpointer        data);
+static void scroll_next_line_cb         (GtkAction      *action,
+                                          gpointer        data);
+static void scroll_next_page_cb         (GtkAction      *action,
+                                         gpointer        data);
+static void scroll_prev_page_cb         (GtkAction      *action,
+                                         gpointer        data);
+
 static void set_charset_cb             (GtkAction *action, GtkRadioAction *current, gpointer data);
 static void set_decode_cb              (GtkAction *action, GtkRadioAction *current, gpointer data);
 
@@ -173,6 +186,16 @@ static void messageview_update             (MessageView    *msgview,
                                         MsgInfo        *old_msginfo);
 static gboolean messageview_update_msg (gpointer source, gpointer data);
 
+static void save_part_as_cb(GtkAction *action, gpointer data);
+static void view_part_as_text_cb(GtkAction *action, gpointer data);
+static void open_part_cb(GtkAction *action, gpointer data);
+#ifndef G_OS_WIN32
+static void open_part_with_cb(GtkAction *action, gpointer data);
+#endif
+static void check_signature_cb(GtkAction *action, gpointer data);
+static void goto_next_part_cb(GtkAction *action, gpointer data);
+static void goto_prev_part_cb(GtkAction *action, gpointer data);
+
 static void messageview_nothing_cb        (GtkAction *action, gpointer data)
 {
 
@@ -192,10 +215,9 @@ static GtkActionEntry msgview_entries[] =
        {"PlaceHolder",                 NULL, "Placeholder", NULL, NULL, G_CALLBACK(messageview_nothing_cb) },
 
 /* File menu */
-       {"File/SaveAs",                 NULL, N_("_Save as..."), "<control>S", NULL, G_CALLBACK(save_as_cb) },
-#if GTK_CHECK_VERSION(2,10,0) && !defined(USE_GNOMEPRINT)
+       {"File/SaveAs",                 NULL, N_("_Save email as..."), "<control>S", NULL, G_CALLBACK(save_as_cb) },
+       {"File/SavePartAs",             NULL, N_("_Save part as..."), "Y", NULL, G_CALLBACK(save_part_as_cb) },
        {"File/PageSetup",              NULL, N_("Page setup..."), NULL, NULL, G_CALLBACK(page_setup_cb) },
-#endif
        {"File/Print",                  NULL, N_("_Print..."), "<control>P", NULL, G_CALLBACK(print_cb) },
        {"File/---",                    NULL, "---", NULL, NULL, NULL },
        {"File/Close",                  NULL, N_("_Close"), "<control>W", NULL, G_CALLBACK(close_cb) },
@@ -222,13 +244,23 @@ static GtkActionEntry msgview_entries[] =
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/PrevLabeled",       NULL, N_("Previous _labeled message"), NULL, NULL, G_CALLBACK(prev_labeled_cb) },
        {"View/Goto/NextLabeled",       NULL, N_("Next la_beled message"), NULL, NULL, G_CALLBACK(next_labeled_cb) },
+       /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
+       {"View/Goto/PrevHistory",       NULL, N_("Previous opened message"), "<alt>Left", NULL, G_CALLBACK(prev_history_cb) },
+       {"View/Goto/NextHistory",       NULL, N_("Next opened message"), "<alt>Right", NULL, G_CALLBACK(next_history_cb) },
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
-       {"View/Goto/LastRead",          NULL, N_("Last read message"), NULL, NULL, G_CALLBACK(last_read_cb) },
        {"View/Goto/ParentMessage",     NULL, N_("Parent message"), "<control>Up", NULL, G_CALLBACK(parent_cb) },
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/NextUnreadFolder",  NULL, N_("Next unread _folder"), "<shift>G", NULL, G_CALLBACK(goto_unread_folder_cb) },
        {"View/Goto/OtherFolder",       NULL, N_("_Other folder..."), "G", NULL, G_CALLBACK(goto_folder_cb) },
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
+       {"View/Goto/NextPart",          NULL, N_("Next part"), "A", NULL, G_CALLBACK(goto_next_part_cb) },
+       {"View/Goto/PrevPart",          NULL, N_("Previous part"), "Z", NULL, G_CALLBACK(goto_prev_part_cb) },
+        {"View/Scroll",                 NULL, N_("Message scroll") },
+        {"View/Scroll/PrevLine",        NULL, N_("Previous line"), NULL, NULL, G_CALLBACK(scroll_prev_line_cb) },
+        {"View/Scroll/NextLine",        NULL, N_("Next line"), NULL, NULL, G_CALLBACK(scroll_next_line_cb) },
+        {"View/Scroll/PrevPage",        NULL, N_("Previous page"), NULL, NULL, G_CALLBACK(scroll_prev_page_cb) },
+        {"View/Scroll/NextPage",        NULL, N_("Next page"), NULL, NULL, G_CALLBACK(scroll_next_page_cb) },
+        /* {"View/Scroll/---",          NULL, "---", NULL, NULL, NULL }, */
 
        {"View/Encoding",               NULL, N_("Character _encoding") }, /* set_charset_cb */
        {"View/Encoding/---",           NULL, "---" },
@@ -253,6 +285,12 @@ static GtkActionEntry msgview_entries[] =
 
        {"View/---",                    NULL, "---", NULL, NULL, NULL },
        {"View/MessageSource",          NULL, N_("Mess_age source"), "<control>U", NULL, G_CALLBACK(view_source_cb) },
+       {"View/Part",                   NULL, N_("Message part") },
+       {"View/Part/AsText",            NULL, N_("View as text"), "T", NULL, G_CALLBACK(view_part_as_text_cb) },
+       {"View/Part/Open",              NULL, N_("Open"), "L", NULL, G_CALLBACK(open_part_cb) },
+#ifndef G_OS_WIN32
+       {"View/Part/OpenWith",          NULL, N_("Open with..."), "O", NULL, G_CALLBACK(open_part_with_cb) },
+#endif
 
        {"View/Quotes",                 NULL, N_("Quotes") }, 
 
@@ -262,14 +300,15 @@ static GtkActionEntry msgview_entries[] =
 
        {"Message/Reply",               NULL, N_("_Reply"), "<control>R", NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REPLY */
        {"Message/ReplyTo",             NULL, N_("Repl_y to") }, 
-       {"Message/ReplyTo/All",         NULL, N_("_all"), "<control><shift>R", NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REPLY_TO_ALL */
-       {"Message/ReplyTo/Sender",      NULL, N_("_sender"), NULL, NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REPLY_TO_SENDER */
-       {"Message/ReplyTo/List",        NULL, N_("mailing _list"), "<control>L", NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REPLY_TO_LIST */
+       {"Message/ReplyTo/All",         NULL, N_("_All"), "<control><shift>R", NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REPLY_TO_ALL */
+       {"Message/ReplyTo/Sender",      NULL, N_("_Sender"), NULL, NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REPLY_TO_SENDER */
+       {"Message/ReplyTo/List",        NULL, N_("Mailing _list"), "<control>L", NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REPLY_TO_LIST */
        /* {"Message/---",                      NULL, "---", NULL, NULL, NULL }, */
 
        {"Message/Forward",             NULL, N_("_Forward"), "<control><alt>F", NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_FORWARD_INLINE */
        {"Message/ForwardAtt",          NULL, N_("For_ward as attachment"), NULL, NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_FORWARD_AS_ATTACH */
        {"Message/Redirect",            NULL, N_("Redirec_t"), NULL, NULL, G_CALLBACK(reply_cb) }, /* COMPOSE_REDIRECT */
+       {"Message/CheckSignature",              NULL, N_("Check signature"), "C", NULL, G_CALLBACK(check_signature_cb) },
 
 /* Tools menu */       
        {"Tools/AddressBook",           NULL, N_("_Address book"), "<control><shift>A", NULL, G_CALLBACK(addressbook_open_cb) }, 
@@ -303,9 +342,9 @@ static GtkActionEntry msgview_entries[] =
 static GtkToggleActionEntry msgview_toggle_entries[] =
 {
        {"View/AllHeaders",             NULL, N_("Show all _headers"), "<control>H", NULL, G_CALLBACK(show_all_header_cb) }, /* toggle */
-       {"View/Quotes/FoldAll",         NULL, N_("_Fold all"), "<control><shift>Q", NULL, G_CALLBACK(msg_hide_quotes_cb) }, /* 1 toggle */
-       {"View/Quotes/Fold2",           NULL, N_("Fold from level _2"), NULL, NULL, G_CALLBACK(msg_hide_quotes_cb) }, /* 2 toggle */
-       {"View/Quotes/Fold3",           NULL, N_("Fold from level _3"), NULL, NULL, G_CALLBACK(msg_hide_quotes_cb) }, /* 3 toggle */
+       {"View/Quotes/CollapseAll",     NULL, N_("_Collapse all"), "<control><shift>Q", NULL, G_CALLBACK(msg_hide_quotes_cb) }, /* 1 toggle */
+       {"View/Quotes/Collapse2",               NULL, N_("Collapse from level _2"), NULL, NULL, G_CALLBACK(msg_hide_quotes_cb) }, /* 2 toggle */
+       {"View/Quotes/Collapse3",               NULL, N_("Collapse from level _3"), NULL, NULL, G_CALLBACK(msg_hide_quotes_cb) }, /* 3 toggle */
 };
 
 static GtkRadioActionEntry msgview_radio_enc_entries[] =
@@ -333,6 +372,7 @@ static GtkRadioActionEntry msgview_radio_enc_entries[] =
        ENC_ACTION("Japanese/"CS_ISO_2022_JP_2, C_ISO_2022_JP_2, "ISO-2022-JP-_2"), /* RADIO set_charset_cb */
        ENC_ACTION("Japanese/"CS_EUC_JP, C_EUC_JP, "_EUC-JP"), /* RADIO set_charset_cb */
        ENC_ACTION("Japanese/"CS_SHIFT_JIS, C_SHIFT_JIS, "_Shift-JIS"), /* RADIO set_charset_cb */
+       ENC_ACTION("Chinese/"CS_GB18030, C_GB18030, "_GB18030"), /* RADIO set_charset_cb */
        ENC_ACTION("Chinese/"CS_GB2312, C_GB2312, "_GB2312"), /* RADIO set_charset_cb */
        ENC_ACTION("Chinese/"CS_GBK, C_GBK, "GB_K"), /* RADIO set_charset_cb */
        ENC_ACTION("Chinese/"CS_BIG5, C_BIG5, "_Big5-JP"), /* RADIO set_charset_cb */
@@ -394,6 +434,7 @@ MessageView *messageview_create(MainWindow *mainwin)
        messageview->statusbar_cid = 0;
 
        messageview->show_full_text= FALSE;
+       messageview->update_needed = FALSE;
 
        messageview->msginfo_update_callback_id =
                hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, messageview_update_msg, (gpointer) messageview);
@@ -439,12 +480,7 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        gtk_action_group_add_radio_actions(action_group, msgview_radio_dec_entries,
                        G_N_ELEMENTS(msgview_radio_dec_entries), C_AUTO, G_CALLBACK(set_decode_cb), (gpointer)msgview);
 
-#ifndef MAEMO
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/", "Menu", NULL, GTK_UI_MANAGER_MENUBAR)
-#else
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/", "Menu", NULL, GTK_UI_MANAGER_POPUP)
-#endif
-
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu", "File", "File", GTK_UI_MANAGER_MENU)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu", "Edit", "Edit", GTK_UI_MANAGER_MENU)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu", "View", "View", GTK_UI_MANAGER_MENU)
@@ -454,11 +490,11 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
 
 /* File menu */
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "SaveAs", "File/SaveAs", GTK_UI_MANAGER_MENUITEM)
-#if GTK_CHECK_VERSION(2,10,0) && !defined(USE_GNOMEPRINT)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "SavePartAs", "File/SavePartAs", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "Separator1", "File/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "PageSetup", "File/PageSetup", GTK_UI_MANAGER_MENUITEM)
-#endif
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "Print", "File/Print", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "Separator1", "File/---", GTK_UI_MANAGER_SEPARATOR)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "Separator2", "File/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/File", "Close", "File/Close", GTK_UI_MANAGER_MENUITEM)
 
 /* Edit menu */
@@ -471,24 +507,35 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View", "Goto", "View/Goto", GTK_UI_MANAGER_MENU)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Prev", "View/Goto/Prev", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Next", "View/Goto/Next", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator1", "View/Goto/---", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator1", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevUnread", "View/Goto/PrevUnread", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextUnread", "View/Goto/NextUnread", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator2", "View/Goto/---", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator2", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevNew", "View/Goto/PrevNew", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextNew", "View/Goto/NextNew", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator3", "View/Goto/---", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator3", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevMarked", "View/Goto/PrevMarked", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextMarked", "View/Goto/NextMarked", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator4", "View/Goto/---", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator4", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevLabeled", "View/Goto/PrevLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextLabeled", "View/Goto/NextLabeled", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator5", "View/Goto/---", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "LastRead", "View/Goto/LastRead", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator5", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevHistory", "View/Goto/PrevHistory", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextHistory", "View/Goto/NextHistory", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator6", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator6", "View/Goto/---", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator7", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextUnreadFolder", "View/Goto/NextUnreadFolder", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "OtherFolder", "View/Goto/OtherFolder", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator8", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextPart", "View/Goto/NextPart", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevPart", "View/Goto/PrevPart", GTK_UI_MANAGER_MENUITEM)
+
+        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View", "Scroll", "View/Scroll", GTK_UI_MANAGER_MENU)
+        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Scroll", "PrevLine", "View/Scroll/PrevLine", GTK_UI_MANAGER_MENUITEM)
+        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Scroll", "NextLine", "View/Scroll/NextLine", GTK_UI_MANAGER_MENUITEM)
+        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Scroll", "PrevPage", "View/Scroll/PrevPage", GTK_UI_MANAGER_MENUITEM)
+        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Scroll", "NextPage", "View/Scroll/NextPage", GTK_UI_MANAGER_MENUITEM)
 
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View", "Separator1", "View/---", GTK_UI_MANAGER_SEPARATOR)
 
@@ -535,6 +582,7 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Japanese", CS_SHIFT_JIS, "View/Encoding/Japanese/"CS_SHIFT_JIS, GTK_UI_MANAGER_MENUITEM)
 
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding", "Chinese", "View/Encoding/Chinese", GTK_UI_MANAGER_MENU)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Chinese", CS_GB18030, "View/Encoding/Chinese/"CS_GB18030, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Chinese", CS_GB2312, "View/Encoding/Chinese/"CS_GB2312, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Chinese", CS_GBK, "View/Encoding/Chinese/"CS_GBK, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Chinese", CS_BIG5, "View/Encoding/Chinese/"CS_BIG5, GTK_UI_MANAGER_MENUITEM)
@@ -561,9 +609,15 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View", "MessageSource", "View/MessageSource", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View", "AllHeaders", "View/AllHeaders", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View", "Quotes", "View/Quotes", GTK_UI_MANAGER_MENU)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Quotes", "FoldAll", "View/Quotes/FoldAll", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Quotes", "Fold2", "View/Quotes/Fold2", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Quotes", "Fold3", "View/Quotes/Fold3", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Quotes", "CollapseAll", "View/Quotes/CollapseAll", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Quotes", "Collapse2", "View/Quotes/Collapse2", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Quotes", "Collapse3", "View/Quotes/Collapse3", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View", "Part", "View/Part", GTK_UI_MANAGER_MENU)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Part", "AsText", "View/Part/AsText", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Part", "Open", "View/Part/Open", GTK_UI_MANAGER_MENUITEM)
+#ifndef G_OS_WIN32
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Part", "OpenWith", "View/Part/OpenWith", GTK_UI_MANAGER_MENUITEM)
+#endif
 
 /* Message menu */
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Message", "Compose", "Message/Compose", GTK_UI_MANAGER_MENUITEM)
@@ -577,6 +631,7 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Message", "Forward", "Message/Forward", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Message", "ForwardAtt", "Message/ForwardAtt", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Message", "Redirect", "Message/Redirect", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Message", "CheckSignature", "Message/CheckSignature", GTK_UI_MANAGER_MENUITEM)
 
 /* Tools menu */
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/Tools", "AddressBook", "Tools/AddressBook", GTK_UI_MANAGER_MENUITEM)
@@ -609,11 +664,10 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        gtk_widget_show_all(menubar);
        gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(msgview->ui_manager));
 
-#ifndef MAEMO
        gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
-#else
-       hildon_window_set_menu(HILDON_WINDOW(window), GTK_MENU(menubar));
-#endif
+
+       cm_toggle_menu_set_active_full(msgview->ui_manager, "Menu/View/AllHeaders",
+                                       prefs_common.show_all_headers);
 
        if (prefs_common.toolbar_detachable) {
                handlebox = gtk_handle_box_new();
@@ -622,12 +676,6 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        }
        gtk_box_pack_start(GTK_BOX(vbox), handlebox, FALSE, FALSE, 0);
        gtk_widget_realize(handlebox);
-#ifdef MAEMO
-       msgview->toolbar = toolbar_create(TOOLBAR_MSGVIEW, window,
-                                         (gpointer)msgview);
-       msgview->statusbar = NULL;
-       msgview->statusbar_cid = 0;
-#else
        msgview->toolbar = toolbar_create(TOOLBAR_MSGVIEW, handlebox,
                                          (gpointer)msgview);
 #ifndef GENERIC_UMPC
@@ -641,7 +689,6 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        msgview->statusbar = NULL;
        msgview->statusbar_cid = 0;
 #endif
-#endif
 
 
        msgview->handlebox = handlebox;
@@ -685,16 +732,11 @@ static MessageView *messageview_create_with_new_window_visible(MainWindow *mainw
                         msgview);
        g_signal_connect(G_OBJECT(window), "delete_event",
                         G_CALLBACK(messageview_delete_cb), msgview);
-#ifdef MAEMO
-       maemo_connect_key_press_to_mainwindow(GTK_WINDOW(window));
-#else
        g_signal_connect(G_OBJECT(window), "key_press_event",
                         G_CALLBACK(key_pressed), msgview);
-#endif
        messageview_add_toolbar(msgview, window);
 
        if (show) {
-               gtk_widget_grab_focus(msgview->mimeview->textview->text);
                gtk_widget_show(window);
        } else {
                gtk_widget_realize(window);
@@ -708,6 +750,11 @@ static MessageView *messageview_create_with_new_window_visible(MainWindow *mainw
                          prefs_common.toolbar_style);
        messageview_init(msgview);
 
+       if (show) {
+               GTK_EVENTS_FLUSH();
+               gtk_widget_grab_focus(msgview->mimeview->textview->text);
+       }
+
        return msgview;
 }
 
@@ -864,7 +911,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        addrp = addr;
        
        /* write queue headers */
-       if (fprintf(fp, "AF:\n"
+       ok = fprintf(fp, "AF:\n"
                    "NF:0\n"
                    "PS:10\n"
                    "SRH:1\n"
@@ -880,14 +927,11 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                    "R:<%s>\n", 
                    account->address,
                    account->smtp_server?account->smtp_server:"",
-                   addrp) < 0) {
-               g_free(addrp);
-               fclose(fp);
-               claws_unlink(tmp);
-               return -1;
-       }
+                   addrp);
 
        g_free(addrp);
+       if (ok < 0)
+               goto FILE_ERROR;
        
        /* check whether we need to save the message */
        outbox = account_get_special_folder(account, F_OUTBOX); 
@@ -895,61 +939,40 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                outbox = NULL;
        if (outbox) {
                path = folder_item_get_identifier(outbox);
-               if (fprintf(fp, "SCF:%s\n", path) < 0) {
-                       g_free(path);
-                       fclose(fp);
-                       claws_unlink(tmp);
-                       return -1;
-               }
+               ok = fprintf(fp, "SCF:%s\n", path);
                g_free(path);
+               
+               if (ok < 0)
+                       goto FILE_ERROR;
        }               
 
-       if (fprintf(fp, "X-Claws-End-Special-Headers: 1\n") < 0) {
-               fclose(fp);
-               claws_unlink(tmp);
-               return -1;
-       }
+       if (fprintf(fp, "X-Claws-End-Special-Headers: 1\n") < 0)
+               goto FILE_ERROR;
 
        /* Date */
        get_rfc822_date(buf, sizeof(buf));
-       if (fprintf(fp, "Date: %s\n", buf) < 0) {
-               fclose(fp);
-               claws_unlink(tmp);
-               return -1;
-       }
+       if (fprintf(fp, "Date: %s\n", buf) < 0)
+               goto FILE_ERROR;
 
        /* From */
        if (account->name && *account->name) {
                notification_convert_header
                        (buf, sizeof(buf), account->name,
                         strlen("From: "));
-               if (fprintf(fp, "From: %s <%s>\n", buf, account->address) < 0) {
-                       fclose(fp);
-                       claws_unlink(tmp);
-                       return -1;
-               }
+               if (fprintf(fp, "From: %s <%s>\n", buf, account->address) < 0)
+                       goto FILE_ERROR;
        } else
-               if (fprintf(fp, "From: %s\n", account->address) < 0) {
-                       fclose(fp);
-                       claws_unlink(tmp);
-                       return -1;
-               }
-
+               if (fprintf(fp, "From: %s\n", account->address) < 0)
+                       goto FILE_ERROR;
 
-       if (fprintf(fp, "To: %s\n", to) < 0) {
-               fclose(fp);
-               claws_unlink(tmp);
-               return -1;
-       }
+       if (fprintf(fp, "To: %s\n", to) < 0)
+               goto FILE_ERROR;
 
        /* Subject */
        notification_convert_header(buf, sizeof(buf), msginfo->subject,
                                    strlen("Subject: "));
-       if (fprintf(fp, "Subject: Disposition notification: %s\n", buf) < 0) {
-               fclose(fp);
-               claws_unlink(tmp);
-               return -1;
-       }
+       if (fprintf(fp, "Subject: Disposition notification: %s\n", buf) < 0)
+               goto FILE_ERROR;
 
        /* Message ID */
        if (account->set_domain && account->domain) {
@@ -970,11 +993,8 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                }
                generate_msgid(buf, sizeof(buf), addr);
 
-               if (fprintf(fp, "Message-ID: <%s>\n", buf) < 0) {
-                       fclose(fp);
-                       claws_unlink(tmp);
-                       return -1;
-               }
+               if (fprintf(fp, "Message-ID: <%s>\n", buf) < 0)
+                       goto FILE_ERROR;
        }
 
        boundary = generate_mime_boundary("DN");
@@ -989,7 +1009,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                qp_encode_line(enc_sub, (const guchar *)msginfo->subject);
                g_strstrip(enc_sub);
        }
-       if (fprintf(fp, "MIME-Version: 1.0\n"
+       ok = fprintf(fp,"MIME-Version: 1.0\n"
                        "Content-Type: multipart/report; report-type=disposition-notification;\n"
                        "  boundary=\"%s\"\n"
                        "\n"
@@ -1015,6 +1035,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                        "\n"
                        "--%s\n"
                        "Content-Type: application/octet-stream\n"
+                       "\n"
                        "Reporting-UA: %s\n"
                        "Original-Recipient: rfc822;%s\n"
                        "Final-Recipient: rfc822;%s\n"
@@ -1038,18 +1059,16 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                        orig_to?orig_to:"No To:",
                        account->address,
                        msginfo->msgid?msginfo->msgid:"NO MESSAGE ID",
-                       boundary) < 0) {
-               fclose(fp);
-               claws_unlink(tmp);
-               g_free(boundary);
-               return -1;
-       }
+                       boundary);
 
        g_free(enc_sub);
        g_free(orig_to);
        g_free(date);
        g_free(boundary);
 
+       if (ok < 0)
+               goto FILE_ERROR;        
+
        if (fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
                claws_unlink(tmp);
@@ -1079,13 +1098,18 @@ static gint disposition_notification_send(MsgInfo *msginfo)
 
        /* send it */
        path = folder_item_fetch_msg(queue, num);
-       ok = procmsg_send_message_queue(path, &foo, queue, num, &queued_removed);
+       ok = procmsg_send_message_queue_with_lock(path, &foo, queue, num, &queued_removed);
        g_free(path);
        g_free(foo);
        if (ok == 0 && !queued_removed)
                folder_item_remove_msg(queue, num);
 
        return ok;
+
+FILE_ERROR:
+       fclose(fp);
+       claws_unlink(tmp);
+       return -1;
 }
 
 static gboolean find_encrypted_func(GNode *node, gpointer data)
@@ -1134,12 +1158,124 @@ static MimeInfo *find_broken_part(MimeInfo *rootinfo)
        return brokeninfo;
 }
 
+static void messageview_register_nav(MessageView *messageview)
+{
+       gchar *id;
+       gint pos = -1;
+       GList *existing;
+
+       cm_return_if_fail(messageview);
+       cm_return_if_fail(messageview->msginfo);
+
+       id = procmsg_msginfo_get_identifier(messageview->msginfo);
+       existing = g_list_find_custom(messageview->trail, id, (GCompareFunc)g_strcmp0);
+
+       if (existing != NULL)
+               pos = g_list_position(messageview->trail, existing);
+       else
+               pos = -1;
+
+       if (pos != -1) {
+               messageview->trail_pos = pos;
+               g_free(id);
+       } else {
+               /* Cut the end of the list */
+               GList *end = g_list_nth(messageview->trail, messageview->trail_pos + 1);
+               if (end) {
+                       if (end->prev) {
+                               end->prev->next = NULL;
+                               end->prev = NULL;
+                               list_free_strings(end);
+                               g_list_free(end);
+                       } else {
+                               list_free_strings(messageview->trail);
+                               g_list_free(messageview->trail);
+                               messageview->trail = NULL;
+                       }
+               }
+               messageview->trail = g_list_append(messageview->trail, id);
+               messageview->trail_pos = g_list_length(messageview->trail) - 1;
+               
+               /* Cut the beginning if needed */
+               while (messageview->trail_pos > prefs_common.nav_history_length) {
+                       g_free(messageview->trail->data);
+                       messageview->trail = g_list_delete_link(messageview->trail,
+                                               messageview->trail);
+                       messageview->trail_pos--;
+               }
+       }
+       messageview_set_menu_sensitive(messageview);
+}
+
+gboolean messageview_nav_has_prev(MessageView *messageview) {
+       return messageview->trail != NULL &&  messageview->trail_pos > 0;
+}
+
+gboolean messageview_nav_has_next(MessageView *messageview) {
+       if (!messageview->trail)
+               return FALSE;
+       
+       return sc_g_list_bigger(messageview->trail, messageview->trail_pos + 1);
+}
+
+MsgInfo *messageview_nav_get_prev(MessageView *messageview) {
+       GList *item;
+       MsgInfo *info;
+
+       cm_return_val_if_fail(messageview, NULL);
+       cm_return_val_if_fail(messageview->trail, NULL);
+
+       do {
+               if (!messageview_nav_has_prev(messageview))
+                       return NULL;
+
+               item = g_list_nth(messageview->trail, messageview->trail_pos - 1);
+               cm_return_val_if_fail(item != NULL, NULL);
+
+               info = procmsg_get_msginfo_from_identifier((const gchar *)item->data);
+               if (info != NULL)
+                       break;
+
+               g_free(item->data);
+               messageview->trail = g_list_delete_link(messageview->trail, item);
+               if (messageview->trail_pos > 0)
+                       messageview->trail_pos--;
+       } while (info == NULL);
+
+       return info;
+}
+
+MsgInfo *messageview_nav_get_next(MessageView *messageview) {
+       GList *item;
+       MsgInfo *info;
+
+       cm_return_val_if_fail(messageview, NULL);
+       cm_return_val_if_fail(messageview->trail, NULL);
+
+       do {
+               if (!messageview_nav_has_next(messageview))
+                       return NULL;
+
+               item = g_list_nth(messageview->trail, messageview->trail_pos + 1);
+               cm_return_val_if_fail(item != NULL, NULL);
+
+               info = procmsg_get_msginfo_from_identifier((const gchar *)item->data);
+               if (info != NULL)
+                       break;
+
+               g_free(item->data);
+               messageview->trail = g_list_delete_link(messageview->trail, item);
+       } while (info == NULL);
+       
+       return info;
+}
+
 gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                      gboolean all_headers)
 {
        gchar *text = NULL;
        gchar *file;
-       MimeInfo *mimeinfo, *encinfo, *brokeninfo;
+       MimeInfo *mimeinfo, *encinfo, *brokeninfo, *root;
        gchar *subject = NULL;
        cm_return_val_if_fail(msginfo != NULL, -1);
 
@@ -1243,16 +1379,12 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                messageview_set_menu_sensitive(messageview);
                messageview->msginfo = msginfo;
        }
-       headerview_show(messageview->headerview, messageview->msginfo);
+       if (prefs_common.display_header_pane)
+               headerview_show(messageview->headerview, messageview->msginfo);
 
+       messageview_register_nav(messageview);
        messageview_set_position(messageview, 0);
 
-       textview_set_all_headers(messageview->mimeview->textview, 
-                       messageview->all_headers);
-
-#ifdef MAEMO
-       maemo_window_full_screen_if_needed(GTK_WINDOW(messageview->window));
-#endif
        if (messageview->window) {
                gtk_window_set_title(GTK_WINDOW(messageview->window), 
                                _("Claws Mail - Message View"));
@@ -1318,6 +1450,7 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                noticeview_show(messageview->noticeview);
        }
                        
+       root = mimeinfo;
        mimeinfo = procmime_mimeinfo_next(mimeinfo);
        if (!all_headers && mimeinfo 
                        && (mimeinfo->type != MIMETYPE_TEXT || 
@@ -1352,7 +1485,10 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                                                goto done;
                                        } else if (mimeinfo->type == MIMETYPE_TEXT && 
                                            !strcasecmp(mimeinfo->subtype, "html") &&
-                                           prefs_common.promote_html_part) {
+                                           mimeinfo->disposition != DISPOSITIONTYPE_ATTACHMENT &&
+                                                       (msginfo->folder->prefs->promote_html_part == HTML_PROMOTE_ALWAYS ||
+                                                        (msginfo->folder->prefs->promote_html_part == HTML_PROMOTE_DEFAULT &&
+                                                               prefs_common.promote_html_part))) {
                                                mimeview_select_mimepart_icon(messageview->mimeview, mimeinfo);
                                                goto done;
                                        }
@@ -1370,6 +1506,7 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                                                 * not to show html attachments */
                                                continue;
                                        }
+                                       
                                        if (mimeinfo->type == MIMETYPE_TEXT && 
                                            !strcasecmp(mimeinfo->subtype, "calendar") &&
                                            mimeview_has_viewer_for_content_type(messageview->mimeview,
@@ -1378,7 +1515,10 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                                                goto done;
                                        } else if (mimeinfo->type == MIMETYPE_TEXT && 
                                            !strcasecmp(mimeinfo->subtype, "html") &&
-                                           prefs_common.promote_html_part) {
+                                           mimeinfo->disposition != DISPOSITIONTYPE_ATTACHMENT &&
+                                                       (msginfo->folder->prefs->promote_html_part == HTML_PROMOTE_ALWAYS ||
+                                                        (msginfo->folder->prefs->promote_html_part == HTML_PROMOTE_DEFAULT &&
+                                                               prefs_common.promote_html_part))) {
                                                mimeview_select_mimepart_icon(messageview->mimeview, mimeinfo);
                                                goto done;
                                        }
@@ -1389,7 +1529,8 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                        if (!mimeinfo) 
                                mimeinfo = saved_mimeinfo;
 
-                       mimeview_show_part(messageview->mimeview,mimeinfo);
+                       if (!mimeview_show_part(messageview->mimeview, mimeinfo))
+                               mimeview_select_mimepart_icon(messageview->mimeview, root);
                        goto done;
                } else if (prefs_common.invoke_plugin_on_html) {
                        mimeview_select_mimepart_icon(messageview->mimeview, mimeinfo);
@@ -1409,7 +1550,10 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                        mimeinfo = procmime_mimeinfo_next(mimeinfo);
                }
        }
+
+       mimeview_select_mimepart_icon(messageview->mimeview, root);
 done:
+       messageview_set_menu_sensitive(messageview);
        /* plugins may hook in here to work with the message view */
        hooks_invoke(MESSAGE_VIEW_SHOW_DONE_HOOKLIST, messageview);
 
@@ -1437,6 +1581,13 @@ void messageview_clear(MessageView *messageview)
        procmsg_msginfo_free(messageview->msginfo);
        messageview->msginfo = NULL;
        messageview->filtered = FALSE;
+
+       if (messageview->window) {
+               gtk_window_set_title(GTK_WINDOW(messageview->window), 
+                               _("Claws Mail - Message View"));
+               GTK_EVENTS_FLUSH();
+       }
+
        mimeview_clear(messageview->mimeview);
        headerview_clear(messageview->headerview);
        noticeview_hide(messageview->noticeview);
@@ -1455,10 +1606,9 @@ void messageview_destroy(MessageView *messageview)
                messageview->mainwin->summaryview->displayed = NULL;
                messageview->mainwin->summaryview->ext_messageview = NULL;
        }
-       if (!messageview->deferred_destroy) {
+       if (!messageview->deferred_destroy)
                hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST,
                              messageview->msginfo_update_callback_id);
-       }
 
        if (messageview->updating) {
                debug_print("uh oh, better not touch that now (fetching)\n");
@@ -1486,7 +1636,9 @@ void messageview_destroy(MessageView *messageview)
                toolbar_destroy(messageview->toolbar);
                g_free(messageview->toolbar);
        }
-       
+
+       list_free_strings(messageview->trail);
+       g_list_free(messageview->trail);
        msgview_list = g_list_remove(msgview_list, messageview); 
 
        if (messageview->window)
@@ -1721,24 +1873,22 @@ static void messageview_size_allocate_cb(GtkWidget *widget,
        prefs_common.msgwin_width  = allocation->width;
        prefs_common.msgwin_height = allocation->height;
 }
-#ifndef MAEMO
+
 static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
                        MessageView *messageview)
 {
-       if (event && event->keyval == GDK_Escape && messageview->window) {
+       if (event && event->keyval == GDK_KEY_Escape && messageview->window) {
                messageview_destroy(messageview);
                return TRUE;
        }
 
-       if (event && (event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK|GDK_SHIFT_MASK)) != 0)
+       if (event && (event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0)
+               return FALSE;
+       if (event && (event->state & GDK_SHIFT_MASK) && event->keyval != GDK_KEY_space) 
                return FALSE;
 
-       g_signal_stop_emission_by_name(G_OBJECT(widget),
-                                       "key_press_event");
-       mimeview_pass_key_press_event(messageview->mimeview, event);
-       return FALSE;
+       return mimeview_pass_key_press_event(messageview->mimeview, event);
 }
-#endif
 
 static void messageview_show_partial_display_cb(NoticeView *noticeview, MessageView *messageview)
 {
@@ -1941,9 +2091,9 @@ static PrefsAccount *select_account_from_list(GList *ac_list)
        account_id = ((PrefsAccount *) ac_list->data)->account_id;
        if (alertpanel_with_widget(
                                _("Return Receipt Notification"),
-                               _("The message was sent to several of your "
-                                 "accounts.\n"
-                                 "Please choose which account do you want to "
+                               _("More than one of your accounts uses the "
+                                 "address that this message was sent to.\n"
+                                 "Please choose which account you want to "
                                  "use for sending the receipt notification:"),
                                _("_Cancel"), _("_Send Notification"), NULL,
                                FALSE, G_ALERTDEFAULT, optmenu) != G_ALERTALTERNATE)
@@ -2006,12 +2156,9 @@ static void save_as_cb(GtkAction *action, gpointer data)
        messageview_save_as(messageview);
 }
 
-#if defined(USE_GNOMEPRINT) || GTK_CHECK_VERSION(2,10,0)
 static void print_mimeview(MimeView *mimeview, gint sel_start, gint sel_end, gint partnum) 
 {
-#if !defined(USE_GNOMEPRINT) && GTK_CHECK_VERSION(2,10,0)
        MainWindow *mainwin;
-#endif
        if (!mimeview 
        ||  !mimeview->textview
        ||  !mimeview->textview->text)
@@ -2038,15 +2185,11 @@ static void print_mimeview(MimeView *mimeview, gint sel_start, gint sel_end, gin
                        gtk_text_buffer_get_iter_at_offset(buffer, &end, sel_end);
                        gtk_text_buffer_select_range(buffer, &start, &end);
                }
-#if defined(USE_GNOMEPRINT)
-               gedit_print(GTK_TEXT_VIEW(mimeview->textview->text));
-#else
                /* TODO: Get the real parent window, not the main window */
                mainwin = mainwindow_get_mainwindow();
                printing_print(GTK_TEXT_VIEW(mimeview->textview->text),
                               mainwin ? GTK_WINDOW(mainwin->window) : NULL,
                                sel_start, sel_end);
-#endif
        }
 }
 
@@ -2078,51 +2221,26 @@ void messageview_print(MsgInfo *msginfo, gboolean all_headers,
        }
        messageview_destroy(tmpview);
 }
-#endif
 
-#if GTK_CHECK_VERSION(2,10,0) && !defined(USE_GNOMEPRINT)
 static void page_setup_cb(GtkAction *action, gpointer data)
 {
        MessageView *messageview = (MessageView *)data;
        printing_page_setup(messageview ?
                            GTK_WINDOW(messageview->window) : NULL);
 }
-#endif
 
 static void print_cb(GtkAction *action, gpointer data)
 {
        MessageView *messageview = (MessageView *)data;
-#if !defined(USE_GNOMEPRINT) && !GTK_CHECK_VERSION(2,10,0)
-       gchar *cmdline = NULL;
-       gchar *p;
-#else
        gint sel_start = -1, sel_end = -1, partnum = 0;
-#endif
 
        if (!messageview->msginfo) return;
 
-#if !defined(USE_GNOMEPRINT) && !GTK_CHECK_VERSION(2,10,0)
-       cmdline = input_dialog(_("Print"),
-                              _("Enter the print command-line:\n"
-                                "('%s' will be replaced with file name)"),
-                              prefs_common.print_cmd);
-       if (!cmdline) return;
-       if (!(p = strchr(cmdline, '%')) || *(p + 1) != 's' ||
-           strchr(p + 2, '%')) {
-               alertpanel_error(_("Print command-line is invalid:\n'%s'"),
-                                cmdline);
-               g_free(cmdline);
-               return;
-       }
-       procmsg_print_message(messageview->msginfo, cmdline);
-       g_free(cmdline);
-#else
        partnum = mimeview_get_selected_part_num(messageview->mimeview);
        textview_get_selection_offsets(messageview->mimeview->textview,
                &sel_start, &sel_end);
        messageview_print(messageview->msginfo, messageview->all_headers, 
                sel_start, sel_end, partnum);
-#endif
 }
 
 static void close_cb(GtkAction *action, gpointer data)
@@ -2399,28 +2517,39 @@ static void next_labeled_cb(GtkAction *action, gpointer data)
        }
 }
 
-static void last_read_cb(GtkAction *action, gpointer data)
+static void prev_history_cb(GtkAction *action, gpointer data)
 {
        MessageView *messageview = (MessageView *)data;
-       messageview->updating = TRUE;
-       summary_select_last_read(messageview->mainwin->summaryview);
-       messageview->updating = FALSE;
-
-       if (messageview->deferred_destroy) {
-               debug_print("messageview got away!\n");
-               messageview_destroy(messageview);
-               return;
+       MsgInfo *info = messageview_nav_get_prev(messageview);
+       if (info) {
+               messageview->updating = TRUE;
+               messageview_show(messageview, info, 
+                                        messageview->all_headers);
+               messageview->updating = FALSE;
+               procmsg_msginfo_free(info);
+               if (messageview->deferred_destroy) {
+                       debug_print("messageview got away!\n");
+                       messageview_destroy(messageview);
+                       return;
+               }
        }
-       if (messageview->mainwin->summaryview->selected) {
-#ifndef GENERIC_UMPC
-               MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
-                      
-               if (msginfo)
-                       messageview_show(messageview, msginfo, 
+}
+
+static void next_history_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+       MsgInfo *info = messageview_nav_get_next(messageview);
+       if (info) {
+               messageview->updating = TRUE;
+               messageview_show(messageview, info, 
                                         messageview->all_headers);
-#endif
-       } else {
-               gtk_widget_destroy(messageview->window);
+               messageview->updating = FALSE;
+               procmsg_msginfo_free(info);
+               if (messageview->deferred_destroy) {
+                       debug_print("messageview got away!\n");
+                       messageview_destroy(messageview);
+                       return;
+               }
        }
 }
 
@@ -2505,6 +2634,30 @@ static void goto_folder_cb(GtkAction *action, gpointer data)
        }
 }
 
+static void scroll_prev_line_cb(GtkAction *action, gpointer data)
+{
+        MessageView *messageview = (MessageView *)data;
+        mimeview_scroll_one_line(messageview->mimeview,TRUE);
+}
+
+static void scroll_next_line_cb(GtkAction *action, gpointer data)
+{
+        MessageView *messageview = (MessageView *)data;
+        mimeview_scroll_one_line(messageview->mimeview,FALSE);
+}
+
+static void scroll_prev_page_cb(GtkAction *action, gpointer data)
+{
+        MessageView *messageview = (MessageView *)data;
+        mimeview_scroll_page(messageview->mimeview,TRUE);
+}
+
+static void scroll_next_page_cb(GtkAction *action, gpointer data)
+{
+        MessageView *messageview = (MessageView *)data;
+        mimeview_scroll_page(messageview->mimeview,FALSE);
+}
+
 static void set_charset_cb(GtkAction *action, GtkRadioAction *current, gpointer data)
 {
        MessageView *messageview = (MessageView *)data;
@@ -2561,13 +2714,14 @@ static void show_all_header_cb(GtkToggleAction *action, gpointer data)
        if (messageview->updating)
                return;
 
-       messageview->all_headers = 
+       messageview->all_headers = prefs_common.show_all_headers =
                        gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
        if (!msginfo) return;
        messageview->msginfo = NULL;
-       messageview_show(messageview, msginfo,gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
+       messageview_show(messageview, msginfo, messageview->all_headers);
        procmsg_msginfo_free(msginfo);
        main_window_set_menu_sensitive(messageview->mainwin);
+       summary_redisplay_msg(messageview->mainwin->summaryview);
 }
 
 static void msg_hide_quotes_cb(GtkToggleAction *action, gpointer data)
@@ -2580,17 +2734,17 @@ static void msg_hide_quotes_cb(GtkToggleAction *action, gpointer data)
                return;
        if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
                const gchar *a_name = gtk_action_get_name(GTK_ACTION(action));
-               if (!strcmp(a_name, "View/Quotes/FoldAll")) prefs_common.hide_quotes = 1;
-               else if (!strcmp(a_name, "View/Quotes/Fold2")) prefs_common.hide_quotes = 2;
-               else if (!strcmp(a_name, "View/Quotes/Fold3")) prefs_common.hide_quotes = 3;
+               if (!strcmp(a_name, "View/Quotes/CollapseAll")) prefs_common.hide_quotes = 1;
+               else if (!strcmp(a_name, "View/Quotes/Collapse2")) prefs_common.hide_quotes = 2;
+               else if (!strcmp(a_name, "View/Quotes/Collapse3")) prefs_common.hide_quotes = 3;
        } else
                prefs_common.hide_quotes = 0;
        
        updating_menu=TRUE;
        
-       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/FoldAll", (prefs_common.hide_quotes == 1));
-       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Fold2", (prefs_common.hide_quotes == 2));
-       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Fold3", (prefs_common.hide_quotes == 3));
+       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/CollapseAll", (prefs_common.hide_quotes == 1));
+       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse2", (prefs_common.hide_quotes == 2));
+       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse3", (prefs_common.hide_quotes == 3));
 
        updating_menu=FALSE;
        if (!msginfo) return;
@@ -2617,7 +2771,7 @@ static void compose_cb(GtkAction *action, gpointer data)
        if (item) {
                ac = account_find_from_item(item);
                if (ac && ac->protocol == A_NNTP &&
-                   item->stype == F_NEWS) {
+                   FOLDER_TYPE(item->folder) == F_NEWS) {
                        compose_new(ac, item->path, NULL);
                        return;
                }
@@ -2652,7 +2806,18 @@ static void reply_cb(GtkAction *gaction, gpointer data)
 
 static void addressbook_open_cb(GtkAction *action, gpointer data)
 {
+#ifndef USE_NEW_ADDRBOOK
        addressbook_open(NULL);
+#else
+       GError* error = NULL;
+       
+       addressbook_dbus_open(FALSE, &error);
+       if (error) {
+               g_warning("Failed to open address book");
+               g_warning("%s", error->message);
+               g_error_free(error);
+       }
+#endif
 }
 
 static void add_address_cb(GtkAction *action, gpointer data)
@@ -2660,8 +2825,8 @@ static void add_address_cb(GtkAction *action, gpointer data)
        MessageView *messageview = (MessageView *)data;
        MsgInfo *msginfo, *full_msginfo;
        gchar *from;
-       GtkWidget *image = NULL;
        GdkPixbuf *picture = NULL;
+       AvatarRender *avatarr;
 
        if (!messageview->msginfo || !messageview->msginfo->from) 
                return;
@@ -2672,28 +2837,23 @@ static void add_address_cb(GtkAction *action, gpointer data)
        extract_address(from);
        
        full_msginfo = procmsg_msginfo_get_full_info(msginfo);
-       if (full_msginfo &&
-           full_msginfo->extradata &&
-           full_msginfo->extradata->face) {
-               image = face_get_from_header(full_msginfo->extradata->face);
-       } 
-#if HAVE_LIBCOMPFACE
-       else if (full_msginfo &&
-                full_msginfo->extradata &&
-                full_msginfo->extradata->xface) {
-               image = xface_get_from_header(full_msginfo->extradata->xface,
-                               &messageview->mainwin->summaryview->ctree->style->white,
-                               messageview->window->window);   
-       }
-#endif
+
+       avatarr = avatars_avatarrender_new(full_msginfo);
+       hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
+
        procmsg_msginfo_free(full_msginfo);
-       if (image)
-               picture = gtk_image_get_pixbuf(GTK_IMAGE(image));
 
-       addressbook_add_contact(msginfo->fromname, from, NULL, picture);
+       if (avatarr->image != NULL)
+               picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image));
 
-       if (image)
-               gtk_widget_destroy(image);
+#ifndef USE_NEW_ADDRBOOK
+       addressbook_add_contact(msginfo->fromname, from, NULL, picture);
+#else
+       if (addressadd_selection(msginfo->fromname, from, NULL, picture)) {
+               debug_print( "addressbook_add_contact - added\n" );
+       }
+#endif
+       avatars_avatarrender_free(avatarr);
 }
 
 static void create_filter_cb(GtkAction *gaction, gpointer data)
@@ -2749,29 +2909,52 @@ static gboolean messageview_update_msg(gpointer source, gpointer data)
 {
        MsgInfoUpdate *msginfo_update = (MsgInfoUpdate *) source;
        MessageView *messageview = (MessageView *)data;
+       MsgInfo *old_msginfo = messageview->msginfo;
 
        if (messageview->msginfo != msginfo_update->msginfo)
                return FALSE;
 
-       if (msginfo_update->flags & MSGINFO_UPDATE_DELETED) {
-               MsgInfo *old_msginfo = messageview->msginfo;
-               messageview_clear(messageview);
-               messageview_update(messageview, old_msginfo);
-       }
+       if ((msginfo_update->flags & MSGINFO_UPDATE_DELETED) ||
+           MSG_IS_DELETED(old_msginfo->flags))
+       {
+               if (messageview->new_window) {
+                       if (old_msginfo->folder && old_msginfo->folder->total_msgs == 0) {
+                               messageview_clear(messageview);
+                               textview_show_info(messageview->mimeview->textview,
+                                       _("\n  There are no messages in this folder"));
+                               return FALSE;
+                       }
+                       
+                       if (!prefs_common.always_show_msg) {
+                               messageview_clear(messageview);
+                               textview_show_info(messageview->mimeview->textview,
+                                       MSG_IS_DELETED(old_msginfo->flags) ?
+                                       _("\n  Message has been deleted") :
+                                       _("\n  Message has been deleted or moved to another folder"));
+                       } else
+                               messageview->update_needed = TRUE;
+
+               } else {
+                       messageview_clear(messageview);
+                       messageview_update(messageview, old_msginfo);
+               }
+       } 
 
        return FALSE;
 }
 
 void messageview_set_menu_sensitive(MessageView *messageview)
 {
-       if (!messageview || !messageview->new_window) 
+       if (!messageview || !messageview->ui_manager)
                return;
-       /* do some smart things */
-       if (!messageview->menubar) return;
 
-       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/FoldAll", (prefs_common.hide_quotes == 1));
-       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Fold2", (prefs_common.hide_quotes == 2));
-       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Fold3", (prefs_common.hide_quotes == 3));
+       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/CollapseAll", (prefs_common.hide_quotes == 1));
+       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse2", (prefs_common.hide_quotes == 2));
+       cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse3", (prefs_common.hide_quotes == 3));
+       cm_menu_set_sensitive_full(messageview->ui_manager, "Menu/View/Goto/PrevHistory", messageview_nav_has_prev(messageview));
+       cm_menu_set_sensitive_full(messageview->ui_manager, "Menu/View/Goto/NextHistory", messageview_nav_has_next(messageview));
+
+       cm_menu_set_sensitive_full(messageview->ui_manager, "Menu/Message/CheckSignature", messageview->mimeview->signed_part);
 }
 
 void messageview_learn (MessageView *msgview, gboolean is_spam)
@@ -2834,3 +3017,60 @@ void messageview_list_urls (MessageView  *msgview)
        g_slist_free(newlist);
        g_hash_table_destroy(uri_hashtable);
 }
+
+static void save_part_as_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+
+       if (messageview->mimeview)
+               mimeview_save_as(messageview->mimeview);
+}
+
+static void view_part_as_text_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+
+       if (messageview->mimeview)
+               mimeview_display_as_text(messageview->mimeview);
+}
+
+static void open_part_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+
+       if (messageview->mimeview)
+               mimeview_launch(messageview->mimeview, NULL);
+}
+#ifndef G_OS_WIN32
+static void open_part_with_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+
+       if (messageview->mimeview)
+               mimeview_open_with(messageview->mimeview);
+}
+#endif
+static void check_signature_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+
+       if (messageview->mimeview)
+               mimeview_check_signature(messageview->mimeview);
+}
+
+static void goto_next_part_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+
+       if (messageview->mimeview)
+               mimeview_select_next_part(messageview->mimeview);
+}
+
+static void goto_prev_part_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+
+       if (messageview->mimeview)
+               mimeview_select_prev_part(messageview->mimeview);
+}
+