Do not update window title if the window is destroyed before the message is retrieved
[modest] / src / hildon2 / modest-msg-view-window.c
index 547eff2..fca8093 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>
 #include <modest-main-window-ui.h>
 #include "modest-msg-view-window-ui-dimming.h"
 #include <modest-widget-memory.h>
+#include <modest-progress-object.h>
 #include <modest-runtime.h>
 #include <modest-window-priv.h>
 #include <modest-tny-folder.h>
 #include <modest-text-utils.h>
 #include <modest-account-mgr-helpers.h>
-#include "modest-progress-bar.h"
 #include <hildon/hildon-pannable-area.h>
 #include <hildon/hildon-picker-dialog.h>
+#include <hildon/hildon-app-menu.h>
 #include "modest-defs.h"
 #include "modest-hildon-includes.h"
 #include "modest-ui-dimming-manager.h"
 #include <errno.h>
 #include <glib/gstdio.h>
 #include <modest-debug.h>
+#include <modest-header-window.h>
 
-#define DEFAULT_FOLDER "MyDocs/.documents"
+#define MYDOCS_ENV "MYDOCSDIR"
+#define DOCS_FOLDER ".documents"
+
+typedef struct _ModestMsgViewWindowPrivate ModestMsgViewWindowPrivate;
+struct _ModestMsgViewWindowPrivate {
+
+       GtkWidget   *msg_view;
+       GtkWidget   *main_scroll;
+       GtkWidget   *find_toolbar;
+       gchar       *last_search;
+
+       /* Progress observers */
+       GSList           *progress_widgets;
+
+       /* Tollbar items */
+       GtkWidget   *prev_toolitem;
+       GtkWidget   *next_toolitem;
+       gboolean    progress_hint;
+
+       /* Optimized view enabled */
+       gboolean optimized_view;
+
+       /* Whether this was created via the *_new_for_search_result() function. */
+       gboolean is_search_result;
+
+       /* 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.
+        */
+       const gchar *header_folder_id;
+       GtkTreeModel *header_model;
+       GtkTreeRowReference *row_reference;
+       GtkTreeRowReference *next_row_reference;
+
+       gulong clipboard_change_handler;
+       gulong queue_change_handler;
+       gulong account_removed_handler;
+       gulong row_changed_handler;
+       gulong row_deleted_handler;
+       gulong row_inserted_handler;
+       gulong rows_reordered_handler;
+
+       guint purge_timeout;
+       GtkWidget *remove_attachment_banner;
+
+       gchar *msg_uid;
+
+       GSList *sighandlers;
+};
 
 static void  modest_msg_view_window_class_init   (ModestMsgViewWindowClass *klass);
 static void  modest_msg_view_window_init         (ModestMsgViewWindow *obj);
