On cancelling connect dialog saving attachments, don't show error.
[modest] / src / hildon2 / modest-msg-view-window.c
index 9d751c6..6cdae1d 100644 (file)
 #include <modest-debug.h>
 #include <modest-header-window.h>
 #include <modest-account-protocol.h>
+#include <modest-hildon2-window-mgr.h>
+#include <tny-camel-msg.h>
+#include <tny-camel-bs-mime-part.h>
+#include <tny-camel-bs-msg.h>
 
 #define MYDOCS_ENV "MYDOCSDIR"
 #define DOCS_FOLDER ".documents"
@@ -229,7 +233,7 @@ static gboolean _modest_msg_view_window_map_event (GtkWidget *widget,
                                                   GdkEvent *event,
                                                   gpointer userdata);
 static void update_branding (ModestMsgViewWindow *self);
-
+static void sync_flags      (ModestMsgViewWindow *self);
 
 /* list my signals */
 enum {
@@ -290,22 +294,48 @@ static void
 save_state (ModestWindow *self)
 {
        modest_widget_memory_save (modest_runtime_get_conf (),
-                                  G_OBJECT(self), 
+                                  G_OBJECT(self),
                                   MODEST_CONF_MSG_VIEW_WINDOW_KEY);
 }
 
-static 
-gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
-                                             GtkScrollType scroll_type,
-                                             gboolean horizontal,
-                                             gpointer userdata)
+static gboolean
+modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
+                                    GtkScrollType scroll_type,
+                                    gboolean horizontal,
+                                    gpointer userdata)
 {
        ModestMsgViewWindowPrivate *priv;
-       gboolean return_value;
+       gint step = 0;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
-       g_signal_emit_by_name (priv->main_scroll, "scroll-child", scroll_type, horizontal, &return_value);
-       return return_value;
+
+       switch (scroll_type) {
+       case GTK_SCROLL_STEP_UP:
+               step = -1;
+               break;
+       case GTK_SCROLL_STEP_DOWN:
+               step = +1;
+               break;
+       case GTK_SCROLL_PAGE_UP:
+               step = -6;
+               break;
+       case GTK_SCROLL_PAGE_DOWN:
+               step = +6;
+               break;
+       case GTK_SCROLL_START:
+               step = -100;
+               break;
+       case GTK_SCROLL_END:
+               step = +100;
+               break;
+       default:
+               step = 0;
+       }
+
+       if (step)
+               modest_maemo_utils_scroll_pannable((HildonPannableArea *) priv->main_scroll, 0, step);
+
+       return (gboolean) step;
 }
 
 static void
@@ -314,7 +344,7 @@ add_scroll_binding (GtkBindingSet *binding_set,
                    GtkScrollType scroll)
 {
        guint keypad_keyval = keyval - GDK_Left + GDK_KP_Left;
-       
+
        gtk_binding_entry_add_signal (binding_set, keyval, 0,
                                      "scroll_child", 2,
                                      GTK_TYPE_SCROLL_TYPE, scroll,
@@ -394,7 +424,6 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        ModestWindowPrivate *parent_priv = NULL;
        GtkActionGroup *action_group = NULL;
        GError *error = NULL;
-       GdkPixbuf *window_icon;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
        parent_priv = MODEST_WINDOW_GET_PRIVATE(obj);
@@ -457,13 +486,6 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        /* Init window */
        init_window (MODEST_MSG_VIEW_WINDOW(obj));
        
-       /* Set window icon */
-       window_icon = modest_platform_get_icon (MODEST_APP_MSG_VIEW_ICON, MODEST_ICON_SIZE_BIG); 
-       if (window_icon) {
-               gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
-               g_object_unref (window_icon);
-       }       
-       
        hildon_program_add_window (hildon_program_get_instance(),
                                   HILDON_WINDOW(obj));
 
@@ -513,6 +535,10 @@ init_window (ModestMsgViewWindow *obj)
        modest_msg_view_set_shadow_type (MODEST_MSG_VIEW (priv->msg_view), GTK_SHADOW_NONE);
        main_vbox = gtk_vbox_new  (FALSE, 6);
        priv->main_scroll = hildon_pannable_area_new ();
+        g_object_set (G_OBJECT (priv->main_scroll),
+                     "mov-mode", HILDON_MOVEMENT_MODE_BOTH,
+                     "hovershoot-max", 0,
+                     NULL);
        gtk_container_add (GTK_CONTAINER (priv->main_scroll), priv->msg_view);
        gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_scroll, TRUE, TRUE, 0);
        gtk_container_add   (GTK_CONTAINER(obj), main_vbox);
@@ -581,7 +607,7 @@ modest_msg_view_window_disconnect_signals (ModestWindow *self)
                                                           MODEST_HEADER_VIEW_OBSERVER(self));
                }
        }
-}      
+}
 
 static void
 modest_msg_view_window_finalize (GObject *obj)
@@ -766,6 +792,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
                          G_CALLBACK (modest_ui_actions_on_details), obj);
        g_signal_connect (G_OBJECT(priv->msg_view), "link_contextual",
                          G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj);
+       g_signal_connect (G_OBJECT(priv->msg_view), "limit_error",
+                         G_CALLBACK (modest_ui_actions_on_limit_error), obj);
        g_signal_connect (G_OBJECT (priv->msg_view), "fetch_image",
                          G_CALLBACK (on_fetch_image), obj);
 
@@ -861,7 +889,7 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        /* Setup row references and connect signals */
        priv->header_model = g_object_ref (model);
 
