Build fix
[modest] / src / hildon2 / modest-msg-view-window.c
index 790e3cd..70effef 100644 (file)
@@ -33,6 +33,7 @@
 #include <tny-msg.h>
 #include <tny-mime-part.h>
 #include <tny-vfs-stream.h>
+#include <tny-error.h>
 #include "modest-marshal.h"
 #include "modest-platform.h"
 #include <modest-utils.h>
@@ -65,6 +66,7 @@
 #include <glib/gstdio.h>
 #include <modest-debug.h>
 #include <modest-header-window.h>
+#include <modest-account-protocol.h>
 
 #define MYDOCS_ENV "MYDOCSDIR"
 #define DOCS_FOLDER ".documents"
@@ -84,6 +86,7 @@ struct _ModestMsgViewWindowPrivate {
        GtkWidget   *prev_toolitem;
        GtkWidget   *next_toolitem;
        gboolean    progress_hint;
+       gint        fetching_images;
 
        /* Optimized view enabled */
        gboolean optimized_view;
@@ -93,7 +96,7 @@ struct _ModestMsgViewWindowPrivate {
 
        /* Whether the message is in outbox */
        gboolean is_outbox;
-       
+
        /* A reference to the @model of the header view 
         * to allow selecting previous/next messages,
         * if the message is currently selected in the header view.
@@ -115,7 +118,8 @@ struct _ModestMsgViewWindowPrivate {
        GtkWidget *remove_attachment_banner;
 
        gchar *msg_uid;
-       
+       TnyMimePart *other_body;
+
        GSList *sighandlers;
 };
 
@@ -221,6 +225,11 @@ static gboolean message_reader (ModestMsgViewWindow *window,
                                GtkTreeRowReference *row_reference);
 
 static void setup_menu (ModestMsgViewWindow *self);
+static gboolean _modest_msg_view_window_map_event (GtkWidget *widget,
+                                                  GdkEvent *event,
+                                                  gpointer userdata);
+static void update_branding (ModestMsgViewWindow *self);
+
 
 /* list my signals */
 enum {
@@ -230,10 +239,9 @@ enum {
 };
 
 static const GtkToggleActionEntry msg_view_toggle_action_entries [] = {
-       { "FindInMessage",    MODEST_TOOLBAR_ICON_FIND,    N_("qgn_toolb_gene_find"), NULL, NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE },
+       { "FindInMessage",    MODEST_TOOLBAR_ICON_FIND,    N_("qgn_toolb_gene_find"), "<CTRL>F", NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE },
 };
 
-
 #define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
                                                     MODEST_TYPE_MSG_VIEW_WINDOW, \
                                                     ModestMsgViewWindowPrivate))
@@ -436,11 +444,13 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        priv->row_inserted_handler = 0;
        priv->rows_reordered_handler = 0;
        priv->progress_hint = FALSE;
+       priv->fetching_images = 0;
 
        priv->optimized_view  = FALSE;
        priv->purge_timeout = 0;
        priv->remove_attachment_banner = NULL;
        priv->msg_uid = NULL;
+       priv->other_body = NULL;
        
        priv->sighandlers = NULL;
        
@@ -474,6 +484,18 @@ set_toolbar_transfer_mode (ModestMsgViewWindow *self)
        return FALSE;
 }
 
+static void
+update_progress_hint (ModestMsgViewWindow *self)
+{
+       ModestMsgViewWindowPrivate *priv;
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
+
+       if (GTK_WIDGET_VISIBLE (self)) {
+               hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), 
+                                                         (priv->progress_hint || (priv->fetching_images > 0))?1:0);
+       }
+}
+
 static void 
 set_progress_hint (ModestMsgViewWindow *self, 
                   gboolean enabled)
@@ -489,9 +511,7 @@ set_progress_hint (ModestMsgViewWindow *self,
        /* Sets current progress hint */
        priv->progress_hint = enabled;
 
-       if (GTK_WIDGET_VISIBLE (self)) {
-               hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), enabled?1:0);
-       }
+       update_progress_hint (self);
 
 }
 
@@ -507,29 +527,14 @@ init_window (ModestMsgViewWindow *obj)
        priv->msg_view = GTK_WIDGET (tny_platform_factory_new_msg_view (modest_tny_platform_factory_get_instance ()));
        modest_msg_view_set_shadow_type (MODEST_MSG_VIEW (priv->msg_view), GTK_SHADOW_NONE);
        main_vbox = gtk_vbox_new  (FALSE, 6);
-#ifdef MODEST_TOOLKIT_HILDON2
        priv->main_scroll = hildon_pannable_area_new ();
        gtk_container_add (GTK_CONTAINER (priv->main_scroll), priv->msg_view);
-#else
-#ifdef MODEST_USE_MOZEMBED
-       priv->main_scroll = priv->msg_view;
-       gtk_widget_set_size_request (priv->msg_view, -1, 1600);
-#else
-       priv->main_scroll = gtk_scrolled_window_new (NULL, NULL);
-       gtk_container_add (GTK_CONTAINER (priv->main_scroll), priv->msg_view);
-#endif
-       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->main_scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->main_scroll), GTK_SHADOW_NONE);
-       modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->main_scroll), TRUE);
-
-#endif
        gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_scroll, TRUE, TRUE, 0);
        gtk_container_add   (GTK_CONTAINER(obj), main_vbox);
 
-       priv->find_toolbar = hildon_find_toolbar_new (NULL);
-       hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
-       gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
-       
+       /* NULL-ize fields if the window is destroyed */
+       g_signal_connect (priv->msg_view, "destroy", G_CALLBACK (gtk_widget_destroyed), &(priv->msg_view));
+
        gtk_widget_show_all (GTK_WIDGET(main_vbox));
 }
 
@@ -604,6 +609,11 @@ modest_msg_view_window_finalize (GObject *obj)
           call this function before */
        modest_msg_view_window_disconnect_signals (MODEST_WINDOW (obj));
 
+       if (priv->other_body != NULL) {
+               g_object_unref (priv->other_body);
+               priv->other_body = NULL;
+       }
+
        if (priv->header_model != NULL) {
                g_object_unref (priv->header_model);
                priv->header_model = NULL;
@@ -718,6 +728,7 @@ select_next_valid_row (GtkTreeModel *model,
 static void
 modest_msg_view_window_construct (ModestMsgViewWindow *self, 
                                  const gchar *modest_account_name,
+                                 const gchar *mailbox,
                                  const gchar *msg_uid)
 {
        GObject *obj = NULL;
@@ -784,6 +795,10 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        g_signal_connect (G_OBJECT (obj), "move-focus",
                          G_CALLBACK (on_move_focus), obj);
 
+       g_signal_connect (G_OBJECT (obj), "map-event",
+                         G_CALLBACK (_modest_msg_view_window_map_event),
+                         G_OBJECT (obj));
+
        /* Mail Operation Queue */
        priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
                                                       "queue-changed",
@@ -797,13 +812,22 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
                                                          obj);
 
        modest_window_set_active_account (MODEST_WINDOW(obj), modest_account_name);
+       modest_window_set_active_mailbox (MODEST_WINDOW(obj), mailbox);
 
-       g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_view_window_find_toolbar_close), obj);
-       g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj);
-       priv->last_search = NULL;
-
+       /* First add out toolbar ... */
        modest_msg_view_window_show_toolbar (MODEST_WINDOW (obj), TRUE);
 