@@ -81,10 +135,13 @@ static void  modest_msg_view_window_find_toolbar_search (GtkWidget *widget,
 static void modest_msg_view_window_disconnect_signals (ModestWindow *self);
 
 static gdouble modest_msg_view_window_get_zoom (ModestWindow *window);
+static void modest_msg_view_window_set_zoom (ModestWindow *window,
+                                            gdouble zoom);
+static gboolean modest_msg_view_window_zoom_minus (ModestWindow *window);
+static gboolean modest_msg_view_window_zoom_plus (ModestWindow *window);
 static gboolean modest_msg_view_window_key_event (GtkWidget *window,
                                                  GdkEventKey *event,
                                                  gpointer userdata);
-
 static void modest_msg_view_window_update_priority (ModestMsgViewWindow *window);
 
 static void modest_msg_view_window_show_toolbar   (ModestWindow *window,
@@ -118,9 +175,6 @@ static void modest_msg_view_window_update_model_replaced (ModestHeaderViewObserv
                                                          GtkTreeModel *model,
                                                          const gchar *tny_folder_id);
 
-static void cancel_progressbar  (GtkToolButton *toolbutton,
-                                ModestMsgViewWindow *self);
-
 static void on_queue_changed    (ModestMailOperationQueue *queue,
                                 ModestMailOperation *mail_op,
                                 ModestMailOperationQueueNotification type,
@@ -141,8 +195,8 @@ static void view_msg_cb         (ModestMailOperation *mail_op,
                                 GError *error,
                                 gpointer user_data);
 
-static void set_toolbar_mode    (ModestMsgViewWindow *self, 
-                                ModestToolBarModes mode);
+static void set_progress_hint    (ModestMsgViewWindow *self, 
+                                 gboolean enabled);
 
 static void update_window_title (ModestMsgViewWindow *window);
 
@@ -162,6 +216,15 @@ static gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
                                                     GtkScrollType scroll_type,
                                                     gboolean horizontal,
                                                     gpointer userdata);
+static gboolean message_reader (ModestMsgViewWindow *window,
+                               ModestMsgViewWindowPrivate *priv,
+                               TnyHeader *header,
+                               GtkTreeRowReference *row_reference);
+
+static void setup_menu (ModestMsgViewWindow *self);
+static gboolean _modest_msg_view_window_map_event (GtkWidget *widget,
+                                                  GdkEvent *event,
+                                                  gpointer userdata);
 
 /* list my signals */
 enum {
@@ -174,60 +237,6 @@ 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 },
 };
 
-typedef struct _ModestMsgViewWindowPrivate ModestMsgViewWindowPrivate;
-struct _ModestMsgViewWindowPrivate {
-
-       GtkWidget   *msg_view;
-       GtkWidget   *main_scroll;
-       GtkWidget   *find_toolbar;
-       gchar       *last_search;
-
-       /* Progress observers */
-       GtkWidget        *progress_bar;
-       GSList           *progress_widgets;
-
-       /* Tollbar items */
-       GtkWidget   *progress_toolitem;
-       GtkWidget   *cancel_toolitem;
-       GtkWidget   *prev_toolitem;
-       GtkWidget   *next_toolitem;
-       ModestToolBarModes current_toolbar_mode;
-
-       /* Optimized view enabled */
-       gboolean optimized_view;
-
-       /* Whether this was created via the *_new_for_search_result() function. */
-       gboolean is_search_result;
-
-       /* 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.
-        */
-       const gchar *header_folder_id;
-       GtkTreeModel *header_model;
-       GtkTreeRowReference *row_reference;
-       GtkTreeRowReference *next_row_reference;
-
-       gulong clipboard_change_handler;
-       gulong queue_change_handler;
-       gulong account_removed_handler;
-       gulong row_changed_handler;
-       gulong row_deleted_handler;
-       gulong row_inserted_handler;
-       gulong rows_reordered_handler;
-
-       guint purge_timeout;
-       GtkWidget *remove_attachment_banner;
-
-       guint progress_bar_timeout;
-
-       gchar *msg_uid;
-       
-       GSList *sighandlers;
-};
 
 #define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
                                                     MODEST_TYPE_MSG_VIEW_WINDOW, \
@@ -255,7 +264,7 @@ modest_msg_view_window_get_type (void)
                        (GInstanceInitFunc) modest_msg_view_window_init,
                        NULL
                };