-       if (row_reference) {
+       if (row_reference && gtk_tree_row_reference_valid (row_reference)) {
                priv->row_reference = gtk_tree_row_reference_copy (row_reference);
                priv->next_row_reference = gtk_tree_row_reference_copy (row_reference);
                select_next_valid_row (model, &(priv->next_row_reference), TRUE, priv->is_outbox);
@@ -926,8 +954,6 @@ modest_msg_view_window_new_from_uid (const gchar *modest_account_name,
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
-
-
        is_merge = g_str_has_prefix (msg_uid, "merge:");
 
        /* Get the account */
@@ -935,7 +961,6 @@ modest_msg_view_window_new_from_uid (const gchar *modest_account_name,
                account = tny_account_store_find_account (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
                                                          msg_uid);
 
-       
        if (is_merge || account) {
                TnyFolder *folder = NULL;
 
@@ -968,6 +993,8 @@ modest_msg_view_window_new_from_uid (const gchar *modest_account_name,
                                        update_window_title (MODEST_MSG_VIEW_WINDOW (window));
                                        update_branding (MODEST_MSG_VIEW_WINDOW (window));
                                        g_object_unref (msg);
+                                       /* Sync flags to server */
+                                       sync_flags (MODEST_MSG_VIEW_WINDOW (window));
                                } else {
                                        message_reader (window, priv, NULL, msg_uid, folder, NULL);
                                }
@@ -1028,7 +1055,7 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
        priv->header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
        g_object_ref (priv->header_model);
 
-       if (row_reference) {
+       if (row_reference && gtk_tree_row_reference_valid (row_reference)) {
                priv->row_reference = gtk_tree_row_reference_copy (row_reference);
                priv->next_row_reference = gtk_tree_row_reference_copy (row_reference);
                select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE, priv->is_outbox);
@@ -1063,17 +1090,18 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), NULL);
        update_branding (MODEST_MSG_VIEW_WINDOW (window));
 
-       path = gtk_tree_row_reference_get_path (row_reference);
-       if (gtk_tree_model_get_iter (priv->header_model, &iter, path)) {
-               TnyHeader *header;
-               gtk_tree_model_get (priv->header_model, &iter, 
-                                   TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
-                                   &header, -1);
-               message_reader (window, priv, header, NULL, NULL, row_reference);
-               g_object_unref (header);
+       if (priv->row_reference) {
+               path = gtk_tree_row_reference_get_path (priv->row_reference);
+               if (gtk_tree_model_get_iter (priv->header_model, &iter, path)) {
+                       TnyHeader *header;
+                       gtk_tree_model_get (priv->header_model, &iter, 
+                                           TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
+                                           &header, -1);
+                       message_reader (window, priv, header, NULL, NULL, priv->row_reference);
+                       g_object_unref (header);
+               }
+               gtk_tree_path_free (path);
        }
-       gtk_tree_path_free (path);
-
        /* Check dimming rules */
        modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
        modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
@@ -1687,7 +1715,6 @@ modest_msg_view_window_zoom_minus (ModestWindow *window)
        modest_zoomable_set_zoom (MODEST_ZOOMABLE (priv->msg_view), zoom_level);
 
        return TRUE;
-       
 }
 
 static gboolean
@@ -1707,52 +1734,11 @@ modest_msg_view_window_key_event (GtkWidget *window,
                        gtk_widget_event (focus, copy);
                        gdk_event_free (copy);
                        return TRUE;
-               } else 
-                       return FALSE;
-       }
-       if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up ||
-           event->keyval == GDK_Down || event->keyval == GDK_KP_Down ||
-           event->keyval == GDK_Page_Up || event->keyval == GDK_KP_Page_Up ||
-           event->keyval == GDK_Page_Down || event->keyval == GDK_KP_Page_Down ||
-           event->keyval == GDK_Home || event->keyval == GDK_KP_Home ||
-           event->keyval == GDK_End || event->keyval == GDK_KP_End) {
-               /* ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); */
-               /* gboolean return_value; */
-
-               if (event->type == GDK_KEY_PRESS) {
-                       GtkScrollType scroll_type;
-
-                       switch (event->keyval) {
-                       case GDK_Up: 
-                       case GDK_KP_Up:
-                               scroll_type = GTK_SCROLL_STEP_UP; break;
-                       case GDK_Down: 
-                       case GDK_KP_Down:
-                               scroll_type = GTK_SCROLL_STEP_DOWN; break;
-                       case GDK_Page_Up:
-                       case GDK_KP_Page_Up:
-                               scroll_type = GTK_SCROLL_PAGE_UP; break;
-                       case GDK_Page_Down:
-                       case GDK_KP_Page_Down:
-                               scroll_type = GTK_SCROLL_PAGE_DOWN; break;
-                       case GDK_Home:
-                       case GDK_KP_Home:
-                               scroll_type = GTK_SCROLL_START; break;
-                       case GDK_End:
-                       case GDK_KP_End:
-                               scroll_type = GTK_SCROLL_END; break;
-                       default: scroll_type = GTK_SCROLL_NONE;
-                       }
-
-                       /* g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child",  */
-                       /*                     scroll_type, FALSE, &return_value); */
-                       return FALSE;
                } else {
                        return FALSE;
                }
-       } else {
-               return FALSE;
        }
+       return FALSE;
 }
 
 gboolean
@@ -1897,6 +1883,7 @@ message_reader_performer (gboolean canceled,
        info = (MsgReaderInfo *) user_data;
        if (canceled || err) {
                update_window_title (MODEST_MSG_VIEW_WINDOW (parent_window));
+               modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (parent_window));
                goto frees;
        }
 
@@ -1952,13 +1939,16 @@ message_reader (ModestMsgViewWindow *window,
                GtkTreeRowReference *row_reference)
 {
        ModestWindowMgr *mgr;
-       TnyAccount *account;
+       TnyAccount *account = NULL;
        MsgReaderInfo *info;
 
        /* We set the header from model while we're loading */
        tny_header_view_set_header (TNY_HEADER_VIEW (priv->msg_view), header);
        gtk_window_set_title (GTK_WINDOW (window), _CS("ckdg_pb_updating"));
 
+       if (header)
+               folder = NULL;
+
        if (folder)
                g_object_ref (folder);
 
@@ -2003,7 +1993,8 @@ message_reader (ModestMsgViewWindow *window,
                                                                       TNY_FOLDER_STORE (folder),
                                                                       message_reader_performer, 
                                                                       info);
-                       g_object_unref (folder);
+                       if (folder)
+                               g_object_unref (folder);
                        return TRUE;
                }
        }