+       /* ... and later the find toolbar. This way find toolbar will
+          be shown over the other */
+       priv->find_toolbar = hildon_find_toolbar_new (NULL);
+       hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
+       gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
+       g_signal_connect (G_OBJECT (priv->find_toolbar), "close", 
+                         G_CALLBACK (modest_msg_view_window_find_toolbar_close), obj);
+       g_signal_connect (G_OBJECT (priv->find_toolbar), "search", 
+                         G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj);
+       priv->last_search = NULL;
+
        /* Init the clipboard actions dim status */
        modest_msg_view_grab_focus(MODEST_MSG_VIEW (priv->msg_view));
 
@@ -816,6 +840,7 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
 ModestWindow *
 modest_msg_view_window_new_with_header_model (TnyMsg *msg, 
                                              const gchar *modest_account_name,
+                                             const gchar *mailbox,
                                              const gchar *msg_uid,
                                              GtkTreeModel *model, 
                                              GtkTreeRowReference *row_reference)
@@ -824,7 +849,6 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        ModestMsgViewWindowPrivate *priv = NULL;
        TnyFolder *header_folder = NULL;
        ModestHeaderView *header_view = NULL;
-       ModestWindow *main_window = NULL;
        ModestWindowMgr *mgr = NULL;
 
        MODEST_DEBUG_BLOCK (
@@ -835,32 +859,18 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        window = MODEST_MSG_VIEW_WINDOW (modest_window_mgr_get_msg_view_window (mgr));
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL);
 
-       modest_msg_view_window_construct (window, modest_account_name, msg_uid);
+       modest_msg_view_window_construct (window, modest_account_name, mailbox, msg_uid);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
-       /* Remember the message list's TreeModel so we can detect changes 
+       /* Remember the message list's TreeModel so we can detect changes
         * and change the list selection when necessary: */
-
-       main_window = modest_window_mgr_get_main_window(mgr, FALSE); /* don't create */
-       if (main_window) {
-               header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget(
-                                                        MODEST_MAIN_WINDOW(main_window),
-                                                        MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
-       }
-       
-       if (header_view != NULL){
-               header_folder = modest_header_view_get_folder(header_view);
-               /* This could happen if the header folder was
-                  unseleted before opening this msg window (for
-                  example if the user selects an account in the
-                  folder view of the main window */
-               if (header_folder) {
-                       priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) == TNY_FOLDER_TYPE_OUTBOX);
-                       priv->header_folder_id = tny_folder_get_id(header_folder);
-                       g_assert(priv->header_folder_id != NULL);
-                       g_object_unref(header_folder);
-               }
+       header_folder = modest_header_view_get_folder (header_view);
+       if (header_folder) {
+               priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) ==
+                                  TNY_FOLDER_TYPE_OUTBOX);
+               priv->header_folder_id = tny_folder_get_id (header_folder);
+               g_object_unref(header_folder);
        }
 
        /* Setup row references and connect signals */
@@ -900,6 +910,7 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
 
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
        update_window_title (MODEST_MSG_VIEW_WINDOW (window));
+       update_branding (MODEST_MSG_VIEW_WINDOW (window));
 
        /* gtk_widget_show_all (GTK_WIDGET (window)); */
        modest_msg_view_window_update_priority (window);
@@ -912,10 +923,11 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
 }
 
 ModestWindow *
-modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view, 
-                                             const gchar *modest_account_name,
-                                             const gchar *msg_uid,
-                                             GtkTreeRowReference *row_reference)
+modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
+                                            const gchar *modest_account_name,
+                                            const gchar *mailbox,
+                                            const gchar *msg_uid,
+                                            GtkTreeRowReference *row_reference)
 {
        ModestMsgViewWindow *window = NULL;
        ModestMsgViewWindowPrivate *priv = NULL;
@@ -928,7 +940,7 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
        window = MODEST_MSG_VIEW_WINDOW (modest_window_mgr_get_msg_view_window (mgr));
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL);
 
-       modest_msg_view_window_construct (window, modest_account_name, msg_uid);
+       modest_msg_view_window_construct (window, modest_account_name, mailbox, msg_uid);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
@@ -942,9 +954,9 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
                   example if the user selects an account in the
                   folder view of the main window */
                if (header_folder) {
-                       priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) == TNY_FOLDER_TYPE_OUTBOX);
+                       priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) == 
+                                          TNY_FOLDER_TYPE_OUTBOX);
                        priv->header_folder_id = tny_folder_get_id(header_folder);
-                       g_assert(priv->header_folder_id != NULL);
                        g_object_unref(header_folder);
                }
        }
@@ -982,10 +994,11 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
 
        if (header_view != NULL){
                modest_header_view_add_observer(header_view,
-                               MODEST_HEADER_VIEW_OBSERVER(window));
+                                               MODEST_HEADER_VIEW_OBSERVER(window));
        }
 
        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)) {
@@ -994,6 +1007,7 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
                                    TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                    &header, -1);
                message_reader (window, priv, header, row_reference);
+               g_object_unref (header);
        }
        gtk_tree_path_free (path);
 
@@ -1008,6 +1022,7 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
 ModestWindow *
 modest_msg_view_window_new_for_search_result (TnyMsg *msg, 
                                              const gchar *modest_account_name,
+                                             const gchar *mailbox,
                                              const gchar *msg_uid)
 {
        ModestMsgViewWindow *window = NULL;
@@ -1017,7 +1032,7 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg,
        mgr = modest_runtime_get_window_mgr ();
        window = MODEST_MSG_VIEW_WINDOW (modest_window_mgr_get_msg_view_window (mgr));
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL);
-       modest_msg_view_window_construct (window, modest_account_name, msg_uid);
+       modest_msg_view_window_construct (window, modest_account_name, mailbox, msg_uid);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
@@ -1026,6 +1041,7 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg,
        priv->is_search_result = TRUE;
 
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
+       update_branding (MODEST_MSG_VIEW_WINDOW (window));
        
        update_window_title (window);
        /* gtk_widget_show_all (GTK_WIDGET (window));*/
@@ -1039,10 +1055,23 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg,
        return MODEST_WINDOW(window);
 }
 
+gboolean
+modest_msg_view_window_is_other_body (ModestMsgViewWindow *self)
+{
+       ModestMsgViewWindowPrivate *priv = NULL;
+
+       g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE);
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+
+       return (priv->other_body != NULL);
+}
+
 ModestWindow *