-               my_type = g_type_register_static (MODEST_TYPE_WINDOW,
+               my_type = g_type_register_static (MODEST_TYPE_HILDON2_WINDOW,
                                                  "ModestMsgViewWindow",
                                                  &my_info, 0);
 
@@ -316,16 +325,21 @@ static void
 modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass)
 {
        GObjectClass *gobject_class;
+       HildonWindowClass *hildon_window_class;
        ModestWindowClass *modest_window_class;
        GtkBindingSet *binding_set;
 
        gobject_class = (GObjectClass*) klass;
+       hildon_window_class = (HildonWindowClass *) klass;
        modest_window_class = (ModestWindowClass *) klass;
 
        parent_class            = g_type_class_peek_parent (klass);
        gobject_class->finalize = modest_msg_view_window_finalize;
 
+       modest_window_class->set_zoom_func = modest_msg_view_window_set_zoom;
        modest_window_class->get_zoom_func = modest_msg_view_window_get_zoom;
+       modest_window_class->zoom_plus_func = modest_msg_view_window_zoom_plus;
+       modest_window_class->zoom_minus_func = modest_msg_view_window_zoom_minus;
        modest_window_class->show_toolbar_func = modest_msg_view_window_show_toolbar;
        modest_window_class->disconnect_signals_func = modest_msg_view_window_disconnect_signals;
 
@@ -425,10 +439,9 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        priv->row_deleted_handler = 0;
        priv->row_inserted_handler = 0;
        priv->rows_reordered_handler = 0;
-       priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
+       priv->progress_hint = FALSE;
 
        priv->optimized_view  = FALSE;
-       priv->progress_bar_timeout = 0;
        priv->purge_timeout = 0;
        priv->remove_attachment_banner = NULL;
        priv->msg_uid = NULL;
@@ -460,88 +473,28 @@ set_toolbar_transfer_mode (ModestMsgViewWindow *self)
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
 
-       set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
-       
-       if (priv->progress_bar_timeout > 0) {
-               g_source_remove (priv->progress_bar_timeout);
-               priv->progress_bar_timeout = 0;
-       }
+       set_progress_hint (self, TRUE);
        
        return FALSE;
 }
 
 static void 
-set_toolbar_mode (ModestMsgViewWindow *self, 
-                 ModestToolBarModes mode)
+set_progress_hint (ModestMsgViewWindow *self, 
+                  gboolean enabled)
 {
        ModestWindowPrivate *parent_priv;
        ModestMsgViewWindowPrivate *priv;
-/*     GtkWidget *widget = NULL; */
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
 
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
                        
-       /* Sets current toolbar mode */
-       priv->current_toolbar_mode = mode;
-
-       /* Update toolbar dimming state */
-       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
-
-       switch (mode) {
-       case TOOLBAR_MODE_NORMAL:               
-               if (priv->progress_toolitem) {
-                       gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
-                       gtk_widget_hide (priv->progress_toolitem);
-               }
-
-               if (priv->progress_bar)
-                       gtk_widget_hide (priv->progress_bar);
-                       
-               if (priv->cancel_toolitem)
-                       gtk_widget_hide (priv->cancel_toolitem);
+       /* Sets current progress hint */
+       priv->progress_hint = enabled;
 
-               if (priv->prev_toolitem)
-                       gtk_widget_show (priv->prev_toolitem);
-               
-               if (priv->next_toolitem)
-                       gtk_widget_show (priv->next_toolitem);
-                       
-               /* Hide toolbar if optimized view is enabled */
-               if (priv->optimized_view) {
-                       gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
-                       gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
-               }
-
-               break;
-       case TOOLBAR_MODE_TRANSFER:
-               if (priv->prev_toolitem)
-                       gtk_widget_hide (priv->prev_toolitem);
-               
-               if (priv->next_toolitem)
-                       gtk_widget_hide (priv->next_toolitem);
-               
-               if (priv->progress_bar)
-                       gtk_widget_show (priv->progress_bar);
-
-               if (priv->progress_toolitem) {
-                       gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
-                       gtk_widget_show (priv->progress_toolitem);
-               }
-                       
-               if (priv->cancel_toolitem)
-                       gtk_widget_show (priv->cancel_toolitem);
-
-               /* Show toolbar if it's hiden (optimized view ) */
-               if (priv->optimized_view) {
-                       gtk_widget_set_no_show_all (parent_priv->toolbar, FALSE);
-                       gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
-               }
-
-               break;
-       default:
-               g_return_if_reached ();
+       if (GTK_WIDGET_VISIBLE (self)) {
+               hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), enabled?1:0);
        }
 
 }