@@ -2011,7 +2002,9 @@ message_reader (ModestMsgViewWindow *window,
        if (header) {
                folder = tny_header_get_folder (header);
        }
-       account = tny_folder_get_account (folder);
+        if (folder)
+               account = tny_folder_get_account (folder);
+
        info = g_slice_new (MsgReaderInfo);
        info->msg_uid = g_strdup (msg_uid);
        if (folder)
@@ -2028,13 +2021,15 @@ message_reader (ModestMsgViewWindow *window,
                info->row_reference = NULL;
 
        message_reader_performer (FALSE, NULL, (GtkWindow *) window, account, info);
-       g_object_unref (account);
-       g_object_unref (folder);
+        if (account)
+               g_object_unref (account);
+       if (folder)
+               g_object_unref (folder);
 
        return TRUE;
 }
 
-gboolean        
+gboolean
 modest_msg_view_window_select_next_message (ModestMsgViewWindow *window)
 {
        ModestMsgViewWindowPrivate *priv;
@@ -2057,9 +2052,14 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window)
           tree models and reports the deletion when the row is still
           there */
        if (!gtk_tree_row_reference_valid (priv->next_row_reference)) {
+               if (priv->next_row_reference) {
+                       gtk_tree_row_reference_free (priv->next_row_reference);
+               }
                if (gtk_tree_row_reference_valid (priv->row_reference)) {
                        priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
                        select_next_valid_row (priv->header_model, &(priv->next_row_reference), FALSE, priv->is_outbox);
+               } else {
+                       priv->next_row_reference = NULL;
                }
        }
        if (priv->next_row_reference)
@@ -2101,6 +2101,11 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window)
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
+       if (priv->row_reference && !gtk_tree_row_reference_valid (priv->row_reference)) {
+               gtk_tree_row_reference_free (priv->row_reference);
+               priv->row_reference = NULL;
+       }
+
        /* Return inmediatly if there is no header model */
        if (!priv->header_model || !priv->row_reference)
                return FALSE;
@@ -2156,6 +2161,7 @@ view_msg_cb (ModestMailOperation *mail_op,
                if (self) {
                        /* Restore window title */
                        update_window_title (self);
+                       modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (self));
                        g_object_unref (self);
                }
                return;
@@ -2167,13 +2173,91 @@ view_msg_cb (ModestMailOperation *mail_op,
                        gtk_tree_row_reference_free (row_reference);
                self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
                if (self) {
+                       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+                       /* First we check if the parent is a folder window */
+                       if (priv->msg_uid && !modest_hildon2_window_mgr_get_folder_window (MODEST_HILDON2_WINDOW_MGR (modest_runtime_get_window_mgr ()))) {
+                               gboolean is_merge;
+                               TnyAccount *account = NULL;
+                               GtkWidget *header_window = NULL;
+
+                               is_merge = g_str_has_prefix (priv->msg_uid, "merge:");
+
+                               /* Get the account */
+                               if (!is_merge)
+                                       account = tny_account_store_find_account (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
+                                                                                 priv->msg_uid);
+
+                               if (is_merge || account) {
+                                       TnyFolder *folder = NULL;
+
+                                       /* Try to get the message, if it's already downloaded
+                                          we don't need to connect */
+                                       if (account) {
+                                               folder = modest_tny_folder_store_find_folder_from_uri (TNY_FOLDER_STORE (account), 
+                                                                                                      priv->msg_uid);
+                                       } else {
+                                               ModestTnyAccountStore *account_store;
+                                               ModestTnyLocalFoldersAccount *local_folders_account;
+
+                                               account_store = modest_runtime_get_account_store ();
+                                               local_folders_account = MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (
+                                                       modest_tny_account_store_get_local_folders_account (account_store));
+                                               folder = modest_tny_local_folders_account_get_merged_outbox (local_folders_account);
+                                               g_object_unref (local_folders_account);
+                                       }
+                                       if (account) g_object_unref (account);
+
+                                       if (folder) {
+                                               header_window = (GtkWidget *)
+                                                       modest_header_window_new (
+                                                               folder, 
+                                                               modest_window_get_active_account (MODEST_WINDOW (self)), 
+                                                               modest_window_get_active_mailbox (MODEST_WINDOW (self)));
+                                               if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
+                                                                                       MODEST_WINDOW (header_window),
+                                                                                       NULL)) {
+                                                       gtk_widget_destroy (GTK_WIDGET (header_window));
+                                               } else {
+                                                       gtk_widget_show_all (GTK_WIDGET (header_window));
+                                               }
+                                               g_object_unref (folder);
+                                       }
+                               }
+                       }
+
+
                        /* Restore window title */
                        update_window_title (self);