-modest_msg_view_window_new_for_attachment (TnyMsg *msg, 
-                           const gchar *modest_account_name,
-                           const gchar *msg_uid)
+modest_msg_view_window_new_with_other_body (TnyMsg *msg, 
+                                           TnyMimePart *other_body,
+                                           const gchar *modest_account_name,
+                                           const gchar *mailbox,
+                                           const gchar *msg_uid)
 {
        GObject *obj = NULL;
        ModestMsgViewWindowPrivate *priv;       
@@ -1053,10 +1082,16 @@ modest_msg_view_window_new_for_attachment (TnyMsg *msg,
        obj = G_OBJECT (modest_window_mgr_get_msg_view_window (mgr));
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (obj);
        modest_msg_view_window_construct (MODEST_MSG_VIEW_WINDOW (obj), 
-               modest_account_name, msg_uid);
+                                         modest_account_name, mailbox, msg_uid);
 
-       tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
+       if (other_body) {
+               priv->other_body = g_object_ref (other_body);
+               modest_msg_view_set_msg_with_other_body (MODEST_MSG_VIEW (priv->msg_view), msg, other_body);
+       } else {
+               tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
+       }
        update_window_title (MODEST_MSG_VIEW_WINDOW (obj));
+       update_branding (MODEST_MSG_VIEW_WINDOW (obj));
 
        /* gtk_widget_show_all (GTK_WIDGET (obj)); */
 
@@ -1068,6 +1103,15 @@ modest_msg_view_window_new_for_attachment (TnyMsg *msg,
        return MODEST_WINDOW(obj);
 }
 
+ModestWindow *
+modest_msg_view_window_new_for_attachment (TnyMsg *msg, 
+                                          const gchar *modest_account_name,
+                                          const gchar *mailbox,
+                                          const gchar *msg_uid)
+{
+       return modest_msg_view_window_new_with_other_body (msg, NULL, modest_account_name, mailbox, msg_uid);
+}
+
 static void
 modest_msg_view_window_on_row_changed (GtkTreeModel *header_model,
                                       GtkTreePath *arg1,
@@ -1147,7 +1191,7 @@ modest_msg_view_window_on_row_inserted (GtkTreeModel *model,
        /* Setup row_reference for the actual msg. */
        priv->row_reference = gtk_tree_row_reference_new (priv->header_model, tree_path);
        if (priv->row_reference == NULL) {
-               g_warning("No reference for msg header item.");
+               g_warning("%s: No reference for msg header item.", __FUNCTION__);
                return;
        }
 
@@ -1443,7 +1487,7 @@ modest_msg_view_window_find_toolbar_search (GtkWidget *widget,
 
        if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
                g_free (current_search);
-               hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
+               hildon_banner_show_information (NULL, NULL, _CS("ecdg_ib_find_rep_enter_text"));
                return;
        }
 
@@ -1454,20 +1498,20 @@ modest_msg_view_window_find_toolbar_search (GtkWidget *widget,
                result = modest_isearch_view_search (MODEST_ISEARCH_VIEW (priv->msg_view),
                                                     priv->last_search);
                if (!result) {
-                       hildon_banner_show_information (NULL, NULL, dgettext("hildon-libs", "ckct_ib_find_no_matches"));
+                       hildon_banner_show_information (NULL, NULL, 
+                                                       _HL("ckct_ib_find_no_matches"));
                        g_free (priv->last_search);
                        priv->last_search = NULL;
                } else {
-                       modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
                        hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
                }
        } else {
                if (!modest_isearch_view_search_next (MODEST_ISEARCH_VIEW (priv->msg_view))) {
-                       hildon_banner_show_information (NULL, NULL, dgettext("hildon-libs", "ckct_ib_find_search_complete"));
+                       hildon_banner_show_information (NULL, NULL, 
+                                                       _HL("ckct_ib_find_search_complete"));
                        g_free (priv->last_search);
                        priv->last_search = NULL;
                } else {
-                       modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
                        hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
                }
        }
@@ -1507,6 +1551,8 @@ modest_msg_view_window_zoom_plus (ModestWindow *window)
 {
        gdouble zoom_level;
        ModestMsgViewWindowPrivate *priv;
+       gint int_zoom;
+       gchar *banner_text;
      
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), 1.0);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
@@ -1514,7 +1560,8 @@ modest_msg_view_window_zoom_plus (ModestWindow *window)
        zoom_level =  modest_zoomable_get_zoom (MODEST_ZOOMABLE (priv->msg_view));
 
        if (zoom_level >= 2.0) {
-               hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
+               hildon_banner_show_information (NULL, NULL, 
+                                               _CS("ckct_ib_max_zoom_level_reached"));
                return FALSE;
        } else if (zoom_level >= 1.5) {
                zoom_level = 2.0;
@@ -1531,10 +1578,13 @@ modest_msg_view_window_zoom_plus (ModestWindow *window)
        }
 
        /* set zoom level */
+       int_zoom = (gint) rint (zoom_level*100.0+0.1);
+       banner_text = g_strdup_printf (_HL("wdgt_ib_zoom"), int_zoom);
+       modest_platform_information_banner (GTK_WIDGET (window), NULL, banner_text);
+       g_free (banner_text);
        modest_zoomable_set_zoom (MODEST_ZOOMABLE (priv->msg_view), zoom_level);
 
        return TRUE;
-       
 }
 
 static gboolean
@@ -1542,6 +1592,8 @@ modest_msg_view_window_zoom_minus (ModestWindow *window)
 {
        gdouble zoom_level;
        ModestMsgViewWindowPrivate *priv;
+       gint int_zoom;
+       gchar *banner_text;
      
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), 1.0);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
@@ -1549,7 +1601,8 @@ modest_msg_view_window_zoom_minus (ModestWindow *window)
        zoom_level =  modest_zoomable_get_zoom (MODEST_ZOOMABLE (priv->msg_view));
 
        if (zoom_level <= 0.5) {
-                         hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
+               hildon_banner_show_information (NULL, NULL, 
+                                               _CS("ckct_ib_min_zoom_level_reached"));
                return FALSE;
        } else if (zoom_level <= 0.8) {
                zoom_level = 0.5;
@@ -1566,6 +1619,10 @@ modest_msg_view_window_zoom_minus (ModestWindow *window)
        }
 
        /* set zoom level */
+       int_zoom = (gint) rint (zoom_level*100.0+0.1);
+       banner_text = g_strdup_printf (_HL("wdgt_ib_zoom"), int_zoom);
+       modest_platform_information_banner (GTK_WIDGET (window), NULL, banner_text);
+       g_free (banner_text);
        modest_zoomable_set_zoom (MODEST_ZOOMABLE (priv->msg_view), zoom_level);
 
        return TRUE;