@@ -580,7 +533,10 @@ init_window (ModestMsgViewWindow *obj)
        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));
 }
 
@@ -588,8 +544,8 @@ static void
 modest_msg_view_window_disconnect_signals (ModestWindow *self)
 {
        ModestMsgViewWindowPrivate *priv;
-       ModestHeaderView *header_view = NULL;
-       ModestWindow *main_window = NULL;
+       GtkWidget *header_view = NULL;
+       GtkWindow *parent_window = NULL;
        
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
 
@@ -633,21 +589,15 @@ modest_msg_view_window_disconnect_signals (ModestWindow *self)
 
        modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
        priv->sighandlers = NULL;
-       
-       main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
-                                                        FALSE); /* don't create */
-       if (!main_window)
-               return;
-       
-       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)
-               return;
-       
-       modest_header_view_remove_observer(header_view,
-                       MODEST_HEADER_VIEW_OBSERVER(self));
+
+       parent_window = gtk_window_get_transient_for (GTK_WINDOW (self));
+       if (parent_window && MODEST_IS_HEADER_WINDOW (parent_window)) {
+               header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (parent_window)));
+               if (header_view) {
+                       modest_header_view_remove_observer(MODEST_HEADER_VIEW (header_view),
+                                                          MODEST_HEADER_VIEW_OBSERVER(self));
+               }
+       }
 }      
 
 static void
@@ -666,11 +616,6 @@ modest_msg_view_window_finalize (GObject *obj)
                priv->header_model = NULL;
        }
 
-       if (priv->progress_bar_timeout > 0) {
-               g_source_remove (priv->progress_bar_timeout);
-               priv->progress_bar_timeout = 0;
-       }
-
        if (priv->remove_attachment_banner) {
                gtk_widget_destroy (priv->remove_attachment_banner);
                g_object_unref (priv->remove_attachment_banner);
@@ -785,7 +730,6 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        GObject *obj = NULL;
        ModestMsgViewWindowPrivate *priv = NULL;
        ModestWindowPrivate *parent_priv = NULL;
-       ModestDimmingRulesGroup *menu_rules_group = NULL;
        ModestDimmingRulesGroup *toolbar_rules_group = NULL;
        ModestDimmingRulesGroup *clipboard_rules_group = NULL;
 
@@ -796,20 +740,13 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        priv->msg_uid = g_strdup (msg_uid);
 
        /* Menubar */
-       parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
-       hildon_window_set_menu    (HILDON_WINDOW(obj), GTK_MENU(parent_priv->menubar));
-       gtk_widget_show (parent_priv->menubar);
-       parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
+       parent_priv->menubar = NULL;
 
-       menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
        toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
        clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
 
+       setup_menu (self);
        /* Add common dimming rules */
-       modest_dimming_rules_group_add_rules (menu_rules_group, 
-                                             modest_msg_view_menu_dimming_entries,
-                                             G_N_ELEMENTS (modest_msg_view_menu_dimming_entries),
-                                             MODEST_WINDOW (self));
        modest_dimming_rules_group_add_rules (toolbar_rules_group, 
                                              modest_msg_view_toolbar_dimming_entries,
                                              G_N_ELEMENTS (modest_msg_view_toolbar_dimming_entries),
@@ -820,10 +757,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
                                              MODEST_WINDOW (self));
 
        /* Insert dimming rules group for this window */
-       modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
        modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
        modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
-       g_object_unref (menu_rules_group);
        g_object_unref (toolbar_rules_group);
        g_object_unref (clipboard_rules_group);
 
@@ -838,6 +773,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
                          G_CALLBACK (modest_ui_actions_on_msg_attachment_clicked), obj);
        g_signal_connect (G_OBJECT(priv->msg_view), "recpt_activated",
                          G_CALLBACK (modest_ui_actions_on_msg_recpt_activated), obj);