+                       modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (self));
                        g_object_unref (self);
                }
                return;
        }
 
+       if (msg && TNY_IS_CAMEL_BS_MSG (msg)) {
+               TnyMimePart *body;
+               body = modest_tny_msg_find_body_part (msg, TRUE);
+               
+               if (body && !tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (body))) {
+                       /* We have body structure but not the body mime part. What we do
+                        * is restarting load of message */
+                       self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
+                       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+
+                       tny_header_unset_flag (TNY_HEADER (header), TNY_HEADER_FLAG_CACHED);
+
+                       modest_msg_view_window_reload (self);
+
+                       if (row_reference)
+                               gtk_tree_row_reference_free (row_reference);
+                       g_object_unref (body);
+                       return;
+               }
+
+               if (body)
+                       g_object_unref  (body);
+       }
+
        /* Get the window */ 
        self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
@@ -2182,12 +2266,16 @@ view_msg_cb (ModestMailOperation *mail_op,
        /* Update the row reference */
        if (priv->row_reference != NULL) {
                gtk_tree_row_reference_free (priv->row_reference);
-               priv->row_reference = gtk_tree_row_reference_copy (row_reference);
+               priv->row_reference = (row_reference && gtk_tree_row_reference_valid (row_reference))?gtk_tree_row_reference_copy (row_reference):NULL;
                if (priv->next_row_reference != NULL) {
                        gtk_tree_row_reference_free (priv->next_row_reference);
                }
-               priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
-               select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE, priv->is_outbox);
+               if (priv->row_reference) {
+                       priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
+                       select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE, priv->is_outbox);
+               } else {
+                       priv->next_row_reference = NULL;
+               }
        }
 
        /* Mark header as read */
@@ -2210,13 +2298,18 @@ view_msg_cb (ModestMailOperation *mail_op,
        }
 
        /* Notify the observers */
-       g_signal_emit (G_OBJECT (self), signals[MSG_CHANGED_SIGNAL], 
+       g_signal_emit (G_OBJECT (self), signals[MSG_CHANGED_SIGNAL],
                       0, priv->header_model, priv->row_reference);
 
+       /* Sync the flags if the message is not opened from a header
+          model, i.e, if it's opened from a notification */
+       if (!priv->header_model)
+               sync_flags (self);
+
        /* Frees */
        g_object_unref (self);
        if (row_reference)
-               gtk_tree_row_reference_free (row_reference);            
+               gtk_tree_row_reference_free (row_reference);
 }
 
 TnyFolderType
@@ -2255,7 +2348,7 @@ modest_msg_view_window_update_priority (ModestMsgViewWindow *window)
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
-       if (priv->header_model && priv->row_reference) {
+       if (priv->header_model && priv->row_reference && gtk_tree_row_reference_valid (priv->row_reference)) {
                GtkTreeIter iter;
                GtkTreePath *path = NULL;
 
@@ -2303,24 +2396,22 @@ toolbar_resize (ModestMsgViewWindow *self)
        static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?120:120;
 
        if (parent_priv->toolbar) {
-               /* left size buttons */
+               /* Set expandable and homogeneous tool buttons */
                widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
+               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
+               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
                widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReplyAll");
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
+               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
+               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
+               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageForward");
+               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
+               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
                widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
+               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
+               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
                widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDownloadExternalImages");
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
-               gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
-
+               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
+               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
                gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->next_toolitem), TRUE);
                gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->next_toolitem), TRUE);
                gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->prev_toolitem), TRUE);
@@ -2562,6 +2653,7 @@ modest_msg_view_window_get_attachments (ModestMsgViewWindow *win)
 typedef struct {
        ModestMsgViewWindow *self;
        gchar *file_path;
+       gchar *attachment_uid;
 } DecodeAsyncHelper;
 
 static void