@@ -1603,7 +1660,7 @@ modest_msg_view_window_key_event (GtkWidget *window,
 
                if (event->type == GDK_KEY_PRESS) {
                        GtkScrollType scroll_type;
-                       
+
                        switch (event->keyval) {
                        case GDK_Up: 
                        case GDK_KP_Up:
@@ -1625,7 +1682,7 @@ modest_msg_view_window_key_event (GtkWidget *window,
                                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;
@@ -1776,6 +1833,7 @@ message_reader_performer (gboolean canceled,
 
        info = (MsgReaderInfo *) user_data;
        if (canceled || err) {
+               update_window_title (MODEST_MSG_VIEW_WINDOW (parent_window));
                goto frees;
        }
 
@@ -1786,7 +1844,7 @@ message_reader_performer (gboolean canceled,
        mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
                                                                 modest_ui_actions_disk_operations_error_handler, 
                                                                 NULL, NULL);
-                               
+
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
        modest_mail_operation_get_msg (mail_op, info->header, TRUE, view_msg_cb, info->row_reference);
        g_object_unref (mail_op);
@@ -1827,14 +1885,14 @@ message_reader (ModestMsgViewWindow *window,
 
        g_return_val_if_fail (row_reference != NULL, FALSE);
 
+       /* 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"));
+
        mgr = modest_runtime_get_window_mgr ();
        /* Msg download completed */
        if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED)) {
 
-               /* 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"));
-
                /* Ask the user if he wants to download the message if
                   we're not online */
                if (!tny_device_is_online (modest_runtime_get_device())) {
@@ -1842,9 +1900,11 @@ message_reader (ModestMsgViewWindow *window,
 
                        response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
                                                                            _("mcen_nc_get_msg"));
-                       if (response == GTK_RESPONSE_CANCEL)
+                       if (response == GTK_RESPONSE_CANCEL) {
+                               update_window_title (window);
                                return FALSE;
-               
+                       }
+
                        folder = tny_header_get_folder (header);
                        info = g_slice_new (MsgReaderInfo);
                        info->header = g_object_ref (header);
@@ -1860,13 +1920,13 @@ message_reader (ModestMsgViewWindow *window,
                        return TRUE;
                }
        }
-       
+
        folder = tny_header_get_folder (header);
        account = tny_folder_get_account (folder);
        info = g_slice_new (MsgReaderInfo);
        info->header = g_object_ref (header);
        info->row_reference = gtk_tree_row_reference_copy (row_reference);
-       
+
        message_reader_performer (FALSE, NULL, (GtkWindow *) window, account, info);
        g_object_unref (account);
        g_object_unref (folder);
@@ -1991,12 +2051,24 @@ view_msg_cb (ModestMailOperation *mail_op,
        row_reference = (GtkTreeRowReference *) user_data;
        if (canceled) {
                gtk_tree_row_reference_free (row_reference);
+               self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
+               if (self) {
+                       /* Restore window title */
+                       update_window_title (self);
+                       g_object_unref (self);
+               }
                return;
        }
-       
+
        /* If there was any error */
        if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
-               gtk_tree_row_reference_free (row_reference);                    
+               gtk_tree_row_reference_free (row_reference);
+               self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
+               if (self) {
+                       /* Restore window title */
+                       update_window_title (self);
+                       g_object_unref (self);
+               }
                return;
        }
 
@@ -2025,6 +2097,7 @@ view_msg_cb (ModestMailOperation *mail_op,
                tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
                modest_msg_view_window_update_priority (self);
                update_window_title (MODEST_MSG_VIEW_WINDOW (self));
+               update_branding (MODEST_MSG_VIEW_WINDOW (self));
                modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
        }
 
@@ -2124,7 +2197,7 @@ toolbar_resize (ModestMsgViewWindow *self)
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
 
        mgr = modest_runtime_get_window_mgr ();
-       static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
+       static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?120:120;
 
        if (parent_priv->toolbar) {
                /* left size buttons */
@@ -2144,13 +2217,12 @@ toolbar_resize (ModestMsgViewWindow *self)
                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_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);
                gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->prev_toolitem), TRUE);
        }
-               
 }
 
 static void
@@ -2159,7 +2231,6 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
 {
        ModestMsgViewWindowPrivate *priv = NULL;
        ModestWindowPrivate *parent_priv;
-       GtkWidget *reply_button = NULL, *menu = NULL;
 
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
@@ -2170,6 +2241,7 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
        if (!parent_priv->toolbar) {
                parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
                                                                  "/ToolBar");
+               gtk_toolbar_set_icon_size (GTK_TOOLBAR (parent_priv->toolbar), HILDON_ICON_SIZE_FINGER);
                gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
 
                priv->next_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNext");
@@ -2180,13 +2252,6 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
                hildon_window_add_toolbar (HILDON_WINDOW (self), 
                                           GTK_TOOLBAR (parent_priv->toolbar));
 
-               /* Set reply button tap and hold menu */
-               reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
-                                                         "/ToolBar/ToolbarMessageReply");
-               menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
-                                                 "/ToolbarReplyCSM");
-               if (menu && reply_button)
-                       gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
        }
 
        if (show_toolbar) {
@@ -2265,7 +2330,7 @@ on_account_removed (TnyAccountStore *account_store,
                parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
 
                /* Close this window if I'm showing a message of the removed account */
-               if (strcmp (parent_acc, our_acc) == 0)
+               if (our_acc && parent_acc && strcmp (parent_acc, our_acc) == 0)
                        modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
        }
 }
@@ -2286,7 +2351,7 @@ on_mail_operation_started (ModestMailOperation *mail_op,
        tmp = priv->progress_widgets;
        source = modest_mail_operation_get_source(mail_op);
        if (G_OBJECT (self) == source) {
-               if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE ) {
+               if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
                        set_toolbar_transfer_mode(self);
                        while (tmp) {
                                modest_progress_object_add_operation (
@@ -2313,7 +2378,7 @@ on_mail_operation_finished (ModestMailOperation *mail_op,
        op_type = modest_mail_operation_get_type_operation (mail_op);
        tmp = priv->progress_widgets;
        
-       if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE ) {
+       if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
                while (tmp) {
                        modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
                                                                 mail_op);
@@ -2324,15 +2389,15 @@ on_mail_operation_finished (ModestMailOperation *mail_op,
                if (observers_empty (self)) {
                        set_progress_hint (self, FALSE);
                }
-
-               /* Update dimming rules. We have to do this right here
-                  and not in view_msg_cb because at that point the
-                  transfer mode is still enabled so the dimming rule
-                  won't let the user delete the message that has been
-                  readed for example */
-               modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
-               modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
        }
+
+       /* Update dimming rules. We have to do this right here
+          and not in view_msg_cb because at that point the
+          transfer mode is still enabled so the dimming rule
+          won't let the user delete the message that has been
+          readed for example */
+       check_dimming_rules_after_change (self);
+
 }
 
 static void
@@ -2379,28 +2444,17 @@ modest_msg_view_window_get_attachments (ModestMsgViewWindow *win)
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), NULL);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (win);
 
-       selected_attachments = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
+       /* In Hildon 2.2 as there's no selection we assume we have all attachments selected */
+       selected_attachments = modest_msg_view_get_attachments (MODEST_MSG_VIEW (priv->msg_view));
        
        return selected_attachments;
 }
 
 typedef struct {
-       gchar *filepath;
-       GtkWidget *banner;
-       guint banner_idle_id;
+       ModestMsgViewWindow *self;
+       gchar *file_path;
 } DecodeAsyncHelper;
 
-static gboolean
-decode_async_banner_idle (gpointer user_data)
-{
-       DecodeAsyncHelper *helper = (DecodeAsyncHelper *) user_data;
-
-       helper->banner_idle_id = 0;
-       helper->banner = hildon_banner_show_animation (NULL, NULL, _("mail_me_opening"));
-
-       return FALSE;
-}
-
 static void
 on_decode_to_stream_async_handler (TnyMimePart *mime_part, 
                                   gboolean cancelled, 
@@ -2410,29 +2464,29 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
 {
        DecodeAsyncHelper *helper = (DecodeAsyncHelper *) user_data;
 
-       if (helper->banner_idle_id > 0) {
-               g_source_remove (helper->banner_idle_id);
-               helper->banner_idle_id = 0;
-       }
-       if (helper->banner) {
-               gtk_widget_destroy (helper->banner);
-               helper->banner = NULL;
-       }
+       /* It could happen that the window was closed */
+       if (GTK_WIDGET_VISIBLE (helper->self))
+               set_progress_hint (helper->self, FALSE);
+
        if (cancelled || err) {
-               modest_platform_information_banner (NULL, NULL, 
-                                                   _("mail_ib_file_operation_failed"));
+               if (err) {
+                       gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+                       modest_platform_information_banner (NULL, NULL, msg);
+                       g_free (msg);
+               }
                goto free;
        }
 
        /* make the file read-only */
-       g_chmod(helper->filepath, 0444);
+       g_chmod(helper->file_path, 0444);
 
        /* Activate the file */
-       modest_platform_activate_file (helper->filepath, tny_mime_part_get_content_type (mime_part));
+       modest_platform_activate_file (helper->file_path, tny_mime_part_get_content_type (mime_part));
 
  free:
        /* Frees */
-       g_free (helper->filepath);
+       g_object_unref (helper->self);
+       g_free (helper->file_path);
        g_slice_free (DecodeAsyncHelper, helper);
 }
 
@@ -2454,7 +2508,7 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
        attachments = modest_msg_view_get_attachments (MODEST_MSG_VIEW (priv->msg_view));
        attachment_index = modest_list_index (attachments, (GObject *) mime_part);
        g_object_unref (attachments);
-       
+
        if (msg_uid && attachment_index >= 0) {
                attachment_uid = g_strdup_printf ("%s/%d", msg_uid, attachment_index);
        }
@@ -2473,35 +2527,39 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                        mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
                        g_object_unref (iter);
                }
-               g_object_unref (selected_attachments);
+               if (selected_attachments)
+                       g_object_unref (selected_attachments);
 
                if (error)
-                       return;
+                       goto frees;
        } else {
                g_object_ref (mime_part);
        }
 