+       g_signal_connect (G_OBJECT(priv->msg_view), "show_details",
+                         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), "fetch_image",
@@ -854,6 +791,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",
@@ -872,6 +813,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj);
        priv->last_search = NULL;
 
+       modest_msg_view_window_show_toolbar (MODEST_WINDOW (obj), TRUE);
+
        /* Init the clipboard actions dim status */
        modest_msg_view_grab_focus(MODEST_MSG_VIEW (priv->msg_view));
 
@@ -968,8 +911,102 @@ 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));
+
        /* gtk_widget_show_all (GTK_WIDGET (window)); */
        modest_msg_view_window_update_priority (window);
+       /* Check dimming rules */
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
+       modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
+
+       return MODEST_WINDOW(window);
+}
+
+ModestWindow *
+modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view, 
+                                             const gchar *modest_account_name,
+                                             const gchar *msg_uid,
+                                             GtkTreeRowReference *row_reference)
+{
+       ModestMsgViewWindow *window = NULL;
+       ModestMsgViewWindowPrivate *priv = NULL;
+       TnyFolder *header_folder = NULL;
+       ModestWindowMgr *mgr = NULL;
+       GtkTreePath *path;
+       GtkTreeIter iter;
+
+       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);
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+
+       /* Remember the message list's TreeModel so we can detect changes 
+        * and change the list selection when necessary: */
+
+       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);
+               }
+       }
+
+       /* Setup row references and connect signals */
+       priv->header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
+       g_object_ref (priv->header_model);
+
+       if (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);
+       } else {
+               priv->row_reference = NULL;
+               priv->next_row_reference = NULL;
+       }
+
+       /* Connect signals */
+       priv->row_changed_handler = 
+               g_signal_connect (GTK_TREE_MODEL(priv->header_model), "row-changed",
+                                 G_CALLBACK(modest_msg_view_window_on_row_changed),
+                                 window);
+       priv->row_deleted_handler = 
+               g_signal_connect (GTK_TREE_MODEL(priv->header_model), "row-deleted",
+                                 G_CALLBACK(modest_msg_view_window_on_row_deleted),
+                                 window);
+       priv->row_inserted_handler = 
+               g_signal_connect (GTK_TREE_MODEL(priv->header_model), "row-inserted",
+                                 G_CALLBACK(modest_msg_view_window_on_row_inserted),
+                                 window);
+       priv->rows_reordered_handler = 
+               g_signal_connect(GTK_TREE_MODEL(priv->header_model), "rows-reordered",
+                                G_CALLBACK(modest_msg_view_window_on_row_reordered),
+                                window);
+
+       if (header_view != NULL){
+               modest_header_view_add_observer(header_view,
+                               MODEST_HEADER_VIEW_OBSERVER(window));
+       }
+
+       tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), NULL);
+
+       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, row_reference);
+       }
+       gtk_tree_path_free (path);
 
        /* Check dimming rules */
        modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
@@ -1289,7 +1326,7 @@ modest_msg_view_window_toolbar_on_transfer_mode     (ModestMsgViewWindow *self)
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
 
-       return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
+       return priv->progress_hint;
 }
 
 TnyHeader*
@@ -1380,7 +1417,9 @@ modest_msg_view_window_toggle_find_toolbar (GtkToggleAction *toggle,
 
        /* update the toggle buttons status */
        action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage");
-       modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active);
+       if (action)
+               modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active);
+
 }
 
 static void
@@ -1393,7 +1432,7 @@ modest_msg_view_window_find_toolbar_close (GtkWidget *widget,
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (obj);
        parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
-       
+
        toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"));
        gtk_toggle_action_set_active (toggle, FALSE);
        modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
@@ -1415,7 +1454,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;
        }
 
@@ -1426,20 +1465,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);
                }
        }
@@ -1448,6 +1487,21 @@ modest_msg_view_window_find_toolbar_search (GtkWidget *widget,
                
 }
 