@@ -2572,33 +2664,104 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
                                   gpointer user_data)
 {
        DecodeAsyncHelper *helper = (DecodeAsyncHelper *) user_data;
-
-       /* It could happen that the window was closed */
-       if (GTK_WIDGET_VISIBLE (helper->self))
-               set_progress_hint (helper->self, FALSE);
+       const gchar *content_type;
 
        if (cancelled || err) {
                if (err) {
-                       gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+                       gchar *msg;
+                       if ((err->domain == TNY_ERROR_DOMAIN) && 
+                           (err->code == TNY_IO_ERROR_WRITE) &&
+                           (errno == ENOSPC)) {
+                               msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+                       } else {
+                               msg = g_strdup (_("mail_ib_file_operation_failed"));
+                       }
                        modest_platform_information_banner (NULL, NULL, msg);
                        g_free (msg);
                }
                goto free;
        }
 
-       /* make the file read-only */
-       g_chmod(helper->file_path, 0444);
+       /* It could happen that the window was closed. So we
+          assume it is a cancelation */
+       if (!GTK_WIDGET_VISIBLE (helper->self))
+               goto free;
+
+       /* Remove the progress hint */
+       set_progress_hint (helper->self, FALSE);
+
+       content_type = tny_mime_part_get_content_type (mime_part);
+       if (g_str_has_prefix (content_type, "message/rfc822")) {
+               ModestWindowMgr *mgr;
+               ModestWindow *msg_win = NULL;
+               TnyMsg * msg;
+               gchar *account;
+               const gchar *mailbox;
+               TnyStream *file_stream;
+               gint fd;
+
+               fd = g_open (helper->file_path, O_RDONLY, 0644);
+               if (fd != -1) {
+                       file_stream = tny_fs_stream_new (fd);
 
-       /* Activate the file */
-       modest_platform_activate_file (helper->file_path, tny_mime_part_get_content_type (mime_part));
+                       mgr = modest_runtime_get_window_mgr ();
+
+                       account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (helper->self)));
+                       mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (helper->self));
+
+                       if (!account)
+                               account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
+
+                       msg = tny_camel_msg_new ();
+                       tny_camel_msg_parse (msg, file_stream);
+                       msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (msg), account, mailbox, helper->attachment_uid);
+                       modest_window_set_zoom (MODEST_WINDOW (msg_win),
+                                               modest_window_get_zoom (MODEST_WINDOW (helper->self)));
+                       if (modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (helper->self)))
+                               gtk_widget_show_all (GTK_WIDGET (msg_win));
+                       else
+                               gtk_widget_destroy (GTK_WIDGET (msg_win));
+                       g_object_unref (msg);
+                       g_object_unref (file_stream);
+               } else {
+                       modest_platform_information_banner (NULL, NULL, _("mail_ib_file_operation_failed"));
+               }
+
+       } else {
+
+               /* make the file read-only */
+               g_chmod(helper->file_path, 0444);
+
+               /* Activate the file */
+               modest_platform_activate_file (helper->file_path, tny_mime_part_get_content_type (mime_part));
+       }
 
  free:
        /* Frees */
        g_object_unref (helper->self);
        g_free (helper->file_path);
+       g_free (helper->attachment_uid);
        g_slice_free (DecodeAsyncHelper, helper);
 }
 
+static void
+view_attachment_connect_handler (gboolean canceled,
+                                GError *err,
+                                GtkWindow *parent_window,
+                                TnyAccount *account,
+                                TnyMimePart *part)
+{
+
+       if (canceled || err) {
+               g_object_unref (part);
+               return;
+       }
+
+       modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (parent_window),
+                                               part);
+       g_object_unref (part);
+}
+
 void
 modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, 
                                        TnyMimePart *mime_part)
@@ -2648,6 +2811,28 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
        if (tny_mime_part_is_purged (mime_part))
                goto frees;
 
+       if (TNY_IS_CAMEL_BS_MIME_PART (mime_part) &&
+           !tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (mime_part))) {
+               gboolean is_merge;
+               TnyAccount *account;
+
+               is_merge = g_str_has_prefix (priv->msg_uid, "merge:");
+               account = NULL;
+               /* Get the account */
+               if (!is_merge)
+                       account = tny_account_store_find_account (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
+                                                                 priv->msg_uid);
+
+               if (!tny_device_is_online (modest_runtime_get_device())) {
+                       modest_platform_connect_and_perform (GTK_WINDOW (window),
+                                                            TRUE,
+                                                            TNY_ACCOUNT (account),
+                                                            (ModestConnectedPerformer) view_attachment_connect_handler,
+                                                            g_object_ref (mime_part));
+                       goto frees;
+               }
+       }
+
        if (!modest_tny_mime_part_is_msg (mime_part) && tny_mime_part_get_filename (mime_part)) {
                gchar *filepath = NULL;
                const gchar *att_filename = tny_mime_part_get_filename (mime_part);
@@ -2657,7 +2842,11 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                                                               &filepath);
 
                if (temp_stream != NULL) {
+                       ModestAccountMgr *mgr;
                        DecodeAsyncHelper *helper;
+                       gboolean decode_in_provider;
+                       ModestProtocol *protocol;
+                       const gchar *account; 
 
                        /* Activate progress hint */
                        set_progress_hint (window, TRUE);
@@ -2665,11 +2854,33 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                        helper = g_slice_new0 (DecodeAsyncHelper);
                        helper->self = g_object_ref (window);
                        helper->file_path = g_strdup (filepath);
+                       helper->attachment_uid = g_strdup (attachment_uid);
+
+                       decode_in_provider = FALSE;
+                       mgr = modest_runtime_get_account_mgr ();
+                       account = modest_window_get_active_account (MODEST_WINDOW (window));
+                       if (modest_account_mgr_account_is_multimailbox (mgr, account, &protocol)) {
+                               if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
+                                       gchar *uri;
+                                       uri = g_strconcat ("file://", filepath, NULL);
+                                       decode_in_provider = 
+                                               modest_account_protocol_decode_part_to_stream_async (
+                                                       MODEST_ACCOUNT_PROTOCOL (protocol),
+                                                       mime_part,
+                                                       filepath,
+                                                       TNY_STREAM (temp_stream),
+                                                       on_decode_to_stream_async_handler,
+                                                       NULL,
+                                                       helper);
+                                       g_free (uri);
+                               }
+                       }
 
-                       tny_mime_part_decode_to_stream_async (mime_part, TNY_STREAM (temp_stream),
-                                                             on_decode_to_stream_async_handler,
-                                                             NULL,
-                                                             helper);
+                       if (!decode_in_provider)
+                               tny_mime_part_decode_to_stream_async (mime_part, TNY_STREAM (temp_stream),
+                                                                     on_decode_to_stream_async_handler,
+                                                                     NULL,
+                                                                     helper);
                        g_object_unref (temp_stream);
                        /* NOTE: files in the temporary area will be automatically
                         * cleaned after some time if they are no longer in use */