-       if (tny_mime_part_is_purged (mime_part)) {
-               g_object_unref (mime_part);
-               return;
-       }
+       if (tny_mime_part_is_purged (mime_part))
+               goto frees;
 
-       if (!modest_tny_mime_part_is_msg (mime_part)) {
+       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);
                gboolean show_error_banner = FALSE;
                TnyFsStream *temp_stream = NULL;
                temp_stream = modest_utils_create_temp_stream (att_filename, attachment_uid,
                                                               &filepath);
-               
+
                if (temp_stream != NULL) {
-                       DecodeAsyncHelper *helper = g_slice_new (DecodeAsyncHelper);
-                       helper->filepath = g_strdup (filepath);
-                       helper->banner = NULL;
-                       helper->banner_idle_id = g_timeout_add (1000, decode_async_banner_idle, helper);
-                       tny_mime_part_decode_to_stream_async (mime_part, TNY_STREAM (temp_stream), 
-                                                             on_decode_to_stream_async_handler, 
-                                                             NULL, 
+                       DecodeAsyncHelper *helper;
+
+                       /* Activate progress hint */
+                       set_progress_hint (window, TRUE);
+
+                       helper = g_slice_new0 (DecodeAsyncHelper);
+                       helper->self = g_object_ref (window);
+                       helper->file_path = g_strdup (filepath);
+
+                       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
@@ -2522,6 +2580,42 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                        g_free (filepath);
                if (show_error_banner)
                        modest_platform_information_banner (NULL, NULL, _("mail_ib_file_operation_failed"));
+       } else if (!modest_tny_mime_part_is_msg (mime_part)) {
+               ModestWindowMgr *mgr;
+               ModestWindow *msg_win = NULL;
+               TnyMsg *current_msg;
+               gboolean found;
+               TnyHeader *header;
+
+               current_msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
+               mgr = modest_runtime_get_window_mgr ();
+               header = tny_msg_get_header (TNY_MSG (current_msg));
+               found = modest_window_mgr_find_registered_message_uid (mgr,
+                                                                      attachment_uid,
+                                                                      &msg_win);
+               
+               if (found) {
+                       g_debug ("window for this body is already being created");
+               } else {
+
+                       /* it's not found, so create a new window for it */
+                       modest_window_mgr_register_header (mgr, header, attachment_uid); /* register the uid before building the window */
+                       gchar *account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (window)));
+                       const gchar *mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (window));
+                       if (!account)
+                               account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
+                       
+                       msg_win = modest_msg_view_window_new_with_other_body (TNY_MSG (current_msg), TNY_MIME_PART (mime_part),
+                                                                             account, mailbox, attachment_uid);
+                       
+                       modest_window_set_zoom (MODEST_WINDOW (msg_win),
+                                               modest_window_get_zoom (MODEST_WINDOW (window)));
+                       if (modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (window)))
+                               gtk_widget_show_all (GTK_WIDGET (msg_win));
+                       else
+                               gtk_widget_destroy (GTK_WIDGET (msg_win));
+               }
+               g_object_unref (current_msg);           
        } else {
                /* message attachment */
                TnyHeader *header = NULL;
@@ -2536,21 +2630,30 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                if (found) {
                        /* if it's found, but there is no msg_win, it's probably in the process of being created;
                         * thus, we don't do anything */
-                       g_warning ("window for is already being created");
+                       g_debug ("window for is already being created");
                } else {
                        /* it's not found, so create a new window for it */
                        modest_window_mgr_register_header (mgr, header, attachment_uid); /* register the uid before building the window */
                        gchar *account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (window)));
+                       const gchar *mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (window));
                        if (!account)
                                account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
-                       msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (mime_part), account, attachment_uid);
+                       msg_win = modest_msg_view_window_new_for_attachment (TNY_MSG (mime_part), account, 
+                                                                            mailbox, attachment_uid);
                        modest_window_set_zoom (MODEST_WINDOW (msg_win),
                                                modest_window_get_zoom (MODEST_WINDOW (window)));
-                       modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (window));
-                       gtk_widget_show_all (GTK_WIDGET (msg_win));
+                       if (modest_window_mgr_register_window (mgr, msg_win, MODEST_WINDOW (window)))
+                               gtk_widget_show_all (GTK_WIDGET (msg_win));
+                       else
+                               gtk_widget_destroy (GTK_WIDGET (msg_win));
                }
        }
-       g_object_unref (mime_part);
+
+ frees:
+       if (attachment_uid)
+               g_free (attachment_uid);
+       if (mime_part)
+               g_object_unref (mime_part);
 }
 
 typedef struct
@@ -2562,20 +2665,19 @@ typedef struct
 typedef struct
 {
        GList *pairs;
-       GtkWidget *banner;
        GnomeVFSResult result;
 } SaveMimePartInfo;
 
 static void save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct);
 static gboolean idle_save_mime_part_show_result (SaveMimePartInfo *info);
 static gpointer save_mime_part_to_file (SaveMimePartInfo *info);