+static void
+modest_msg_view_window_set_zoom (ModestWindow *window,
+                                gdouble zoom)
+{
+       ModestMsgViewWindowPrivate *priv;
+       ModestWindowPrivate *parent_priv;
+     
+       g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+       parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
+       modest_zoomable_set_zoom (MODEST_ZOOMABLE (priv->msg_view), zoom);
+
+}
+
 static gdouble
 modest_msg_view_window_get_zoom (ModestWindow *window)
 {
@@ -1460,6 +1514,89 @@ modest_msg_view_window_get_zoom (ModestWindow *window)
 }
 
 static gboolean
+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);
+  
+       zoom_level =  modest_zoomable_get_zoom (MODEST_ZOOMABLE (priv->msg_view));
+
+       if (zoom_level >= 2.0) {
+               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;
+       } else if (zoom_level >= 1.2) {
+               zoom_level = 1.5;
+       } else if (zoom_level >= 1.0) {
+               zoom_level = 1.2;
+       } else if (zoom_level >= 0.8) {
+               zoom_level = 1.0;
+       } else if (zoom_level >= 0.5) {
+               zoom_level = 0.8;
+       } else {
+               zoom_level = 0.5;
+       }
+
+       /* 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
+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);
+  
+       zoom_level =  modest_zoomable_get_zoom (MODEST_ZOOMABLE (priv->msg_view));
+
+       if (zoom_level <= 0.5) {
+               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;
+       } else if (zoom_level <= 1.0) {
+               zoom_level = 0.8;
+       } else if (zoom_level <= 1.2) {
+               zoom_level = 1.0;
+       } else if (zoom_level <= 1.5) {
+               zoom_level = 1.2;
+       } else if (zoom_level <= 2.0) {
+               zoom_level = 1.5;
+       } else {
+               zoom_level = 2.0;
+       }
+
+       /* 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
 modest_msg_view_window_key_event (GtkWidget *window,
                                  GdkEventKey *event,
                                  gpointer userdata)
@@ -1490,7 +1627,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:
@@ -1512,7 +1649,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;
@@ -1663,6 +1800,7 @@ message_reader_performer (gboolean canceled,
 
        info = (MsgReaderInfo *) user_data;
        if (canceled || err) {
+               update_window_title (MODEST_MSG_VIEW_WINDOW (parent_window));
                goto frees;
        }
 
@@ -1673,7 +1811,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);
@@ -1717,6 +1855,11 @@ message_reader (ModestMsgViewWindow *window,
        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())) {
@@ -1724,9 +1867,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);
@@ -1873,12 +2018,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;
        }
 
@@ -2006,7 +2163,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 */
@@ -2026,17 +2183,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->progress_toolitem), FALSE);
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
-               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
+
                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
@@ -2046,8 +2198,6 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
        ModestMsgViewWindowPrivate *priv = NULL;
        ModestWindowPrivate *parent_priv;
        GtkWidget *reply_button = NULL, *menu = NULL;
-       GtkWidget *placeholder = NULL;
-       gint insert_index;
 
        parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
@@ -2058,30 +2208,13 @@ 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->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
-               priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
                priv->next_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNext");
                priv->prev_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageBack");
                toolbar_resize (MODEST_MSG_VIEW_WINDOW (self));
 
-               /* Add ProgressBar (Transfer toolbar) */ 
-               priv->progress_bar = modest_progress_bar_new ();
-               gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
-               placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressbarView");
-               insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
-               gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
-               gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
-
-               /* Connect cancel 'clicked' signal to abort progress mode */
-               g_signal_connect(priv->cancel_toolitem, "clicked",
-                                G_CALLBACK(cancel_progressbar),
-                                self);
-
-               /* Add it to the observers list */
-               priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
-
                /* Add to window */
                hildon_window_add_toolbar (HILDON_WINDOW (self), 
                                           GTK_TOOLBAR (parent_priv->toolbar));