@@ -2775,6 +2986,8 @@ typedef struct
 {
        GList *pairs;
        GnomeVFSResult result;
+       gchar *uri;
+       ModestMsgViewWindow *window;
 } SaveMimePartInfo;
 
 static void save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct);
@@ -2795,6 +3008,9 @@ save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
        }
        g_list_free (info->pairs);
        info->pairs = NULL;
+       g_free (info->uri);
+       g_object_unref (info->window);
+       info->window = NULL;
        if (with_struct) {
                g_slice_free (SaveMimePartInfo, info);
        }
@@ -2807,10 +3023,18 @@ idle_save_mime_part_show_result (SaveMimePartInfo *info)
         * hildon_banner_show_information is or does Gtk+ code */
 
        gdk_threads_enter (); /* CHECKED */
-       if (info->result == GNOME_VFS_OK) {
+       if (info->result == GNOME_VFS_ERROR_CANCELLED) {
+               /* nothing */
+       } else if (info->result == GNOME_VFS_OK) {
                hildon_banner_show_information (NULL, NULL, _CS("sfil_ib_saved"));
        } else if (info->result == GNOME_VFS_ERROR_NO_SPACE) {
-               gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+               gchar *msg = NULL;
+
+               /* Check if the uri belongs to the external mmc */
+               if (g_str_has_prefix (info->uri, g_getenv (MODEST_MMC1_VOLUMEPATH_ENV)))
+                       msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+               else
+                       msg = g_strdup (_KR("cerm_memory_card_full"));
                modest_platform_information_banner (NULL, NULL, msg);
                g_free (msg);
        } else {
@@ -2822,6 +3046,48 @@ idle_save_mime_part_show_result (SaveMimePartInfo *info)
        return FALSE;
 }
 
+static void
+save_mime_part_to_file_connect_handler (gboolean canceled,
+                                       GError *err,
+                                       GtkWindow *parent_window,
+                                       TnyAccount *account,
+                                       SaveMimePartInfo *info)
+{
+       if (canceled || err) {
+               if (canceled && !err) {
+                       info->result = GNOME_VFS_ERROR_CANCELLED;
+               }
+               g_idle_add ((GSourceFunc) idle_save_mime_part_show_result, info);
+       } else {
+               g_thread_create ((GThreadFunc)save_mime_part_to_file, info, FALSE, NULL);
+       }
+}
+
+static gboolean
+save_mime_part_to_file_connect_idle (SaveMimePartInfo *info)
+{
+       gboolean is_merge;
+       TnyAccount *account;
+       ModestMsgViewWindowPrivate *priv;
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (info->window);
+
+       is_merge = g_str_has_prefix (priv->msg_uid, "merge:");
+       account = NULL;
+
+       /* Get the account */
+       if (!is_merge)
+               account = tny_account_store_find_account (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
+                                                         priv->msg_uid);
+
+       modest_platform_connect_and_perform (GTK_WINDOW (info->window),
+                                            TRUE,
+                                            TNY_ACCOUNT (account),
+                                            (ModestConnectedPerformer) save_mime_part_to_file_connect_handler,
+                                            info);
+       return FALSE;
+}
+
 static gpointer
 save_mime_part_to_file (SaveMimePartInfo *info)
 {
@@ -2829,11 +3095,42 @@ save_mime_part_to_file (SaveMimePartInfo *info)
        TnyStream *stream;
        SaveMimePartPair *pair = (SaveMimePartPair *) info->pairs->data;
 
+       if (TNY_IS_CAMEL_BS_MIME_PART (pair->part) &&
+           !tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (pair->part))) {
+               g_idle_add ((GSourceFunc) save_mime_part_to_file_connect_idle, info);
+               return NULL;
+       }
+
        info->result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0644);
        if (info->result == GNOME_VFS_OK) {
                GError *error = NULL;
+               gboolean decode_in_provider;
+               gssize written;
+               ModestAccountMgr *mgr;
+               const gchar *account;
+               ModestProtocol *protocol = NULL;
+
                stream = tny_vfs_stream_new (handle);
-               if (tny_mime_part_decode_to_stream (pair->part, stream, &error) < 0) {
+
+               decode_in_provider = FALSE;
+               mgr = modest_runtime_get_account_mgr ();
+               account = modest_window_get_active_account (MODEST_WINDOW (info->window));
+               if (modest_account_mgr_account_is_multimailbox (mgr, account, &protocol)) {
+                       if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
+                               decode_in_provider = 
+                                       modest_account_protocol_decode_part_to_stream (
+                                               MODEST_ACCOUNT_PROTOCOL (protocol),
+                                               pair->part,
+                                               pair->filename,
+                                               stream,
+                                               &written,
+                                               &error);
+                       }
+               }
+               if (!decode_in_provider)
+                       written = tny_mime_part_decode_to_stream (pair->part, stream, &error);
+
+               if (written < 0) {
                        g_warning ("modest: could not save attachment %s: %d (%s)\n", pair->filename, error?error->code:-1, error?error->message:"Unknown error");
 
                        if ((error->domain == TNY_ERROR_DOMAIN) && 
@@ -2872,11 +3169,14 @@ save_mime_parts_to_file_with_checks (GtkWindow *parent,
 
         for (iter = files; (iter != NULL) && (replaced_files < 2); iter = g_list_next(iter)) {
                 SaveMimePartPair *pair = iter->data;
-                if (modest_utils_file_exists (pair->filename)) {
+               gchar *unescaped = g_uri_unescape_string (pair->filename, NULL);
+
+                if (modest_utils_file_exists (unescaped)) {
                        replaced_files++;
                        if (replaced_files == 1)
                                to_replace = iter;
                 }
+               g_free (unescaped);
         }
        if (replaced_files) {
                gint response;
@@ -2909,6 +3209,11 @@ save_mime_parts_to_file_with_checks (GtkWindow *parent,
 
 }
 
+typedef struct _SaveAttachmentsInfo {
+       TnyList *attachments_list;
+       ModestMsgViewWindow *window;
+} SaveAttachmentsInfo;
+
 static void
 save_attachments_response (GtkDialog *dialog,
                           gint       arg1,
@@ -2918,17 +3223,18 @@ save_attachments_response (GtkDialog *dialog,
        gchar *chooser_uri;
        GList *files_to_save = NULL;
        gchar *current_folder;
+       SaveAttachmentsInfo *sa_info = (SaveAttachmentsInfo *) user_data;
 
-       mime_parts = TNY_LIST (user_data);
+       mime_parts = TNY_LIST (sa_info->attachments_list);
 
        if (arg1 != GTK_RESPONSE_OK)
                goto end;
 
        chooser_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
        current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
-       if (current_folder && current_folder != '\0') {
+       if (current_folder && *current_folder != '\0') {
                GError *err = NULL;
-               modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH, 
+               modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH,
                                        current_folder,&err);
                if (err != NULL) {
                        g_debug ("Error storing latest used folder: %s", err->message);
@@ -2938,8 +3244,18 @@ save_attachments_response (GtkDialog *dialog,
        g_free (current_folder);
 
        if (!modest_utils_folder_writable (chooser_uri)) {
-               hildon_banner_show_information 
-                       (NULL, NULL, _FM("sfil_ib_readonly_location"));
+               const gchar *err_msg;
+
+#ifdef MODEST_PLATFORM_MAEMO
+               if (modest_maemo_utils_in_usb_mode ()) {
+                       err_msg = dgettext ("hildon-status-bar-usb", "usbh_ib_mmc_usb_connected");
+               } else {
+                       err_msg = _FM("sfil_ib_readonly_location");
+               }
+#else
+               err_msg = _FM("sfil_ib_readonly_location");
+#endif
+               hildon_banner_show_information (NULL, NULL, err_msg);
        } else {
                TnyIterator *iter;
 
@@ -2969,18 +3285,22 @@ save_attachments_response (GtkDialog *dialog,
                }
                g_object_unref (iter);
        }
-       g_free (chooser_uri);
 
        if (files_to_save != NULL) {
                SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
                info->pairs = files_to_save;
                info->result = TRUE;
+               info->uri = g_strdup (chooser_uri);
+               info->window = g_object_ref (sa_info->window);
                save_mime_parts_to_file_with_checks ((GtkWindow *) dialog, info);
        }
+       g_free (chooser_uri);
 
  end:
        /* Free and close the dialog */
        g_object_unref (mime_parts);
+       g_object_unref (sa_info->window);
+       g_slice_free (SaveAttachmentsInfo, sa_info);
        gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
@@ -2993,6 +3313,7 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window,
        gchar *conf_folder = NULL;
        gchar *filename = NULL;
        gchar *save_multiple_str = NULL;
+       const gchar *root_folder = "file:///";
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
@@ -3045,14 +3366,26 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window,
        save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), 
                                                      GTK_FILE_CHOOSER_ACTION_SAVE);
 
-       /* set folder */
-       conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH, NULL);
+       /* Get last used folder */
+       conf_folder = modest_conf_get_string (modest_runtime_get_conf (),
+                                             MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH, NULL);
+
+       /* File chooser stops working if we select "file:///" as current folder */
+       if (conf_folder && g_ascii_strcasecmp (root_folder, conf_folder) != 0) {
+               g_free (conf_folder);
+               conf_folder = NULL;
+       }
+
        if (conf_folder && conf_folder[0] != '\0') {
                gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (save_dialog), conf_folder);
        } else {
                gchar *docs_folder;
-               /* Set the default folder to images folder */
-               docs_folder = g_build_filename (g_getenv (MYDOCS_ENV), DOCS_FOLDER, NULL);
+               /* Set the default folder to documents folder */
+               docs_folder = (gchar *) g_strdup(g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
+               if (!docs_folder) {
+                       /* fallback */
+                       docs_folder = g_build_filename (g_getenv (MYDOCS_ENV), DOCS_FOLDER, NULL);
+               }
                gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (save_dialog), docs_folder);
                g_free (docs_folder);
        }
@@ -3069,13 +3402,18 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window,
        if (save_multiple_str) {
                g_object_set (G_OBJECT (save_dialog), "save-multiple", save_multiple_str, NULL);
                gtk_window_set_title (GTK_WINDOW (save_dialog), _FM("sfil_ti_save_objects_files"));
+               g_free (save_multiple_str);
        }
 
        /* We must run this asynchronously, because the hildon dialog
           performs a gtk_dialog_run by itself which leads to gdk
           deadlocks */
+       SaveAttachmentsInfo *sa_info;
+       sa_info = g_slice_new (SaveAttachmentsInfo);
+       sa_info->attachments_list = mime_parts;
+       sa_info->window = g_object_ref (window);
        g_signal_connect (save_dialog, "response", 
-                         G_CALLBACK (save_attachments_response), mime_parts);
+                         G_CALLBACK (save_attachments_response), sa_info);
 
        gtk_widget_show_all (save_dialog);
 }
@@ -3421,14 +3759,15 @@ setup_menu (ModestMsgViewWindow *self)
                                           APP_MENU_CALLBACK (modest_msg_view_window_show_find_toolbar),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_find_in_msg));
 
-       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_move_messages"), NULL,
+       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self),
+                                          dngettext(GETTEXT_PACKAGE,
+                                                    "mcen_me_move_message",
+                                                    "mcen_me_move_messages",
+                                                    1),
+                                          NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_on_move_to),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_move_to));
 