-static void save_mime_parts_to_file_with_checks (SaveMimePartInfo *info);
+static void save_mime_parts_to_file_with_checks (GtkWindow *parent, SaveMimePartInfo *info);
 
-static void 
+static void
 save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
 {
-       
        GList *node;
+
        for (node = info->pairs; node != NULL; node = g_list_next (node)) {
                SaveMimePartPair *pair = (SaveMimePartPair *) node->data;
                g_free (pair->filename);
@@ -2585,7 +2687,6 @@ save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
        g_list_free (info->pairs);
        info->pairs = NULL;
        if (with_struct) {
-               gtk_widget_destroy (info->banner);
                g_slice_free (SaveMimePartInfo, info);
        }
 }
@@ -2604,8 +2705,9 @@ idle_save_mime_part_show_result (SaveMimePartInfo *info)
                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) {
-                       hildon_banner_show_information (NULL, NULL, dgettext("ke-recv", 
-                                                                            "cerm_device_memory_full"));
+                       gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+                       modest_platform_information_banner (NULL, NULL, msg);
+                       g_free (msg);
                } else {
                        hildon_banner_show_information (NULL, NULL, _("mail_ib_file_operation_failed"));
                }
@@ -2628,15 +2730,21 @@ save_mime_part_to_file (SaveMimePartInfo *info)
                stream = tny_vfs_stream_new (handle);
                if (tny_mime_part_decode_to_stream (pair->part, stream, &error) < 0) {
                        g_warning ("modest: could not save attachment %s: %d (%s)\n", pair->filename, error?error->code:-1, error?error->message:"Unknown error");
-                       
-                       info->result = GNOME_VFS_ERROR_IO;
+
+                       if ((error->domain == TNY_ERROR_DOMAIN) && 
+                           (error->code == TNY_IO_ERROR_WRITE) &&
+                           (errno == ENOSPC)) {
+                               info->result = GNOME_VFS_ERROR_NO_SPACE;
+                       } else {
+                               info->result = GNOME_VFS_ERROR_IO;
+                       }
                }
                g_object_unref (G_OBJECT (stream));
                g_object_unref (pair->part);
                g_slice_free (SaveMimePartPair, pair);
                info->pairs = g_list_delete_link (info->pairs, info->pairs);
        } else {
-               g_warning ("modest: could not create save attachment %s: %s\n", pair->filename, gnome_vfs_result_to_string (info->result));
+               g_warning ("Could not create save attachment %s: %s\n", pair->filename, gnome_vfs_result_to_string (info->result));
                save_mime_part_info_free (info, FALSE);
        }
 
@@ -2645,36 +2753,48 @@ save_mime_part_to_file (SaveMimePartInfo *info)
 }
 
 static void
-save_mime_parts_to_file_with_checks (SaveMimePartInfo *info)
+save_mime_parts_to_file_with_checks (GtkWindow *parent,
+                                    SaveMimePartInfo *info)
 {
        gboolean is_ok = TRUE;
         gint replaced_files = 0;
         const GList *files = info->pairs;
-        const GList *iter;
+        const GList *iter, *to_replace = NULL;
 
         for (iter = files; (iter != NULL) && (replaced_files < 2); iter = g_list_next(iter)) {
                 SaveMimePartPair *pair = iter->data;
                 if (modest_utils_file_exists (pair->filename)) {
                        replaced_files++;
+                       if (replaced_files == 1)
+                               to_replace = iter;
                 }
         }
        if (replaced_files) {
-               GtkWidget *confirm_overwrite_dialog;
-                const gchar *message = (replaced_files == 1) ?
-                        _FM("docm_nc_replace_file") : _FM("docm_nc_replace_multiple");
-                confirm_overwrite_dialog = hildon_note_new_confirmation (NULL, message);
-               if (gtk_dialog_run (GTK_DIALOG (confirm_overwrite_dialog)) != GTK_RESPONSE_OK) {
-                       is_ok = FALSE;
+               gint response;
+
+               if (replaced_files == 1) {
+                       SaveMimePartPair *pair = to_replace->data;
+                       const gchar *basename = strrchr (pair->filename, G_DIR_SEPARATOR) + 1;
+                       gchar *escaped_basename, *message;
+
+                       escaped_basename = g_uri_unescape_string (basename, NULL);
+                       message = g_strdup_printf ("%s\n%s",
+                                                  _FM("docm_nc_replace_file"),
+                                                  (escaped_basename) ? escaped_basename : "");
+                       response = modest_platform_run_confirmation_dialog (parent, message);
+                       g_free (message);
+                       g_free (escaped_basename);
+               } else {
+                       response = modest_platform_run_confirmation_dialog (parent,
+                                                                           _FM("docm_nc_replace_multiple"));
                }
-               gtk_widget_destroy (confirm_overwrite_dialog);
+               if (response != GTK_RESPONSE_OK)
+                       is_ok = FALSE;
        }
 
        if (!is_ok) {
                save_mime_part_info_free (info, TRUE);
        } else {
-               GtkWidget *banner = hildon_banner_show_animation (NULL, NULL, 
-                                                                 _CS("sfil_ib_saving"));
-               info->banner = banner;
                g_thread_create ((GThreadFunc)save_mime_part_to_file, info, FALSE, NULL);
        }
 
@@ -2688,6 +2808,7 @@ save_attachments_response (GtkDialog *dialog,
        TnyList *mime_parts;
        gchar *chooser_uri;
        GList *files_to_save = NULL;
+       gchar *current_folder;
 
        mime_parts = TNY_LIST (user_data);
 
@@ -2695,10 +2816,21 @@ save_attachments_response (GtkDialog *dialog,
                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') {
+               GError *err = NULL;
+               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);
+                       g_error_free (err);
+               }
+       }
+       g_free (current_folder);
 
        if (!modest_utils_folder_writable (chooser_uri)) {
                hildon_banner_show_information 
-                       (NULL, NULL, dgettext("hildon-fm", "sfil_ib_readonly_location"));
+                       (NULL, NULL, _FM("sfil_ib_readonly_location"));
        } else {
                TnyIterator *iter;
 
@@ -2710,7 +2842,7 @@ save_attachments_response (GtkDialog *dialog,
                            !tny_mime_part_is_purged (mime_part) &&
                            (tny_mime_part_get_filename (mime_part) != NULL)) {
                                SaveMimePartPair *pair;
-                                       
+
                                pair = g_slice_new0 (SaveMimePartPair);
 
                                if (tny_list_get_length (mime_parts) > 1) {
@@ -2734,7 +2866,7 @@ save_attachments_response (GtkDialog *dialog,
                SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
                info->pairs = files_to_save;
                info->result = TRUE;
-               save_mime_parts_to_file_with_checks (info);
+               save_mime_parts_to_file_with_checks ((GtkWindow *) dialog, info);
        }
 
  end:
@@ -2744,11 +2876,12 @@ save_attachments_response (GtkDialog *dialog,
 }
 
 void
-modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *mime_parts)
+modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, 
+                                        TnyList *mime_parts)
 {
        ModestMsgViewWindowPrivate *priv;
        GtkWidget *save_dialog = NULL;
-       gchar *folder = NULL;
+       gchar *conf_folder = NULL;
        gchar *filename = NULL;
        gchar *save_multiple_str = NULL;
 
@@ -2756,9 +2889,20 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        if (mime_parts == NULL) {
-               mime_parts = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
-               if (mime_parts == NULL || tny_list_get_length (mime_parts) == 0)
+               /* In Hildon 2.2 save and delete operate over all the attachments as there's no
+                * selection available */
+               mime_parts = modest_msg_view_get_attachments (MODEST_MSG_VIEW (priv->msg_view));
+               if (mime_parts && !modest_maemo_utils_select_attachments (GTK_WINDOW (window), mime_parts, FALSE)) {
+                       g_object_unref (mime_parts);
+                       return;
+               }
+               if (mime_parts == NULL || tny_list_get_length (mime_parts) == 0) {
+                       if (mime_parts) {
+                               g_object_unref (mime_parts);
+                               mime_parts = NULL;
+                       }
                        return;
+               }
        } else {
                g_object_ref (mime_parts);
        }
@@ -2776,23 +2920,34 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m
                        filename = g_strdup (tny_mime_part_get_filename (mime_part));
                } else {
                        /* TODO: show any error? */
-                       g_warning ("Tried to save a non-file attachment");
+                       g_warning ("%s: Tried to save a non-file attachment", __FUNCTION__);
                        g_object_unref (mime_parts);
                        return;
                }
                g_object_unref (mime_part);
        } else {
-               save_multiple_str = g_strdup_printf (_FM("sfil_va_number_of_objects_attachments"), 
-                                                    tny_list_get_length (mime_parts));
+               gint num = tny_list_get_length (mime_parts);
+               save_multiple_str = g_strdup_printf (dngettext("hildon-fm",
+                                                              "sfil_va_number_of_objects_attachment",
+                                                             "sfil_va_number_of_objects_attachments",
+                                                             num), num);
        }
-       
+
        save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), 
                                                      GTK_FILE_CHOOSER_ACTION_SAVE);
 
        /* set folder */