@@ -2091,7 +2224,8 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
                                                          "/ToolBar/ToolbarMessageReply");
                menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
                                                  "/ToolbarReplyCSM");
-               gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
+               if (menu && reply_button)
+                       gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
        }
 
        if (show_toolbar) {
@@ -2101,9 +2235,9 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
 
                gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
                if (modest_msg_view_window_transfer_mode_enabled (MODEST_MSG_VIEW_WINDOW (self))) 
-                       set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_TRANSFER);
+                       set_progress_hint (MODEST_MSG_VIEW_WINDOW (self), TRUE);
                else
-                       set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_NORMAL);
+                       set_progress_hint (MODEST_MSG_VIEW_WINDOW (self), FALSE);
 
        } else {
                gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
@@ -2130,25 +2264,9 @@ modest_msg_view_window_transfer_mode_enabled (ModestMsgViewWindow *self)
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE); 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
 
-       return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
+       return priv->progress_hint;
 }
 
-static void
-cancel_progressbar (GtkToolButton *toolbutton,
-                   ModestMsgViewWindow *self)
-{
-       GSList *tmp;
-       ModestMsgViewWindowPrivate *priv;
-       
-       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
-
-       /* Get operation observers and cancel its current operation */
-       tmp = priv->progress_widgets;
-       while (tmp) {
-               modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
-               tmp=g_slist_next(tmp);
-       }
-}
 static gboolean
 observers_empty (ModestMsgViewWindow *self)
 {
@@ -2186,7 +2304,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));
        }
 }
@@ -2207,7 +2325,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 (
@@ -2234,7 +2352,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);
@@ -2243,17 +2361,17 @@ on_mail_operation_finished (ModestMailOperation *mail_op,
 
                /* If no more operations are being observed, NORMAL mode is enabled again */
                if (observers_empty (self)) {
-                       set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
+                       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
@@ -2300,29 +2418,12 @@ 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;
-} 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"));
-       g_object_ref (helper->banner);
-
-       return FALSE;
-}
-
 static void
 on_decode_to_stream_async_handler (TnyMimePart *mime_part, 
                                   gboolean cancelled, 
@@ -2330,15 +2431,8 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
                                   GError *err, 
                                   gpointer user_data)
 {
-       DecodeAsyncHelper *helper = (DecodeAsyncHelper *) user_data;
+       gchar *filepath = (gchar *) 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);
-       }
        if (cancelled || err) {
                modest_platform_information_banner (NULL, NULL, 
                                                    _("mail_ib_file_operation_failed"));
@@ -2346,16 +2440,14 @@ on_decode_to_stream_async_handler (TnyMimePart *mime_part,
        }
 
        /* make the file read-only */
-       g_chmod(helper->filepath, 0444);
-       
+       g_chmod(filepath, 0444);
+
        /* Activate the file */
-       modest_platform_activate_file (helper->filepath, tny_mime_part_get_content_type (mime_part));
+       modest_platform_activate_file (filepath, tny_mime_part_get_content_type (mime_part));
 
  free:
        /* Frees */
-       g_free (helper->filepath);
-       g_object_unref (helper->banner);
-       g_slice_free (DecodeAsyncHelper, helper);
+       g_free (filepath);
 }
 
 void
@@ -2415,16 +2507,12 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window,
                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, 
-                                                             helper);
+                                                             NULL,
+                                                             g_strdup (filepath));
                        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 */
@@ -2484,7 +2572,6 @@ typedef struct
 typedef struct
 {
        GList *pairs;
-       GtkWidget *banner;
        GnomeVFSResult result;
 } SaveMimePartInfo;
 
@@ -2507,7 +2594,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);
        }
 }
@@ -2526,8 +2612,8 @@ 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"));
+                       hildon_banner_show_information (NULL, NULL, 
+                                                       _KR("cerm_device_memory_full"));
                } else {
                        hildon_banner_show_information (NULL, NULL, _("mail_ib_file_operation_failed"));
                }