-       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_forward"), "<Control>d",
-                                          APP_MENU_CALLBACK (modest_ui_actions_on_forward),
-                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_reply_msg));
-
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_mark_as_read"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_on_mark_as_read),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_mark_as_read_msg_in_view));
@@ -3463,7 +3802,6 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
        GSList *recipients = NULL;
        TnyMsg *msg = NULL;
-       gboolean contacts_to_add = FALSE;
 
        msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
        if (msg == NULL) {
@@ -3479,51 +3817,11 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
                g_object_unref (msg);
        }
 
-       if (recipients != NULL) {
-               GtkWidget *picker_dialog;
-               GtkWidget *selector;
-               GSList *node;
-               gchar *selected = NULL;
-
-               selector = hildon_touch_selector_new_text ();
-               g_object_ref (selector);
-
-               for (node = recipients; node != NULL; node = g_slist_next (node)) {
-                       if (!modest_address_book_has_address ((const gchar *) node->data)) {
-                               hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector), 
-                                                                  (const gchar *) node->data);
-                               contacts_to_add = TRUE;
-                       }
-               }
-
-               if (contacts_to_add) {
-                       gint picker_result;
-
-                       picker_dialog = hildon_picker_dialog_new (GTK_WINDOW (self));
-                       gtk_window_set_title (GTK_WINDOW (picker_dialog), _("mcen_me_viewer_addtocontacts"));
-
-                       hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (picker_dialog), 
-                                                          HILDON_TOUCH_SELECTOR (selector));
-                       
-                       picker_result = gtk_dialog_run (GTK_DIALOG (picker_dialog));
-
-                       if (picker_result == GTK_RESPONSE_OK) {
-                               selected = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
-                       }
-                       gtk_widget_destroy (picker_dialog);
-
-                       if (selected)
-                               modest_address_book_add_address (selected);
-                       g_free (selected);
-
-               } else {
-
-                       g_object_unref (selector);
-
-               }
+       if (recipients) {
+               /* Offer the user to add recipients to the address book */
+               modest_address_book_add_address_list_with_selector (recipients, (GtkWindow *) self);
+               g_slist_foreach (recipients, (GFunc) g_free, NULL); g_slist_free (recipients);
        }