-       folder = g_build_filename (g_getenv (MYDOCS_ENV), DOCS_FOLDER, NULL);
-       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (save_dialog), folder);
-       g_free (folder);
+       conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_SAVE_ATTACHMENT_PATH, 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);
+               gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (save_dialog), docs_folder);
+               g_free (docs_folder);
+       }
+       g_free (conf_folder);
 
        /* set filename */
        if (filename) {
@@ -2842,7 +2997,7 @@ void
 modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean get_all)
 {
        ModestMsgViewWindowPrivate *priv;
-       TnyList *mime_parts = NULL;
+       TnyList *mime_parts = NULL, *tmp;
        gchar *confirmation_message;
        gint response;
        gint n_attachments;
@@ -2852,24 +3007,28 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
-       if (get_all)
-               mime_parts = modest_msg_view_get_attachments (MODEST_MSG_VIEW (priv->msg_view));
-       else
-               mime_parts = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
-               
-       /* Remove already purged messages from mime parts list */
-       iter = tny_list_create_iterator (mime_parts);
+       /* In hildon 2.2 we ignore the get_all flag as we always get all attachments. This is
+        * because we don't have selection
+        */
+       mime_parts = modest_msg_view_get_attachments (MODEST_MSG_VIEW (priv->msg_view));
+
+       /* Remove already purged messages from mime parts list. We use
+          a copy of the list to remove items in the original one */
+       tmp = tny_list_copy (mime_parts);
+       iter = tny_list_create_iterator (tmp);
        while (!tny_iterator_is_done (iter)) {
                TnyMimePart *part = TNY_MIME_PART (tny_iterator_get_current (iter));
-               tny_iterator_next (iter);
-               if (tny_mime_part_is_purged (part)) {
+               if (tny_mime_part_is_purged (part))
                        tny_list_remove (mime_parts, (GObject *) part);
-               }
+
                g_object_unref (part);
+               tny_iterator_next (iter);
        }
+       g_object_unref (tmp);
        g_object_unref (iter);
 
-       if (tny_list_get_length (mime_parts) == 0) {
+       if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), mime_parts, TRUE) ||
+           tny_list_get_length (mime_parts) == 0) {
                g_object_unref (mime_parts);
                return;
        }
@@ -2910,7 +3069,7 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
        }
 
        priv->purge_timeout = g_timeout_add (2000, show_remove_attachment_information, window);
-       
+
        iter = tny_list_create_iterator (mime_parts);
        while (!tny_iterator_is_done (iter)) {
                TnyMimePart *part;
@@ -2927,6 +3086,7 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
        tny_msg_rewrite_cache (msg);
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
        g_object_unref (msg);
+       update_branding (MODEST_MSG_VIEW_WINDOW (window));
 
        g_object_unref (mime_parts);
 
@@ -2940,22 +3100,35 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
                g_object_unref (priv->remove_attachment_banner);
                priv->remove_attachment_banner = NULL;
        }