@@ -2550,8 +2636,14 @@ 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);
@@ -2594,9 +2686,6 @@ save_mime_parts_to_file_with_checks (SaveMimePartInfo *info)
        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);
        }
 
@@ -2620,7 +2709,7 @@ save_attachments_response (GtkDialog *dialog,
 
        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;
 
@@ -2632,7 +2721,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) {
@@ -2678,7 +2767,13 @@ 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));
+               /* 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 (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), mime_parts)) {
+                       g_object_unref (mime_parts);
+                       return;
+               }
                if (mime_parts == NULL || tny_list_get_length (mime_parts) == 0)
                        return;
        } else {
@@ -2707,12 +2802,12 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m
                save_multiple_str = g_strdup_printf (_FM("sfil_va_number_of_objects_attachments"), 
                                                     tny_list_get_length (mime_parts));
        }
-       
+
        save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), 
                                                      GTK_FILE_CHOOSER_ACTION_SAVE);
 
        /* set folder */
-       folder = g_build_filename (g_get_home_dir (), DEFAULT_FOLDER, NULL);
+       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);
 
@@ -2774,10 +2869,10 @@ 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));
+       /* 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 */
        iter = tny_list_create_iterator (mime_parts);
@@ -2791,7 +2886,8 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
        }
        g_object_unref (iter);
 
-       if (tny_list_get_length (mime_parts) == 0) {
+       if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), mime_parts) ||
+           tny_list_get_length (mime_parts) == 0) {
                g_object_unref (mime_parts);
                return;
        }
@@ -2870,11 +2966,18 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
 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) {
@@ -2893,9 +2996,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");
 }
@@ -3011,7 +3115,42 @@ on_fetch_image (ModestMsgView *msgview,
                return FALSE;
        }
 
-       return TRUE;;
+       return TRUE;
+}
+
+static void 
+setup_menu (ModestMsgViewWindow *self)
+{
+       g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(self));
+
+       /* Settings menu buttons */
+       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_replytoall"), NULL,
+                                          APP_MENU_CALLBACK (modest_ui_actions_on_reply_all),
+                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_reply_msg));
+       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));
 }
 
 void
@@ -3024,16 +3163,28 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
        gboolean contacts_to_add = FALSE;
 
        msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
-       if (msg == NULL) return;
-       recipients = modest_tny_msg_get_all_recipients_list (msg);
+       if (msg == NULL) {
+               TnyHeader *header;
+
+               header = modest_msg_view_window_get_header (self);
+               if (header == NULL)
+                       return;
+               recipients = modest_tny_msg_header_get_all_recipients_list (header);
+               g_object_unref (header);
+       } else {
+               recipients = modest_tny_msg_get_all_recipients_list (msg);
+               g_object_unref (msg);
+       }
 
        if (recipients != NULL) {
                GtkWidget *picker_dialog;
                GtkWidget *selector;
                GSList *node;
-               gchar *selected;
+               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), 
@@ -3043,6 +3194,7 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
                }
 
                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"));
@@ -3050,8 +3202,11 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
                        hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (picker_dialog), 
                                                           HILDON_TOUCH_SELECTOR (selector));
                        
-                       gtk_dialog_run (GTK_DIALOG (picker_dialog));
-                       selected = hildon_touch_selector_get_current_text (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)
@@ -3066,5 +3221,19 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
        }
        
        if (recipients) {g_slist_foreach (recipients, (GFunc) g_free, NULL); g_slist_free (recipients);}
-       g_object_unref (msg);
+}
+
+static gboolean 
+_modest_msg_view_window_map_event (GtkWidget *widget,
+                                  GdkEvent *event,
+                                  gpointer userdata)
+{
+       ModestMsgViewWindow *self = (ModestMsgViewWindow *) userdata;
+       ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+
+       if (priv->progress_hint) {
+               hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
+       }
+
+       return FALSE;
 }