-       
-       if (recipients) {g_slist_foreach (recipients, (GFunc) g_free, NULL); g_slist_free (recipients);}
 }
 
 static gboolean 
@@ -3562,18 +3860,38 @@ void
 modest_msg_view_window_reload (ModestMsgViewWindow *self)
 {
        ModestMsgViewWindowPrivate *priv;
-       TnyHeader *header;
+       const gchar *msg_uid;
+       TnyHeader *header = NULL;
+       TnyFolder *folder = NULL;
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
-       header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (self));     
 
-       if (!message_reader (self, priv, header, NULL, NULL, priv->row_reference)) {
-               g_warning ("Shouldn't happen, trying to reload a message failed");
-       }
+       header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (self));
+       if (!header)
+               return;
 
+       folder = tny_header_get_folder (header);
        g_object_unref (header);
+
+       if (!folder)
+               return;
+
+       msg_uid = modest_msg_view_window_get_message_uid (self);
+        if (msg_uid) {
+               GtkTreeRowReference *row_reference;
+
+               if (priv->row_reference && gtk_tree_row_reference_valid (priv->row_reference)) {
+                       row_reference = priv->row_reference;
+               } else {
+                       row_reference = NULL;
+               }
+               if (!message_reader (self, priv, NULL, msg_uid, folder, row_reference))
+                       g_warning ("Shouldn't happen, trying to reload a message failed");
+       }
+
+       g_object_unref (folder);
 }
 
 static void
@@ -3606,3 +3924,35 @@ update_branding (ModestMsgViewWindow *self)
        modest_msg_view_set_branding (MODEST_MSG_VIEW (priv->msg_view), service_name, service_icon);
        g_free (service_name);
 }
+
+static void
+sync_flags (ModestMsgViewWindow *self)
+{
+       TnyHeader *header = NULL;
+
+       header = modest_msg_view_window_get_header (self);
+       if (!header) {
+               TnyMsg *msg = modest_msg_view_window_get_message (self);
+               if (msg) {
+                       header = tny_msg_get_header (msg);
+                       g_object_unref (msg);
+               }
+       }
+
+       if (header) {
+               TnyFolder *folder = tny_header_get_folder (header);
+
+               if (folder) {
+                       ModestMailOperation *mail_op;
+
+                       /* Sync folder, we need this to save the seen flag */
+                       mail_op = modest_mail_operation_new (NULL);
+                       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                                        mail_op);
+                       modest_mail_operation_sync_folder (mail_op, folder, FALSE, NULL, NULL);
+                       g_object_unref (mail_op);
+                       g_object_unref (folder);
+               }
+               g_object_unref (header);
+       }
+}