-
-
 }
 
 
 static void
 update_window_title (ModestMsgViewWindow *window)
 {
-       ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+       ModestMsgViewWindowPrivate *priv;
        TnyMsg *msg = NULL;
        TnyHeader *header = NULL;
        gchar *subject = NULL;
-       
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+
+       /* Note that if the window is closed while we're retrieving
+          the message, this widget could de deleted */
+       if (!priv->msg_view)
+               return;
+
        msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
 
-       if (msg != NULL) {
+       if (priv->other_body) {
+               gchar *description;
+
+               description = modest_tny_mime_part_get_header_value (priv->other_body, "Content-Description");
+               if (description) {
+                       g_strstrip (description);
+                       subject = description;
+               }
+       } else if (msg != NULL) {
                header = tny_msg_get_header (msg);
                subject = tny_header_dup_subject (header);
                g_object_unref (header);
@@ -2971,9 +3144,10 @@ update_window_title (ModestMsgViewWindow *window)
 }
 
 
-static void on_move_focus (GtkWidget *widget,
-                          GtkDirectionType direction,
-                          gpointer userdata)
+static void
+on_move_focus (GtkWidget *widget,
+              GtkDirectionType direction,
+              gpointer userdata)
 {
        g_signal_stop_emission_by_name (G_OBJECT (widget), "move-focus");
 }
@@ -3013,6 +3187,7 @@ typedef struct {
        gchar *cache_id;
        TnyStream *output_stream;
        GtkWidget *msg_view;
+       GtkWidget *window;
 } FetchImageData;
 
 gboolean
@@ -3020,12 +3195,20 @@ on_fetch_image_idle_refresh_view (gpointer userdata)
 {
 
        FetchImageData *fidata = (FetchImageData *) userdata;
-       g_message ("REFRESH VIEW");
+
+       gdk_threads_enter ();
        if (GTK_WIDGET_DRAWABLE (fidata->msg_view)) {
-               g_message ("QUEUING DRAW");
+               ModestMsgViewWindowPrivate *priv;
+
+               priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (fidata->window);
+               priv->fetching_images--;
                gtk_widget_queue_draw (fidata->msg_view);
+               update_progress_hint (MODEST_MSG_VIEW_WINDOW (fidata->window));
        }
+       gdk_threads_leave ();
+
        g_object_unref (fidata->msg_view);
+       g_object_unref (fidata->window);
        g_slice_free (FetchImageData, fidata);
        return FALSE;
 }
@@ -3038,12 +3221,37 @@ on_fetch_image_thread (gpointer userdata)
        TnyStream *cache_stream;
 
        cache = modest_runtime_get_images_cache ();
-       cache_stream = tny_stream_cache_get_stream (cache, fidata->cache_id, (TnyStreamCacheOpenStreamFetcher) fetch_image_open_stream, (gpointer) fidata->uri);
+       cache_stream = 
+               tny_stream_cache_get_stream (cache, 
+                                            fidata->cache_id, 
+                                            (TnyStreamCacheOpenStreamFetcher) fetch_image_open_stream, 
+                                            (gpointer) fidata->uri);
        g_free (fidata->cache_id);
        g_free (fidata->uri);
 
        if (cache_stream != NULL) {
-               tny_stream_write_to_stream (cache_stream, fidata->output_stream);
+               char buffer[4096];
+
+               while (G_LIKELY (!tny_stream_is_eos (cache_stream))) {
+                       gssize nb_read;
+
+                       nb_read = tny_stream_read (cache_stream, buffer, sizeof (buffer));
+                       if (G_UNLIKELY (nb_read < 0)) {
+                               break;
+                       } else if (G_LIKELY (nb_read > 0)) {
+                               gssize nb_written = 0;
+
+                               while (G_UNLIKELY (nb_written < nb_read)) {
+                                       gssize len;
+
+                                       len = tny_stream_write (fidata->output_stream, buffer + nb_written,
+                                                               nb_read - nb_written);
+                                       if (G_UNLIKELY (len < 0))
+                                               break;
+                                       nb_written += len;
+                               }
+                       }
+               }
                tny_stream_close (cache_stream);
                g_object_unref (cache_stream);
        }
@@ -3051,10 +3259,7 @@ on_fetch_image_thread (gpointer userdata)
        tny_stream_close (fidata->output_stream);
        g_object_unref (fidata->output_stream);
 
-
-       gdk_threads_enter ();
        g_idle_add (on_fetch_image_idle_refresh_view, fidata);
-       gdk_threads_leave ();
 
        return NULL;
 }
@@ -3075,10 +3280,12 @@ on_fetch_image (ModestMsgView *msgview,
 
        fidata = g_slice_new0 (FetchImageData);
        fidata->msg_view = g_object_ref (msgview);
+       fidata->window = g_object_ref (window);
        fidata->uri = g_strdup (uri);
        fidata->cache_id = modest_images_cache_get_id (current_account, uri);
        fidata->output_stream = g_object_ref (stream);
 
+       priv->fetching_images++;
        if (g_thread_create (on_fetch_image_thread, fidata, FALSE, NULL) == NULL) {
                g_object_unref (fidata->output_stream);
                g_free (fidata->cache_id);
@@ -3086,10 +3293,13 @@ on_fetch_image (ModestMsgView *msgview,
                g_object_unref (fidata->msg_view);
                g_slice_free (FetchImageData, fidata);
                tny_stream_close (stream);
+               priv->fetching_images--;
+               update_progress_hint (window);
                return FALSE;
        }
+       update_progress_hint (window);
 
-       return TRUE;;
+       return TRUE;
 }
 
 static void 
@@ -3104,27 +3314,34 @@ setup_menu (ModestMsgViewWindow *self)
        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));
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_mark_as_unread"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_on_mark_as_unread),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_mark_as_unread_msg_in_view));
-       
+
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_save_attachments"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_save_attachments),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_save_attachments));
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_remove_attachments"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_remove_attachments),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_remove_attachments));
-       
+
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_new_message"), "<Control>n",
                                           APP_MENU_CALLBACK (modest_ui_actions_on_new_msg),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_new_msg));
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_addtocontacts"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_add_to_contacts),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_add_to_contacts));
+
+       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mail_bd_external_images"), NULL,
+                                          APP_MENU_CALLBACK (modest_ui_actions_on_fetch_images),
+                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_fetch_images));
+       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_ti_message_properties"), NULL,
+                                          APP_MENU_CALLBACK (modest_ui_actions_on_details),
+                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_details));
 }
 
 void
@@ -3196,3 +3413,84 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
        
        if (recipients) {g_slist_foreach (recipients, (GFunc) g_free, NULL); g_slist_free (recipients);}
 }
+
+static gboolean 
+_modest_msg_view_window_map_event (GtkWidget *widget,
+                                  GdkEvent *event,
+                                  gpointer userdata)
+{
+       ModestMsgViewWindow *self = (ModestMsgViewWindow *) userdata;
+
+       update_progress_hint (self);
+
+       return FALSE;
+}
+
+void
+modest_msg_view_window_fetch_images (ModestMsgViewWindow *self)
+{
+       ModestMsgViewWindowPrivate *priv;
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+
+       modest_msg_view_request_fetch_images (MODEST_MSG_VIEW (priv->msg_view));
+}
+
+gboolean 
+modest_msg_view_window_has_blocked_external_images (ModestMsgViewWindow *self)
+{
+       ModestMsgViewWindowPrivate *priv;
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+
+       g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE);
+
+       return modest_msg_view_has_blocked_external_images (MODEST_MSG_VIEW (priv->msg_view));
+}
+
+void 
+modest_msg_view_window_reload (ModestMsgViewWindow *self)
+{
+       ModestMsgViewWindowPrivate *priv;
+       TnyHeader *header;
+
+       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, priv->row_reference)) {
+               g_warning ("Shouldn't happen, trying to reload a message failed");
+       }
+
+       g_object_unref (header);
+}
+
+static void
+update_branding (ModestMsgViewWindow *self)
+{
+       const gchar *account; 
+       const gchar *mailbox;
+       ModestAccountMgr *mgr;
+       ModestProtocol *protocol = NULL;
+       gchar *service_name = NULL;
+       const GdkPixbuf *service_icon = NULL;
+       ModestMsgViewWindowPrivate *priv;
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+
+       account = modest_window_get_active_account (MODEST_WINDOW (self));
+       mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (self));
+
+       mgr = modest_runtime_get_account_mgr ();
+       
+       if (modest_account_mgr_account_is_multimailbox (mgr, account, &protocol)) {
+               if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
+                       service_name = modest_account_protocol_get_service_name (MODEST_ACCOUNT_PROTOCOL (protocol),
+                                                                                account, mailbox);
+                       service_icon = modest_account_protocol_get_service_icon (MODEST_ACCOUNT_PROTOCOL (protocol),
+                                                                                account, mailbox, MODEST_ICON_SIZE_SMALL);
+               }
+       }
+
+       modest_msg_view_set_branding (MODEST_MSG_VIEW (priv->msg_view), service_name, service_icon);
+       g_free (service_name);
+}