Fix memory leak in select_next_valid_row()
[modest] / src / maemo / modest-msg-view-window.c
index 1dfe7d2..8c6d40f 100644 (file)
 #include <tny-vfs-stream.h>
 #include "modest-marshal.h"
 #include "modest-platform.h"
 #include <tny-vfs-stream.h>
 #include "modest-marshal.h"
 #include "modest-platform.h"
+#include <modest-utils.h>
 #include <modest-maemo-utils.h>
 #include <modest-tny-msg.h>
 #include <modest-msg-view-window.h>
 #include <modest-maemo-utils.h>
 #include <modest-tny-msg.h>
 #include <modest-msg-view-window.h>
-#include <modest-attachments-view.h>
 #include <modest-main-window-ui.h>
 #include "modest-msg-view-window-ui-dimming.h"
 #include <modest-widget-memory.h>
 #include <modest-main-window-ui.h>
 #include "modest-msg-view-window-ui-dimming.h"
 #include <modest-widget-memory.h>
@@ -56,6 +56,8 @@
 #include <modest-mime-part-view.h>
 #include <modest-isearch-view.h>
 #include <math.h>
 #include <modest-mime-part-view.h>
 #include <modest-isearch-view.h>
 #include <math.h>
+#include <errno.h>
+#include <glib/gstdio.h>
 
 #define DEFAULT_FOLDER "MyDocs/.documents"
 
 
 #define DEFAULT_FOLDER "MyDocs/.documents"
 
@@ -77,14 +79,12 @@ static void modest_msg_view_window_set_zoom (ModestWindow *window,
 static gdouble modest_msg_view_window_get_zoom (ModestWindow *window);
 static gboolean modest_msg_view_window_zoom_minus (ModestWindow *window);
 static gboolean modest_msg_view_window_zoom_plus (ModestWindow *window);
 static gdouble modest_msg_view_window_get_zoom (ModestWindow *window);
 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_release_event (GtkWidget *window,
-                                                         GdkEventKey *event,
-                                                         gpointer userdata);
+static gboolean modest_msg_view_window_key_event (GtkWidget *window,
+                                                 GdkEventKey *event,
+                                                 gpointer userdata);
 static gboolean modest_msg_view_window_window_state_event (GtkWidget *widget, 
                                                           GdkEventWindowState *event, 
                                                           gpointer userdata);
 static gboolean modest_msg_view_window_window_state_event (GtkWidget *widget, 
                                                           GdkEventWindowState *event, 
                                                           gpointer userdata);
-static void modest_msg_view_window_scroll_up (ModestWindow *window);
-static void modest_msg_view_window_scroll_down (ModestWindow *window);
 static void modest_msg_view_window_update_priority (ModestMsgViewWindow *window);
 
 static void modest_msg_view_window_show_toolbar   (ModestWindow *window,
 static void modest_msg_view_window_update_priority (ModestMsgViewWindow *window);
 
 static void modest_msg_view_window_show_toolbar   (ModestWindow *window,
@@ -134,13 +134,15 @@ static void on_account_removed  (TnyAccountStore *account_store,
                                 TnyAccount *account,
                                 gpointer user_data);
 
                                 TnyAccount *account,
                                 gpointer user_data);
 
-static void on_move_focus (ModestMsgViewWindow *window,
+static void on_move_focus (GtkWidget *widget,
                           GtkDirectionType direction,
                           gpointer userdata);
 
 static void view_msg_cb         (ModestMailOperation *mail_op, 
                                 TnyHeader *header, 
                           GtkDirectionType direction,
                           gpointer userdata);
 
 static void view_msg_cb         (ModestMailOperation *mail_op, 
                                 TnyHeader *header, 
+                                gboolean canceled,
                                 TnyMsg *msg, 
                                 TnyMsg *msg, 
+                                GError *error,
                                 gpointer user_data);
 
 static void set_toolbar_mode    (ModestMsgViewWindow *self, 
                                 gpointer user_data);
 
 static void set_toolbar_mode    (ModestMsgViewWindow *self, 
@@ -149,6 +151,9 @@ static void set_toolbar_mode    (ModestMsgViewWindow *self,
 static void update_window_title (ModestMsgViewWindow *window);
 
 static gboolean set_toolbar_transfer_mode     (ModestMsgViewWindow *self); 
 static void update_window_title (ModestMsgViewWindow *window);
 
 static gboolean set_toolbar_transfer_mode     (ModestMsgViewWindow *self); 
+static void init_window (ModestMsgViewWindow *obj);
+
+static gboolean msg_is_visible (TnyHeader *header, gboolean check_outbox);
 
 
 /* list my signals */
 
 
 /* list my signals */
@@ -159,7 +164,7 @@ 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 },
 
 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 },
-       { "ToolsFindInMessage", NULL, N_("mcen_me_viewer_find"), NULL, NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE },
+       { "ToolsFindInMessage", NULL, N_("mcen_me_viewer_find"), "<CTRL>F", NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE },
 };
 
 static const GtkRadioActionEntry msg_view_zoom_action_entries [] = {
 };
 
 static const GtkRadioActionEntry msg_view_zoom_action_entries [] = {
@@ -195,6 +200,9 @@ struct _ModestMsgViewWindowPrivate {
 
        /* Whether this was created via the *_new_for_search_result() function. */
        gboolean is_search_result;
 
        /* 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,
        
        /* A reference to the @model of the header view 
         * to allow selecting previous/next messages,
@@ -219,6 +227,8 @@ struct _ModestMsgViewWindowPrivate {
        guint progress_bar_timeout;
 
        gchar *msg_uid;
        guint progress_bar_timeout;
 
        gchar *msg_uid;
+       
+       GSList *sighandlers;
 };
 
 #define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
 };
 
 #define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
@@ -277,7 +287,20 @@ save_state (ModestWindow *self)
 static void
 restore_settings (ModestMsgViewWindow *self)
 {
 static void
 restore_settings (ModestMsgViewWindow *self)
 {
-       modest_widget_memory_restore (modest_runtime_get_conf (),
+       ModestConf *conf;
+       ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
+       GtkAction *action;
+
+       conf = modest_runtime_get_conf ();
+       action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
+                                           "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu");
+       gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+                                     modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR, NULL));
+       action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
+                                           "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarFullScreenMenu");
+       gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+                                     modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
+       modest_widget_memory_restore (conf,
                                      G_OBJECT(self), 
                                      MODEST_CONF_MSG_VIEW_WINDOW_KEY);
 }
                                      G_OBJECT(self), 
                                      MODEST_CONF_MSG_VIEW_WINDOW_KEY);
 }
@@ -324,9 +347,57 @@ static void
 modest_msg_view_window_init (ModestMsgViewWindow *obj)
 {
        ModestMsgViewWindowPrivate *priv;
 modest_msg_view_window_init (ModestMsgViewWindow *obj)
 {
        ModestMsgViewWindowPrivate *priv;
+       ModestWindowPrivate *parent_priv = NULL;
+       GtkActionGroup *action_group = NULL;
+       GError *error = NULL;
+       GdkPixbuf *window_icon;
+
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
+       parent_priv = MODEST_WINDOW_GET_PRIVATE(obj);
+       parent_priv->ui_manager = gtk_ui_manager_new();
+
+       action_group = gtk_action_group_new ("ModestMsgViewWindowActions");
+       gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
+
+       /* Add common actions */
+       gtk_action_group_add_actions (action_group,
+                                     modest_action_entries,
+                                     G_N_ELEMENTS (modest_action_entries),
+                                     obj);
+       gtk_action_group_add_toggle_actions (action_group,
+                                            modest_toggle_action_entries,
+                                            G_N_ELEMENTS (modest_toggle_action_entries),
+                                            obj);
+       gtk_action_group_add_toggle_actions (action_group,
+                                            msg_view_toggle_action_entries,
+                                            G_N_ELEMENTS (msg_view_toggle_action_entries),
+                                            obj);
+       gtk_action_group_add_radio_actions (action_group,
+                                           msg_view_zoom_action_entries,
+                                           G_N_ELEMENTS (msg_view_zoom_action_entries),
+                                           100,
+                                           G_CALLBACK (modest_ui_actions_on_change_zoom),
+                                           obj);
+
+       gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
+       g_object_unref (action_group);
+
+       /* Load the UI definition */
+       gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-view-window-ui.xml",
+                                        &error);
+       if (error) {
+               g_printerr ("modest: could not merge modest-msg-view-window-ui.xml: %s\n", error->message);
+               g_error_free (error);
+               error = NULL;
+       }
+       /* ****** */
 
 
+       /* Add accelerators */
+       gtk_window_add_accel_group (GTK_WINDOW (obj), 
+                                   gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
+       
        priv->is_search_result = FALSE;
        priv->is_search_result = FALSE;
+       priv->is_outbox = FALSE;
 
        priv->msg_view      = NULL;
        priv->header_model  = NULL;
 
        priv->msg_view      = NULL;
        priv->header_model  = NULL;
@@ -345,6 +416,24 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        priv->purge_timeout = 0;
        priv->remove_attachment_banner = NULL;
        priv->msg_uid = NULL;
        priv->purge_timeout = 0;
        priv->remove_attachment_banner = NULL;
        priv->msg_uid = NULL;
+       
+       priv->sighandlers = NULL;
+       
+       /* Init window */
+       init_window (MODEST_MSG_VIEW_WINDOW(obj));
+       
+       /* Set window icon */
+       window_icon = modest_platform_get_icon (MODEST_APP_MSG_VIEW_ICON, MODEST_ICON_SIZE_BIG); 
+       if (window_icon) {
+               gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
+               g_object_unref (window_icon);
+       }       
+       
+       hildon_program_add_window (hildon_program_get_instance(),
+                                  HILDON_WINDOW(obj));
+
+       modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
+                                           GTK_WINDOW(obj),"applications_email_viewer");
 }
 
 
 }
 
 
@@ -388,29 +477,23 @@ set_toolbar_mode (ModestMsgViewWindow *self,
 
        switch (mode) {
        case TOOLBAR_MODE_NORMAL:               
 
        switch (mode) {
        case TOOLBAR_MODE_NORMAL:               
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); */
-/*             gtk_action_set_sensitive (widget, TRUE); */
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage"); */
-/*             gtk_action_set_sensitive (widget, TRUE); */
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo"); */
-/*             gtk_action_set_sensitive (widget, TRUE); */
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"); */
-/*             gtk_action_set_sensitive (widget, TRUE); */
-
-               if (priv->prev_toolitem)
-                       gtk_widget_show (priv->prev_toolitem);
-               
-               if (priv->next_toolitem)
-                       gtk_widget_show (priv->next_toolitem);
-                       
-               if (priv->progress_toolitem)
+               if (priv->progress_toolitem) {
                        gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
                        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);
 
                if (priv->progress_bar)
                        gtk_widget_hide (priv->progress_bar);
                        
                if (priv->cancel_toolitem)
                        gtk_widget_hide (priv->cancel_toolitem);
 
+               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);
                /* Hide toolbar if optimized view is enabled */
                if (priv->optimized_view) {
                        gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
@@ -419,25 +502,19 @@ set_toolbar_mode (ModestMsgViewWindow *self,
 
                break;
        case TOOLBAR_MODE_TRANSFER:
 
                break;
        case TOOLBAR_MODE_TRANSFER:
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); */
-/*             gtk_action_set_sensitive (widget, FALSE); */
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage"); */
-/*             gtk_action_set_sensitive (widget, FALSE); */
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo"); */
-/*             gtk_action_set_sensitive (widget, FALSE); */
-/*             widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"); */
-/*             gtk_action_set_sensitive (widget, FALSE); */
-
                if (priv->prev_toolitem)
                        gtk_widget_hide (priv->prev_toolitem);
                
                if (priv->next_toolitem)
                        gtk_widget_hide (priv->next_toolitem);
                
                if (priv->prev_toolitem)
                        gtk_widget_hide (priv->prev_toolitem);
                
                if (priv->next_toolitem)
                        gtk_widget_hide (priv->next_toolitem);
                
-               if (priv->progress_toolitem)
-                       gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
                if (priv->progress_bar)
                        gtk_widget_show (priv->progress_bar);
                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);
                        
                if (priv->cancel_toolitem)
                        gtk_widget_show (priv->cancel_toolitem);
@@ -456,63 +533,18 @@ set_toolbar_mode (ModestMsgViewWindow *self,
 }
 
 
 }
 
 
-static GtkWidget *
-menubar_to_menu (GtkUIManager *ui_manager)
-{
-       GtkWidget *main_menu;
-       GtkWidget *menubar;
-       GList *iter, *children;
-
-       /* Create new main menu */
-       main_menu = gtk_menu_new();
-
-       /* Get the menubar from the UI manager */
-       menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
-
-       iter = children = gtk_container_get_children (GTK_CONTAINER (menubar));
-       while (iter) {
-               GtkWidget *menu;
-
-               menu = GTK_WIDGET (iter->data);
-               gtk_widget_reparent(menu, main_menu);
-               
-               iter = g_list_next (iter);
-       }
-       g_list_free (children);
-                    
-       return main_menu;
-}
-
 static void
 init_window (ModestMsgViewWindow *obj)
 {
        GtkWidget *main_vbox;
        ModestMsgViewWindowPrivate *priv;
 static void
 init_window (ModestMsgViewWindow *obj)
 {
        GtkWidget *main_vbox;
        ModestMsgViewWindowPrivate *priv;
-       ModestWindowPrivate *parent_priv;
-       ModestConf *conf;
-       GtkAction *action = NULL;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
-       parent_priv = MODEST_WINDOW_GET_PRIVATE(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);
 
 
        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);
 
-       /* Menubar */
-       parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
-       conf = modest_runtime_get_conf ();
-       action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
-                                           "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu");
-       gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-                                     modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR, NULL));
-       action = gtk_ui_manager_get_action (parent_priv->ui_manager, 
-                                           "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarFullScreenMenu");
-       gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-                                     modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
-       hildon_window_set_menu    (HILDON_WINDOW(obj), GTK_MENU(parent_priv->menubar));
-       gtk_widget_show (GTK_WIDGET(parent_priv->menubar));
-
 #ifdef MODEST_USE_MOZEMBED
        priv->main_scroll = priv->msg_view;
        gtk_widget_set_size_request (priv->msg_view, -1, 1600);
 #ifdef MODEST_USE_MOZEMBED
        priv->main_scroll = priv->msg_view;
        gtk_widget_set_size_request (priv->msg_view, -1, 1600);
@@ -530,10 +562,7 @@ 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);
        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->clipboard_change_handler = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change", G_CALLBACK (modest_msg_view_window_clipboard_owner_change), obj);
        gtk_widget_show_all (GTK_WIDGET(main_vbox));
 }
 
        gtk_widget_show_all (GTK_WIDGET(main_vbox));
 }
 
@@ -584,6 +613,9 @@ modest_msg_view_window_disconnect_signals (ModestWindow *self)
                                                    priv->rows_reordered_handler);
        }
 
                                                    priv->rows_reordered_handler);
        }
 
+       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)
        main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
                                                         FALSE); /* don't create */
        if (!main_window)
@@ -656,7 +688,8 @@ select_next_valid_row (GtkTreeModel *model,
                       gboolean cycle)
 {
        GtkTreeIter tmp_iter;
                       gboolean cycle)
 {
        GtkTreeIter tmp_iter;
-       GtkTreePath *path, *next;
+       GtkTreePath *path;
+       GtkTreePath *next = NULL;
        gboolean retval = FALSE;
 
        g_return_val_if_fail (gtk_tree_row_reference_valid (*row_reference), FALSE);
        gboolean retval = FALSE;
 
        g_return_val_if_fail (gtk_tree_row_reference_valid (*row_reference), FALSE);
@@ -682,6 +715,8 @@ select_next_valid_row (GtkTreeModel *model,
 
        /* Free */
        gtk_tree_path_free (path);
 
        /* Free */
        gtk_tree_path_free (path);
+       if (next)
+               gtk_tree_path_free (next);
 
        return retval;
 }
 
        return retval;
 }
@@ -698,9 +733,6 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        ModestDimmingRulesGroup *menu_rules_group = NULL;
        ModestDimmingRulesGroup *toolbar_rules_group = NULL;
        ModestDimmingRulesGroup *clipboard_rules_group = NULL;
        ModestDimmingRulesGroup *menu_rules_group = NULL;
        ModestDimmingRulesGroup *toolbar_rules_group = NULL;
        ModestDimmingRulesGroup *clipboard_rules_group = NULL;
-       GtkActionGroup *action_group = NULL;
-       GError *error = NULL;
-       GdkPixbuf *window_icon;
 
        obj = G_OBJECT (self);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
 
        obj = G_OBJECT (self);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
@@ -708,48 +740,15 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
 
        priv->msg_uid = g_strdup (msg_uid);
 
 
        priv->msg_uid = g_strdup (msg_uid);
 
-       parent_priv->ui_manager = gtk_ui_manager_new();
+       /* 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->ui_dimming_manager = modest_ui_dimming_manager_new();
 
-       action_group = gtk_action_group_new ("ModestMsgViewWindowActions");
-       gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
-
-       menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
-       toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
-       clipboard_rules_group = modest_dimming_rules_group_new ("ModestClipboardDimmingRules", FALSE);
-
-       /* Add common actions */
-       gtk_action_group_add_actions (action_group,
-                                     modest_action_entries,
-                                     G_N_ELEMENTS (modest_action_entries),
-                                     obj);
-       gtk_action_group_add_toggle_actions (action_group,
-                                            modest_toggle_action_entries,
-                                            G_N_ELEMENTS (modest_toggle_action_entries),
-                                            obj);
-       gtk_action_group_add_toggle_actions (action_group,
-                                            msg_view_toggle_action_entries,
-                                            G_N_ELEMENTS (msg_view_toggle_action_entries),
-                                            obj);
-       gtk_action_group_add_radio_actions (action_group,
-                                           msg_view_zoom_action_entries,
-                                           G_N_ELEMENTS (msg_view_zoom_action_entries),
-                                           100,
-                                           G_CALLBACK (modest_ui_actions_on_change_zoom),
-                                           obj);
-
-       gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
-       g_object_unref (action_group);
-
-       /* Load the UI definition */
-       gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-view-window-ui.xml",
-                                        &error);
-       if (error) {
-               g_printerr ("modest: could not merge modest-msg-view-window-ui.xml: %s\n", error->message);
-               g_error_free (error);
-               error = 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);
 
        /* Add common dimming rules */
        modest_dimming_rules_group_add_rules (menu_rules_group, 
 
        /* Add common dimming rules */
        modest_dimming_rules_group_add_rules (menu_rules_group, 
@@ -773,23 +772,11 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        g_object_unref (toolbar_rules_group);
        g_object_unref (clipboard_rules_group);
 
        g_object_unref (toolbar_rules_group);
        g_object_unref (clipboard_rules_group);
 
-       /* Add accelerators */
-       gtk_window_add_accel_group (GTK_WINDOW (obj), 
-                                   gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
-       
-       /* Init window */
-       init_window (MODEST_MSG_VIEW_WINDOW(obj));
        restore_settings (MODEST_MSG_VIEW_WINDOW(obj));
        
        restore_settings (MODEST_MSG_VIEW_WINDOW(obj));
        
-       /* Set window icon */
-       window_icon = modest_platform_get_icon (MODEST_APP_MSG_VIEW_ICON); 
-       if (window_icon) {
-               gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
-               g_object_unref (window_icon);
-       }
-
        /* g_signal_connect (G_OBJECT(obj), "delete-event", G_CALLBACK(on_delete_event), obj); */
 
        /* g_signal_connect (G_OBJECT(obj), "delete-event", G_CALLBACK(on_delete_event), obj); */
 
+       priv->clipboard_change_handler = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change", G_CALLBACK (modest_msg_view_window_clipboard_owner_change), obj);
        g_signal_connect (G_OBJECT(priv->msg_view), "activate_link",
                          G_CALLBACK (modest_ui_actions_on_msg_link_clicked), obj);
        g_signal_connect (G_OBJECT(priv->msg_view), "link_hover",
        g_signal_connect (G_OBJECT(priv->msg_view), "activate_link",
                          G_CALLBACK (modest_ui_actions_on_msg_link_clicked), obj);
        g_signal_connect (G_OBJECT(priv->msg_view), "link_hover",
@@ -802,7 +789,11 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
                          G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj);
 
        g_signal_connect (G_OBJECT (obj), "key-release-event",
                          G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj);
 
        g_signal_connect (G_OBJECT (obj), "key-release-event",
-                         G_CALLBACK (modest_msg_view_window_key_release_event),
+                         G_CALLBACK (modest_msg_view_window_key_event),
+                         NULL);
+
+       g_signal_connect (G_OBJECT (obj), "key-press-event",
+                         G_CALLBACK (modest_msg_view_window_key_event),
                          NULL);
 
        g_signal_connect (G_OBJECT (obj), "window-state-event",
                          NULL);
 
        g_signal_connect (G_OBJECT (obj), "window-state-event",
@@ -826,16 +817,16 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
 
        modest_window_set_active_account (MODEST_WINDOW(obj), modest_account_name);
 
 
        modest_window_set_active_account (MODEST_WINDOW(obj), modest_account_name);
 
+       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));
 
        priv->last_search = NULL;
 
        /* Init the clipboard actions dim status */
        modest_msg_view_grab_focus(MODEST_MSG_VIEW (priv->msg_view));
 
+       gtk_widget_show_all (GTK_WIDGET (obj));
        update_window_title (MODEST_MSG_VIEW_WINDOW (obj));
 
        update_window_title (MODEST_MSG_VIEW_WINDOW (obj));
 
-       /* Check toolbar dimming rules */
-       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
-       modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), "ModestClipboardDimmingRules");
 
 }
 
 
 }
 
@@ -852,8 +843,10 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        TnyFolder *header_folder = NULL;
        ModestHeaderView *header_view = NULL;
        ModestWindow *main_window = NULL;
        TnyFolder *header_folder = NULL;
        ModestHeaderView *header_view = NULL;
        ModestWindow *main_window = NULL;
-       
-       window = g_object_new(MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
+       ModestWindowMgr *mgr = NULL;
+
+       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);
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL);
 
        modest_msg_view_window_construct (window, modest_account_name, msg_uid);
@@ -863,18 +856,16 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        /* Remember the message list's TreeModel so we can detect changes 
         * and change the list selection when necessary: */
 
        /* 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(
-               modest_runtime_get_window_mgr(), FALSE); /* don't create */
-       if (!main_window) {
-               g_warning ("%s: BUG: no main window", __FUNCTION__);
-               return NULL;
+       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));
        }
        
        }
        
-       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);
        if (header_view != NULL){
                header_folder = modest_header_view_get_folder(header_view);
+               priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) == TNY_FOLDER_TYPE_OUTBOX);
                g_assert(header_folder != NULL);
                priv->header_folder_id = tny_folder_get_id(header_folder);
                g_assert(priv->header_folder_id != NULL);
                g_assert(header_folder != NULL);
                priv->header_folder_id = tny_folder_get_id(header_folder);
                g_assert(priv->header_folder_id != NULL);
@@ -882,9 +873,14 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        }
 
        priv->header_model = g_object_ref(model);
        }
 
        priv->header_model = g_object_ref(model);
-       priv->row_reference = gtk_tree_row_reference_copy (row_reference);
-       priv->next_row_reference = gtk_tree_row_reference_copy (row_reference);
-       select_next_valid_row (model, &(priv->next_row_reference), TRUE);
+       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 (model, &(priv->next_row_reference), TRUE);
+       } else {
+               priv->row_reference = NULL;
+               priv->next_row_reference = NULL;
+       }
 
        priv->row_changed_handler = g_signal_connect(
                        GTK_TREE_MODEL(model), "row-changed",
 
        priv->row_changed_handler = g_signal_connect(
                        GTK_TREE_MODEL(model), "row-changed",
@@ -908,14 +904,15 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
                                MODEST_HEADER_VIEW_OBSERVER(window));
        }
 
                                MODEST_HEADER_VIEW_OBSERVER(window));
        }
 
-       gtk_widget_show_all (GTK_WIDGET (window));
-
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), 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);
 
        modest_msg_view_window_update_priority (window);
 
-       /* Check toolbar dimming rules */
+       /* Check dimming rules */
        modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
        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);
 }
 
        return MODEST_WINDOW(window);
 }
@@ -927,8 +924,10 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg,
 {
        ModestMsgViewWindow *window = NULL;
        ModestMsgViewWindowPrivate *priv = NULL;
 {
        ModestMsgViewWindow *window = NULL;
        ModestMsgViewWindowPrivate *priv = NULL;
+       ModestWindowMgr *mgr = NULL;
 
 
-       window = g_object_new(MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
+       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);
 
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL);
        modest_msg_view_window_construct (window, modest_account_name, msg_uid);
 
@@ -939,6 +938,10 @@ 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);
        priv->is_search_result = TRUE;
 
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
+       
+       update_window_title (window);
+       modest_msg_view_window_update_priority (window);
+
 
        return MODEST_WINDOW(window);
 }
 
        return MODEST_WINDOW(window);
 }
@@ -949,15 +952,23 @@ modest_msg_view_window_new_for_attachment (TnyMsg *msg,
                            const gchar *msg_uid)
 {
        GObject *obj = NULL;
                            const gchar *msg_uid)
 {
        GObject *obj = NULL;
-       ModestMsgViewWindowPrivate *priv;
+       ModestMsgViewWindowPrivate *priv;       
+       ModestWindowMgr *mgr = NULL;
+
        g_return_val_if_fail (msg, NULL);
        g_return_val_if_fail (msg, NULL);
-       
-       obj = g_object_new(MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
+       mgr = modest_runtime_get_window_mgr ();
+       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);
 
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (obj);
        modest_msg_view_window_construct (MODEST_MSG_VIEW_WINDOW (obj), 
                modest_account_name, msg_uid);
 
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
+       update_window_title (MODEST_MSG_VIEW_WINDOW (obj));
+
+       /* Check dimming rules */
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
+       modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
+       modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
 
        return MODEST_WINDOW(obj);
 }
 
        return MODEST_WINDOW(obj);
 }
@@ -1005,11 +1016,13 @@ void modest_msg_view_window_on_row_inserted(
         * msg-view is in it, and thus we do not need any actions but
         * to check the dimming rules.*/
        if(priv->header_model != NULL){
         * msg-view is in it, and thus we do not need any actions but
         * to check the dimming rules.*/
        if(priv->header_model != NULL){
-               gtk_tree_row_reference_free(priv->next_row_reference);
-               priv->next_row_reference = gtk_tree_row_reference_copy(
+               if (priv->row_reference) {
+                       gtk_tree_row_reference_free(priv->next_row_reference);
+                       priv->next_row_reference = gtk_tree_row_reference_copy(
                                priv->row_reference);
                                priv->row_reference);
-               select_next_valid_row (priv->header_model,
-                               &(priv->next_row_reference), FALSE);
+                       select_next_valid_row (priv->header_model,
+                                              &(priv->next_row_reference), FALSE);
+               }
                modest_ui_actions_check_toolbar_dimming_rules (
                                MODEST_WINDOW (window));
                return;
                modest_ui_actions_check_toolbar_dimming_rules (
                                MODEST_WINDOW (window));
                return;
@@ -1023,8 +1036,14 @@ void modest_msg_view_window_on_row_inserted(
        uid = modest_tny_folder_get_header_unique_id(header);
        if(!g_str_equal(priv->msg_uid, uid)){
                g_free(uid);
        uid = modest_tny_folder_get_header_unique_id(header);
        if(!g_str_equal(priv->msg_uid, uid)){
                g_free(uid);
+               g_object_unref(G_OBJECT(header));
+               header = NULL;
                return;
        }
                return;
        }
+       if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN))
+               tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
+       g_object_unref(G_OBJECT(header));
+       header = NULL;
        g_free(uid);
 
        /* Setup row_reference for the actual msg. */
        g_free(uid);
 
        /* Setup row_reference for the actual msg. */
@@ -1092,10 +1111,9 @@ void modest_msg_view_window_update_model_replaced(
         * not care about it's model (msg list). Else if the
         * header-view shows the folder the msg shown by us is in, we
         * shall replace our model reference and make some check. */
         * not care about it's model (msg list). Else if the
         * header-view shows the folder the msg shown by us is in, we
         * shall replace our model reference and make some check. */
-       if(tny_folder_id == NULL ||
-                       !g_str_equal(tny_folder_id, priv->header_folder_id))
+       if(tny_folder_id == NULL || !g_str_equal(tny_folder_id, priv->header_folder_id))
                return;
                return;
-
+       
        /* Model is changed(replaced), so we should forget the old
         * one. Because there might be other references and there
         * might be some change on the model even if we unreferenced
        /* Model is changed(replaced), so we should forget the old
         * one. Because there might be other references and there
         * might be some change on the model even if we unreferenced
@@ -1122,16 +1140,15 @@ void modest_msg_view_window_update_model_replaced(
        priv->rows_reordered_handler = 0;
        g_object_unref(priv->header_model);
        priv->header_model = NULL;
        priv->rows_reordered_handler = 0;
        g_object_unref(priv->header_model);
        priv->header_model = NULL;
-       g_object_unref(priv->row_reference);
+       if (priv->row_reference)
+               g_object_unref(priv->row_reference);
        priv->row_reference = NULL;
        priv->row_reference = NULL;
-       g_object_unref(priv->next_row_reference);
+       if (priv->next_row_reference)
+               g_object_unref(priv->next_row_reference);
        priv->next_row_reference = NULL;
 
        modest_ui_actions_check_toolbar_dimming_rules(MODEST_WINDOW(window));
 
        priv->next_row_reference = NULL;
 
        modest_ui_actions_check_toolbar_dimming_rules(MODEST_WINDOW(window));
 
-       if(tny_folder_id == NULL)
-               return;
-
        g_assert(model != NULL);
 
        /* Also we must connect to the new model for row insertions.
        g_assert(model != NULL);
 
        /* Also we must connect to the new model for row insertions.
@@ -1169,7 +1186,7 @@ modest_msg_view_window_get_header (ModestMsgViewWindow *self)
        /* If the message was not obtained from a treemodel,
         * for instance if it was opened directly by the search UI:
         */
        /* If the message was not obtained from a treemodel,
         * for instance if it was opened directly by the search UI:
         */
-       if (priv->header_model == NULL) {
+       if (priv->header_model == NULL || priv->row_reference == NULL) {
                msg = modest_msg_view_window_get_message (self);
                if (msg) {
                        header = tny_msg_get_header (msg);
                msg = modest_msg_view_window_get_message (self);
                if (msg) {
                        header = tny_msg_get_header (msg);
@@ -1203,15 +1220,12 @@ modest_msg_view_window_get_header (ModestMsgViewWindow *self)
 TnyMsg*
 modest_msg_view_window_get_message (ModestMsgViewWindow *self)
 {
 TnyMsg*
 modest_msg_view_window_get_message (ModestMsgViewWindow *self)
 {
-       ModestMsgView *msg_view;
        ModestMsgViewWindowPrivate *priv;
        ModestMsgViewWindowPrivate *priv;
-
+       
        g_return_val_if_fail (self, NULL);
        g_return_val_if_fail (self, NULL);
-
+       
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
-
-       msg_view = MODEST_MSG_VIEW (priv->msg_view);
-
+       
        return tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
 }
 
        return tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
 }
 
@@ -1248,9 +1262,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");
 
        /* update the toggle buttons status */
        action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage");
-       modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active);
+       modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active);
        action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/ToolsFindInMessageMenu");
        action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/ToolsFindInMessageMenu");
-       modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active);
+       modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active);
        
 }
 
        
 }
 
@@ -1401,49 +1415,70 @@ modest_msg_view_window_zoom_minus (ModestWindow *window)
 }
 
 static gboolean
 }
 
 static gboolean
-modest_msg_view_window_key_release_event (GtkWidget *window,
-                                         GdkEventKey *event,
-                                         gpointer userdata)
+modest_msg_view_window_key_event (GtkWidget *window,
+                                 GdkEventKey *event,
+                                 gpointer userdata)
 {
 {
-       if (event->type == GDK_KEY_RELEASE) {
-               switch (event->keyval) {
-               case GDK_Up:
-                       modest_msg_view_window_scroll_up (MODEST_WINDOW (window));
+       GtkWidget *focus;
+
+       focus = gtk_window_get_focus (GTK_WINDOW (window));
+
+       /* for the find toolbar case */
+       if (focus && GTK_IS_ENTRY (focus)) {
+               if (event->keyval == GDK_BackSpace) {
+                       GdkEvent *copy;
+                       copy = gdk_event_copy ((GdkEvent *) event);
+                       gtk_widget_event (focus, copy);
+                       gdk_event_free (copy);
                        return TRUE;
                        return TRUE;
-                       break;
-               case GDK_Down:
-                       modest_msg_view_window_scroll_down (MODEST_WINDOW (window));
+               } else 
+                       return FALSE;
+       }
+       if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up ||
+           event->keyval == GDK_Down || event->keyval == GDK_KP_Down ||
+           event->keyval == GDK_Page_Up || event->keyval == GDK_KP_Page_Up ||
+           event->keyval == GDK_Page_Down || event->keyval == GDK_KP_Page_Down ||
+           event->keyval == GDK_Home || event->keyval == GDK_KP_Home ||
+           event->keyval == GDK_End || event->keyval == GDK_KP_End) {
+               ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+               gboolean return_value;
+
+               if (event->type == GDK_KEY_RELEASE) {
+                       GtkScrollType scroll_type;
+                       
+                       switch (event->keyval) {
+                       case GDK_Up: 
+                       case GDK_KP_Up:
+                               scroll_type = GTK_SCROLL_STEP_UP; break;
+                       case GDK_Down: 
+                       case GDK_KP_Down:
+                               scroll_type = GTK_SCROLL_STEP_DOWN; break;
+                       case GDK_Page_Up:
+                       case GDK_KP_Page_Up:
+                               scroll_type = GTK_SCROLL_PAGE_UP; break;
+                       case GDK_Page_Down:
+                       case GDK_KP_Page_Down:
+                               scroll_type = GTK_SCROLL_PAGE_DOWN; break;
+                       case GDK_Home:
+                       case GDK_KP_Home:
+                               scroll_type = GTK_SCROLL_START; break;
+                       case GDK_End:
+                       case GDK_KP_End:
+                               scroll_type = GTK_SCROLL_END; break;
+                       default: scroll_type = GTK_SCROLL_NONE;
+                       }
+                       
+                       g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", 
+                                              scroll_type, FALSE, &return_value);
                        return TRUE;
                        return TRUE;
-                       break;
-               default:
+               } else {
                        return FALSE;
                        return FALSE;
-                       break;
-               };
+               }
        } else {
                return FALSE;
        }
 }
 
        } else {
                return FALSE;
        }
 }
 
-static void
-modest_msg_view_window_scroll_up (ModestWindow *window)
-{
-       ModestMsgViewWindowPrivate *priv;
-       gboolean return_value;
-
-       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
-       g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", GTK_SCROLL_STEP_UP, FALSE, &return_value);
-}
-
-static void
-modest_msg_view_window_scroll_down (ModestWindow *window)
-{
-       ModestMsgViewWindowPrivate *priv;
-       gboolean return_value;
-
-       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
-       g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", GTK_SCROLL_STEP_DOWN, FALSE, &return_value);
-}
-
 gboolean
 modest_msg_view_window_last_message_selected (ModestMsgViewWindow *window)
 {
 gboolean
 modest_msg_view_window_last_message_selected (ModestMsgViewWindow *window)
 {
@@ -1456,7 +1491,7 @@ modest_msg_view_window_last_message_selected (ModestMsgViewWindow *window)
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        /*if no model (so no rows at all), then virtually we are the last*/
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        /*if no model (so no rows at all), then virtually we are the last*/
-       if (!priv->header_model)
+       if (!priv->header_model || !priv->row_reference)
                return TRUE;
 
        path = gtk_tree_row_reference_get_path (priv->row_reference);
                return TRUE;
 
        path = gtk_tree_row_reference_get_path (priv->row_reference);
@@ -1472,8 +1507,11 @@ modest_msg_view_window_last_message_selected (ModestMsgViewWindow *window)
                gtk_tree_model_get (priv->header_model, &tmp_iter,
                                TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                &header, -1);
                gtk_tree_model_get (priv->header_model, &tmp_iter,
                                TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                &header, -1);
-               if (!(tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED))
-                       is_last_selected = FALSE;
+               if (header) {
+                       if (msg_is_visible (header, priv->is_outbox))
+                               is_last_selected = FALSE;
+                       g_object_unref(G_OBJECT(header));
+               }
        }
        gtk_tree_path_free (path);
        return is_last_selected;
        }
        gtk_tree_path_free (path);
        return is_last_selected;
@@ -1501,6 +1539,14 @@ modest_msg_view_window_is_search_result (ModestMsgViewWindow *window)
        return priv->is_search_result;
 }
 
        return priv->is_search_result;
 }
 
+static gboolean
+msg_is_visible (TnyHeader *header, gboolean check_outbox)
+{
+       return (!(tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED)) &&
+               ( (!check_outbox) || (modest_tny_all_send_queues_get_msg_status (header) != MODEST_TNY_SEND_QUEUE_FAILED)) ;
+       
+}
+
 gboolean
 modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window)
 {
 gboolean
 modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window)
 {
@@ -1514,7 +1560,7 @@ modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window)
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        /*if no model (so no rows at all), then virtually we are the first*/
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        /*if no model (so no rows at all), then virtually we are the first*/
-       if (!priv->header_model)
+       if (!priv->header_model || !priv->row_reference)
                return TRUE;
 
        path = gtk_tree_row_reference_get_path (priv->row_reference);
                return TRUE;
 
        path = gtk_tree_row_reference_get_path (priv->row_reference);
@@ -1541,8 +1587,11 @@ modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window)
                gtk_tree_model_get (priv->header_model, &tmp_iter,
                                TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                &header, -1);
                gtk_tree_model_get (priv->header_model, &tmp_iter,
                                TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                &header, -1);
-               if (!(tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED))
-                       is_first_selected = FALSE;
+               if (header) {
+                       if (msg_is_visible (header, priv->is_outbox))
+                               is_first_selected = FALSE;
+                       g_object_unref(G_OBJECT(header));
+               }
        }
        gtk_tree_path_free (path);
        return is_first_selected;
        }
        gtk_tree_path_free (path);
        return is_first_selected;
@@ -1567,7 +1616,6 @@ message_reader (ModestMsgViewWindow *window,
                GtkTreeRowReference *row_reference)
 {
        ModestMailOperation *mail_op = NULL;
                GtkTreeRowReference *row_reference)
 {
        ModestMailOperation *mail_op = NULL;
-       ModestMailOperationTypeOperation op_type;
        gboolean already_showing = FALSE;
        ModestWindow *msg_window = NULL;
        ModestWindowMgr *mgr;
        gboolean already_showing = FALSE;
        ModestWindow *msg_window = NULL;
        ModestWindowMgr *mgr;
@@ -1585,11 +1633,7 @@ message_reader (ModestMsgViewWindow *window,
        }
 
        /* Msg download completed */
        }
 
        /* Msg download completed */
-       if (tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED) {
-               op_type = MODEST_MAIL_OPERATION_TYPE_OPEN;
-       } else {
-               op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE;
-
+       if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED)) {
                /* Ask the user if he wants to download the message if
                   we're not online */
                if (!tny_device_is_online (modest_runtime_get_device())) {
                /* Ask the user if he wants to download the message if
                   we're not online */
                if (!tny_device_is_online (modest_runtime_get_device())) {
@@ -1623,8 +1667,9 @@ message_reader (ModestMsgViewWindow *window,
        modest_mail_operation_get_msg (mail_op, header, view_msg_cb, row_reference);
        g_object_unref (mail_op);
 
        modest_mail_operation_get_msg (mail_op, header, view_msg_cb, row_reference);
        g_object_unref (mail_op);
 
-       /* Update toolbar dimming rules */
+       /* Update dimming rules */
        modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
        modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
 
        return TRUE;
 }
 
        return TRUE;
 }
@@ -1642,6 +1687,9 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window)
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
+       if (!priv->row_reference)
+               return FALSE;
+
        /* Update the next row reference if it's not valid. This could
           happen if for example the header which it was pointing to,
           was deleted. The best place to do it is in the row-deleted
        /* Update the next row reference if it's not valid. This could
           happen if for example the header which it was pointing to,
           was deleted. The best place to do it is in the row-deleted
@@ -1682,62 +1730,23 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window)
        return retval;          
 }
 
        return retval;          
 }
 
-gboolean 
-modest_msg_view_window_select_first_message (ModestMsgViewWindow *self)
-{
-       ModestMsgViewWindowPrivate *priv = NULL;
-       TnyHeader *header = NULL;
-       GtkTreeIter iter;
-       GtkTreePath *path = NULL;
-       GtkTreeRowReference *row_reference = NULL;
-
-       g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE);
-       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
-
-       /* Check that the model is not empty */
-       if (!gtk_tree_model_get_iter_first (priv->header_model, &iter))
-               return FALSE;
-
-       /* Get the header */
-       gtk_tree_model_get (priv->header_model, 
-                           &iter, 
-                           TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
-                           &header, -1);
-       g_return_val_if_fail (TNY_IS_HEADER (header), FALSE);
-       if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) {
-               g_object_unref (header);
-               return modest_msg_view_window_select_next_message (self);
-       }
-       
-       path = gtk_tree_model_get_path (priv->header_model, &iter);
-       row_reference = gtk_tree_row_reference_new (priv->header_model, path);
-       gtk_tree_path_free (path);
-
-       /* Read the message & show it */
-       message_reader (self, priv, header, row_reference);
-       
-       /* Free */
-       g_object_unref (header);
-
-       return TRUE;
-}
 gboolean        
 modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window)
 {
        ModestMsgViewWindowPrivate *priv = NULL;
        GtkTreePath *path;
 gboolean        
 modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window)
 {
        ModestMsgViewWindowPrivate *priv = NULL;
        GtkTreePath *path;
-       GtkTreeRowReference *row_reference = NULL;
+       gboolean finished = FALSE;
+       gboolean retval = FALSE;
 
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        /* Return inmediatly if there is no header model */
 
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), FALSE);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        /* Return inmediatly if there is no header model */
-       if (!priv->header_model)
+       if (!priv->header_model || !priv->row_reference)
                return FALSE;
 
        path = gtk_tree_row_reference_get_path (priv->row_reference);
                return FALSE;
 
        path = gtk_tree_row_reference_get_path (priv->row_reference);
-       while (gtk_tree_path_prev (path)) {
+       while (!finished && gtk_tree_path_prev (path)) {
                TnyHeader *header;
                GtkTreeIter iter;
 
                TnyHeader *header;
                GtkTreeIter iter;
 
@@ -1745,41 +1754,43 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window)
                gtk_tree_model_get (priv->header_model, &iter, 
                                    TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                    &header, -1);
                gtk_tree_model_get (priv->header_model, &iter, 
                                    TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                    &header, -1);
-               if (!header)
-                       break;
-               if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) {
-                       g_object_unref (header);
-                       continue;
-               }
-
-               row_reference = gtk_tree_row_reference_new (priv->header_model, path);
-               /* Read the message & show it */
-               if (!message_reader (window, priv, header, row_reference)) {
-                       gtk_tree_row_reference_free (row_reference);
+               finished = TRUE;
+               if (header) {
+                       if (msg_is_visible (header, priv->is_outbox)) {
+                               GtkTreeRowReference *row_reference;
+                               row_reference = gtk_tree_row_reference_new (priv->header_model, path);
+                               /* Read the message & show it */
+                               retval = message_reader (window, priv, header, row_reference);
+                               if (!retval)
+                                       gtk_tree_row_reference_free (row_reference);
+                       } else {
+                               finished = FALSE;
+                       }
                        g_object_unref (header);
                        g_object_unref (header);
-                       break;
                }
                }
-
-               gtk_tree_path_free (path);
-               g_object_unref (header);
-
-               return TRUE;
        }
 
        gtk_tree_path_free (path);
        }
 
        gtk_tree_path_free (path);
-       return FALSE;
+       return retval;
 }
 
 static void
 view_msg_cb (ModestMailOperation *mail_op, 
             TnyHeader *header, 
 }
 
 static void
 view_msg_cb (ModestMailOperation *mail_op, 
             TnyHeader *header, 
+            gboolean canceled,
             TnyMsg *msg, 
             TnyMsg *msg, 
+            GError *error,
             gpointer user_data)
 {
        ModestMsgViewWindow *self = NULL;
        ModestMsgViewWindowPrivate *priv = NULL;
        GtkTreeRowReference *row_reference = NULL;
 
             gpointer user_data)
 {
        ModestMsgViewWindow *self = NULL;
        ModestMsgViewWindowPrivate *priv = NULL;
        GtkTreeRowReference *row_reference = NULL;
 
+       if (canceled) {
+               g_object_unref (self);
+               return;
+       }
+       
        /* If there was any error */
        row_reference = (GtkTreeRowReference *) user_data;
        if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
        /* If there was any error */
        row_reference = (GtkTreeRowReference *) user_data;
        if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
@@ -1793,21 +1804,28 @@ view_msg_cb (ModestMailOperation *mail_op,
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
 
        /* Update the row reference */
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
 
        /* Update the row reference */
-       gtk_tree_row_reference_free (priv->row_reference);
-       priv->row_reference = gtk_tree_row_reference_copy (row_reference);
-       priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
-       select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE);
-       gtk_tree_row_reference_free (row_reference);
+       if (priv->row_reference != NULL) {
+               gtk_tree_row_reference_free (priv->row_reference);
+               priv->row_reference = gtk_tree_row_reference_copy (row_reference);
+               if (priv->next_row_reference != NULL) {
+                       gtk_tree_row_reference_free (priv->next_row_reference);
+               }
+               priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
+               select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE);
+               gtk_tree_row_reference_free (row_reference);
+       }
 
        /* Mark header as read */
        if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN))
                tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
 
        /* Set new message */
 
        /* Mark header as read */
        if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_SEEN))
                tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
 
        /* Set new message */
-       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));
-       modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
+       if (priv->msg_view != NULL && TNY_IS_MSG_VIEW (priv->msg_view)) {
+               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));
+               modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
+       }
 
        /* Set the new message uid of the window  */
        if (priv->msg_uid) {
 
        /* Set the new message uid of the window  */
        if (priv->msg_uid) {
@@ -1854,12 +1872,12 @@ static void
 modest_msg_view_window_update_priority (ModestMsgViewWindow *window)
 {
        ModestMsgViewWindowPrivate *priv;
 modest_msg_view_window_update_priority (ModestMsgViewWindow *window)
 {
        ModestMsgViewWindowPrivate *priv;
+       TnyHeader *header = NULL;
        TnyHeaderFlags flags = 0;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        TnyHeaderFlags flags = 0;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
-       if (priv->header_model) {
-               TnyHeader *header;
+       if (priv->header_model && priv->row_reference) {
                GtkTreeIter iter;
                GtkTreePath *path = NULL;
 
                GtkTreeIter iter;
                GtkTreePath *path = NULL;
 
@@ -1871,14 +1889,72 @@ modest_msg_view_window_update_priority (ModestMsgViewWindow *window)
 
                gtk_tree_model_get (priv->header_model, &iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                    &header, -1);
 
                gtk_tree_model_get (priv->header_model, &iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                    &header, -1);
-               flags = tny_header_get_flags (header);
                gtk_tree_path_free (path);
                gtk_tree_path_free (path);
+       } else {
+               TnyMsg *msg;
+               msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
+               if (msg) {
+                       header = tny_msg_get_header (msg);
+                       g_object_unref (msg);
+               }
+       }
+
+       if (header) {
+               flags = tny_header_get_flags (header);
+               g_object_unref(G_OBJECT(header));
        }
 
        modest_msg_view_set_priority (MODEST_MSG_VIEW(priv->msg_view), flags);
 
 }
 
        }
 
        modest_msg_view_set_priority (MODEST_MSG_VIEW(priv->msg_view), flags);
 
 }
 
+static void
+toolbar_resize (ModestMsgViewWindow *self)
+{
+       ModestMsgViewWindowPrivate *priv = NULL;
+       ModestWindowPrivate *parent_priv = NULL;
+       GtkWidget *widget;
+       gint static_button_size;
+       ModestWindowMgr *mgr;
+
+       g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (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;
+
+       if (parent_priv->toolbar) {
+               /* left size buttons */
+               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
+               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
+               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
+               gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
+               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo");
+               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);
+               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
+               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
+               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
+               gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
+               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FindInMessage");
+               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 gboolean
 modest_msg_view_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
 {
 static gboolean
 modest_msg_view_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
 {
@@ -1899,6 +1975,7 @@ modest_msg_view_window_window_state_event (GtkWidget *widget, GdkEventWindowStat
                if (is_fullscreen != active) {
                        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
                }
                if (is_fullscreen != active) {
                        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
                }
+               toolbar_resize (MODEST_MSG_VIEW_WINDOW (widget));
        }
 
        return FALSE;
        }
 
        return FALSE;
@@ -1906,16 +1983,6 @@ modest_msg_view_window_window_state_event (GtkWidget *widget, GdkEventWindowStat
 }
 
 static void
 }
 
 static void
-set_homogeneous (GtkWidget *widget,
-                gpointer data)
-{
-       if (GTK_IS_TOOL_ITEM (widget)) {
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
-               gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
-       }
-}
-
-static void
 modest_msg_view_window_show_toolbar (ModestWindow *self,
                                     gboolean show_toolbar)
 {
 modest_msg_view_window_show_toolbar (ModestWindow *self,
                                     gboolean show_toolbar)
 {
@@ -1938,18 +2005,11 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
                                                                  "/ToolBar");
                gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
 
                                                                  "/ToolBar");
                gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
 
-               /* Set homogeneous toolbar */
-               gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar), 
-                                      set_homogeneous, NULL);
-
                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");
                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");
-               gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
-               gtk_tool_item_set_homogeneous (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);
+               toolbar_resize (MODEST_MSG_VIEW_WINDOW (self));
 
                /* Add ProgressBar (Transfer toolbar) */ 
                priv->progress_bar = modest_progress_bar_widget_new ();
 
                /* Add ProgressBar (Transfer toolbar) */ 
                priv->progress_bar = modest_progress_bar_widget_new ();
@@ -1971,7 +2031,6 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
                hildon_window_add_toolbar (HILDON_WINDOW (self), 
                                           GTK_TOOLBAR (parent_priv->toolbar));
 
                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");
                /* Set reply button tap and hold menu */        
                reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, 
                                                          "/ToolBar/ToolbarMessageReply");
@@ -1984,10 +2043,13 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
                /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ 
                /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
                gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
                /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ 
                /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
                gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
-               
+
                gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
                gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
-               set_toolbar_mode (MODEST_MSG_VIEW_WINDOW(self), TOOLBAR_MODE_NORMAL);                   
-               
+               if (modest_msg_view_window_transfer_mode_enabled (MODEST_MSG_VIEW_WINDOW (self))) 
+                       set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_TRANSFER);
+               else
+                       set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_NORMAL);
+
        } else {
                gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
                gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
        } else {
                gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
                gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
@@ -2004,7 +2066,7 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
                action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
 
        action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
                action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
 
        action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
-       modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
+       modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
                                                            show_toolbar);
 }
 
                                                            show_toolbar);
 }
 
@@ -2016,7 +2078,7 @@ modest_msg_view_window_clipboard_owner_change (GtkClipboard *clipboard,
        if (!GTK_WIDGET_VISIBLE (window))
                return;
 
        if (!GTK_WIDGET_VISIBLE (window))
                return;
 
-       modest_window_check_dimming_rules_group (MODEST_WINDOW (window), "ModestClipboardDimmingRules");
+       modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
 }
 
 gboolean 
 }
 
 gboolean 
@@ -2088,75 +2150,104 @@ on_account_removed (TnyAccountStore *account_store,
        }
 }
 
        }
 }
 
-static void
-on_queue_changed (ModestMailOperationQueue *queue,
-                 ModestMailOperation *mail_op,
-                 ModestMailOperationQueueNotification type,
-                 ModestMsgViewWindow *self)
+static void 
+on_mail_operation_started (ModestMailOperation *mail_op,
+                          gpointer user_data)
 {
 {
+       ModestMsgViewWindow *self;
+       ModestMailOperationTypeOperation op_type;
        GSList *tmp;
        ModestMsgViewWindowPrivate *priv;
        GSList *tmp;
        ModestMsgViewWindowPrivate *priv;
-       ModestMailOperationTypeOperation op_type;
-       ModestToolBarModes mode;
-       
-       g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
-       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
+       GObject *source = NULL;
 
 
-       /* If this operations was created by another window, do nothing */
-       if (!modest_mail_operation_is_mine (mail_op, G_OBJECT(self))) 
-           return;
-
-       /* Get toolbar mode from operation id*/
+       self = MODEST_MSG_VIEW_WINDOW (user_data);
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
        op_type = modest_mail_operation_get_type_operation (mail_op);
        op_type = modest_mail_operation_get_type_operation (mail_op);
-       switch (op_type) {
-/*     case MODEST_MAIL_OPERATION_TYPE_SEND: */
-       case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
-       case MODEST_MAIL_OPERATION_TYPE_OPEN:
-               mode = TOOLBAR_MODE_TRANSFER;
-               break;
-       default:
-               mode = TOOLBAR_MODE_NORMAL;
-               
-       }
-               
-       /* Add operation observers and change toolbar if neccessary*/
        tmp = priv->progress_widgets;
        tmp = priv->progress_widgets;
-       switch (type) {
-       case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
-               if (mode == TOOLBAR_MODE_TRANSFER) {
-                       /* Enable transfer toolbar mode */
+       source = modest_mail_operation_get_source(mail_op);
+       if (G_OBJECT (self) == source) {
+               if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || op_type == MODEST_MAIL_OPERATION_TYPE_OPEN ) {
                        set_toolbar_transfer_mode(self);
                        while (tmp) {
                        set_toolbar_transfer_mode(self);
                        while (tmp) {
-                               modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
-                                                                     mail_op);
+                               modest_progress_object_add_operation (
+                                               MODEST_PROGRESS_OBJECT (tmp->data),
+                                               mail_op);
                                tmp = g_slist_next (tmp);
                        }
                                tmp = g_slist_next (tmp);
                        }
-                       
                }
                }
-               break;
-       case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
-               if (mode == TOOLBAR_MODE_TRANSFER) {
-                       while (tmp) {
-                               modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
-                                                                mail_op);
-                               tmp = g_slist_next (tmp);
-                               
-                       }
+       }
+       g_object_unref (source);
+}
 
 
-                       /* If no more operations are being observed, NORMAL mode is enabled again */
-                       if (observers_empty (self)) {
-                               set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
-                       }
+static void 
+on_mail_operation_finished (ModestMailOperation *mail_op,
+                           gpointer user_data)
+{
+       ModestMsgViewWindow *self;
+       ModestMailOperationTypeOperation op_type;
+       GSList *tmp;
+       ModestMsgViewWindowPrivate *priv;
+       
+       self = MODEST_MSG_VIEW_WINDOW (user_data);
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+       op_type = modest_mail_operation_get_type_operation (mail_op);
+       tmp = priv->progress_widgets;
+       
+       if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || op_type == MODEST_MAIL_OPERATION_TYPE_OPEN ) {
+               while (tmp) {
+                       modest_progress_object_remove_operation (
+                                       MODEST_PROGRESS_OBJECT (tmp->data),
+                                       mail_op);
+                       tmp = g_slist_next (tmp);
+               }
+
+               /* If no more operations are being observed, NORMAL mode is enabled again */
+               if (observers_empty (self)) {
+                       set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
                }
                }
-               break;
        }
 }
 
        }
 }
 
-GList *
+static void
+on_queue_changed (ModestMailOperationQueue *queue,
+                 ModestMailOperation *mail_op,
+                 ModestMailOperationQueueNotification type,
+                 ModestMsgViewWindow *self)
+{      
+       ModestMsgViewWindowPrivate *priv;
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+
+       /* If this operations was created by another window, do nothing */
+       if (!modest_mail_operation_is_mine (mail_op, G_OBJECT(self))) 
+           return;
+
+       if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
+               priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
+                                                              G_OBJECT (mail_op),
+                                                              "operation-started",
+                                                              G_CALLBACK (on_mail_operation_started),
+                                                              self);
+               priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
+                                                              G_OBJECT (mail_op),
+                                                              "operation-finished",
+                                                              G_CALLBACK (on_mail_operation_finished),
+                                                              self);
+       } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
+               priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
+                                                                 G_OBJECT (mail_op),
+                                                                 "operation-started");
+               priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
+                                                                 G_OBJECT (mail_op),
+                                                                 "operation-finished");
+       }
+}
+
+TnyList *
 modest_msg_view_window_get_attachments (ModestMsgViewWindow *win) 
 {
        ModestMsgViewWindowPrivate *priv;
 modest_msg_view_window_get_attachments (ModestMsgViewWindow *win) 
 {
        ModestMsgViewWindowPrivate *priv;
-       GList *selected_attachments = NULL;
+       TnyList *selected_attachments = NULL;
        
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), NULL);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (win);
        
        g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), NULL);
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (win);
@@ -2173,7 +2264,7 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart
        const gchar *msg_uid;
        gchar *attachment_uid = NULL;
        gint attachment_index = 0;
        const gchar *msg_uid;
        gchar *attachment_uid = NULL;
        gint attachment_index = 0;
-       GList *attachments;
+       TnyList *attachments;
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
        g_return_if_fail (TNY_IS_MIME_PART (mime_part) || (mime_part == NULL));
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
        g_return_if_fail (TNY_IS_MIME_PART (mime_part) || (mime_part == NULL));
@@ -2181,8 +2272,8 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart
 
        msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (window));
        attachments = modest_msg_view_get_attachments (MODEST_MSG_VIEW (priv->msg_view));
 
        msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (window));
        attachments = modest_msg_view_get_attachments (MODEST_MSG_VIEW (priv->msg_view));
-       attachment_index = g_list_index (attachments, mime_part);
-       g_list_free (attachments);
+       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);
        
        if (msg_uid && attachment_index >= 0) {
                attachment_uid = g_strdup_printf ("%s/%d", msg_uid, attachment_index);
@@ -2190,18 +2281,19 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart
 
        if (mime_part == NULL) {
                gboolean error = FALSE;
 
        if (mime_part == NULL) {
                gboolean error = FALSE;
-               GList *selected_attachments = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
-               if (selected_attachments == NULL) {
+               TnyList *selected_attachments = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
+               if (selected_attachments == NULL || tny_list_get_length (selected_attachments) == 0) {
                        error = TRUE;
                        error = TRUE;
-               } else if (g_list_length (selected_attachments) > 1) {
+               } else if (tny_list_get_length (selected_attachments) > 1) {
                        hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
                        error = TRUE;
                } else {
                        hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
                        error = TRUE;
                } else {
-                       mime_part = (TnyMimePart *) selected_attachments->data;
-                       g_object_ref (mime_part);
+                       TnyIterator *iter;
+                       iter = tny_list_create_iterator (selected_attachments);
+                       mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
+                       g_object_unref (iter);
                }
                }
-               g_list_foreach (selected_attachments, (GFunc) g_object_unref, NULL);
-               g_list_free (selected_attachments);
+               g_object_unref (selected_attachments);
 
                if (error)
                        return;
 
                if (error)
                        return;
@@ -2217,20 +2309,48 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart
        if (!TNY_IS_MSG (mime_part)) {
                gchar *filepath = NULL;
                const gchar *att_filename = tny_mime_part_get_filename (mime_part);
        if (!TNY_IS_MSG (mime_part)) {
                gchar *filepath = NULL;
                const gchar *att_filename = tny_mime_part_get_filename (mime_part);
+               const gchar *content_type;
+               gboolean show_error_banner = FALSE;
+               GError *err;
                TnyFsStream *temp_stream = NULL;
                TnyFsStream *temp_stream = NULL;
-               temp_stream = modest_maemo_utils_create_temp_stream (att_filename, attachment_uid, &filepath);
+               temp_stream = modest_utils_create_temp_stream (att_filename, attachment_uid,
+                                                              &filepath);
                
                
-               if (temp_stream) {
-                       const gchar *content_type;
+               if (temp_stream != NULL) {
                        content_type = tny_mime_part_get_content_type (mime_part);
                        content_type = tny_mime_part_get_content_type (mime_part);
-                       tny_mime_part_decode_to_stream (mime_part, TNY_STREAM (temp_stream));
-                       
-                       modest_platform_activate_file (filepath, content_type);
+                       if (tny_mime_part_decode_to_stream (mime_part, TNY_STREAM (temp_stream), &err) >= 0) {
+                               /* make the file read-only */
+                               if (g_chmod(filepath, 0444) != 0)
+                                       g_warning ("%s: failed to set file '%s' to read-only: %s",
+                                                       __FUNCTION__, filepath, strerror(errno));
+
+                               modest_platform_activate_file (filepath, content_type);
+                       } else {
+                               /* error while saving attachment, maybe cerm_device_memory_full */
+                               show_error_banner = TRUE;
+                               if (err != NULL) {
+                                       g_warning ("%s: tny_mime_part_decode_to_stream failed (%s)", __FUNCTION__, err->message);
+                                       g_error_free (err);
+                               }
+                       }
                        g_object_unref (temp_stream);
                        g_free (filepath);
                        /* NOTE: files in the temporary area will be automatically
                         * cleaned after some time if they are no longer in use */
                        g_object_unref (temp_stream);
                        g_free (filepath);
                        /* NOTE: files in the temporary area will be automatically
                         * cleaned after some time if they are no longer in use */
+               } else {
+                       if (filepath != NULL) {
+                               /* the file may already exist but it isn't writable,
+                                * let's try to open it anyway */
+                               content_type = tny_mime_part_get_content_type (mime_part);
+                               modest_platform_activate_file (filepath, content_type);
+                               g_free (filepath);
+                       } else {
+                               g_warning ("%s: modest_utils_create_temp_stream failed", __FUNCTION__);
+                               show_error_banner = TRUE;
+                       }
                }
                }
+               if (show_error_banner)
+                       modest_platform_information_banner (NULL, NULL, _("mail_ib_file_operation_failed"));
        } else {
                /* message attachment */
                TnyHeader *header = NULL;
        } else {
                /* message attachment */
                TnyHeader *header = NULL;
@@ -2259,7 +2379,6 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart
                        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_set_zoom (MODEST_WINDOW (msg_win), 
                                                modest_window_get_zoom (MODEST_WINDOW (window)));
                        modest_window_mgr_register_window (mgr, msg_win);
-                       gtk_window_set_transient_for (GTK_WINDOW (msg_win), GTK_WINDOW (window));
                        gtk_widget_show_all (GTK_WIDGET (msg_win));
                }
        }
                        gtk_widget_show_all (GTK_WIDGET (msg_win));
                }
        }
@@ -2336,16 +2455,19 @@ save_mime_part_to_file (SaveMimePartInfo *info)
        GnomeVFSHandle *handle;
        TnyStream *stream;
        SaveMimePartPair *pair = (SaveMimePartPair *) info->pairs->data;
        GnomeVFSHandle *handle;
        TnyStream *stream;
        SaveMimePartPair *pair = (SaveMimePartPair *) info->pairs->data;
+       gboolean decode_result = TRUE;
 
 
-       result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0777);
+       result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0644);
        if (result == GNOME_VFS_OK) {
                stream = tny_vfs_stream_new (handle);
        if (result == GNOME_VFS_OK) {
                stream = tny_vfs_stream_new (handle);
-               tny_mime_part_decode_to_stream (pair->part, stream);
+               if (tny_mime_part_decode_to_stream (pair->part, stream, NULL) < 0) {
+                       decode_result = FALSE;
+               }
                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);
                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);
-               info->result = TRUE;
+               info->result = decode_result;
        } else {
                save_mime_part_info_free (info, FALSE);
                info->result = FALSE;
        } else {
                save_mime_part_info_free (info, FALSE);
                info->result = FALSE;
@@ -2365,8 +2487,8 @@ save_mime_parts_to_file_with_checks (SaveMimePartInfo *info)
 
         for (iter = files; (iter != NULL) && (replaced_files < 2); iter = g_list_next(iter)) {
                 SaveMimePartPair *pair = iter->data;
 
         for (iter = files; (iter != NULL) && (replaced_files < 2); iter = g_list_next(iter)) {
                 SaveMimePartPair *pair = iter->data;
-                if (modest_maemo_utils_file_exists (pair->filename)) {
-                        replaced_files++;
+                if (modest_utils_file_exists (pair->filename)) {
+                       replaced_files++;
                 }
         }
        if (replaced_files) {
                 }
         }
        if (replaced_files) {
@@ -2394,9 +2516,8 @@ save_mime_parts_to_file_with_checks (SaveMimePartInfo *info)
 
 
 void
 
 
 void
-modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, GList *mime_parts)
+modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *mime_parts)
 {
 {
-       gboolean clean_list = FALSE;
        ModestMsgViewWindowPrivate *priv;
        GList *files_to_save = NULL;
        GtkWidget *save_dialog = NULL;
        ModestMsgViewWindowPrivate *priv;
        GList *files_to_save = NULL;
        GtkWidget *save_dialog = NULL;
@@ -2410,24 +2531,29 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, GList *mim
 
        if (mime_parts == NULL) {
                mime_parts = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
 
        if (mime_parts == NULL) {
                mime_parts = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
-               if (mime_parts == NULL)
+               if (mime_parts == NULL || tny_list_get_length (mime_parts) == 0)
                        return;
                        return;
-               clean_list = TRUE;
+       } else {
+               g_object_ref (mime_parts);
        }
 
        /* prepare dialog */
        }
 
        /* prepare dialog */
-       if (mime_parts->next == NULL) {
+       if (tny_list_get_length (mime_parts) == 1) {
+               TnyIterator *iter;
                /* only one attachment selected */
                /* only one attachment selected */
-               TnyMimePart *mime_part = (TnyMimePart *) mime_parts->data;
+               iter = tny_list_create_iterator (mime_parts);
+               TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
+               g_object_unref (iter);
                if (!TNY_IS_MSG (mime_part) && tny_mime_part_is_attachment (mime_part)) {
                        filename = tny_mime_part_get_filename (mime_part);
                } else {
                        g_warning ("Tried to save a non-file attachment");
                        canceled = TRUE;
                }
                if (!TNY_IS_MSG (mime_part) && tny_mime_part_is_attachment (mime_part)) {
                        filename = tny_mime_part_get_filename (mime_part);
                } else {
                        g_warning ("Tried to save a non-file attachment");
                        canceled = TRUE;
                }
+               g_object_unref (mime_part);
        } else {
                save_multiple_str = g_strdup_printf (_FM("sfil_va_number_of_objects_attachments"), 
        } else {
                save_multiple_str = g_strdup_printf (_FM("sfil_va_number_of_objects_attachments"), 
-                                                    g_list_length (mime_parts));
+                                                    tny_list_get_length (mime_parts));
        }
        
        save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), 
        }
        
        save_dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), 
@@ -2452,44 +2578,46 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, GList *mim
        if (gtk_dialog_run (GTK_DIALOG (save_dialog)) == GTK_RESPONSE_OK) {
                gchar *chooser_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
 
        if (gtk_dialog_run (GTK_DIALOG (save_dialog)) == GTK_RESPONSE_OK) {
                gchar *chooser_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog));
 
-               if (!modest_maemo_utils_folder_writable (chooser_uri)) {
+               if (!modest_utils_folder_writable (chooser_uri)) {
                        hildon_banner_show_information 
                                (NULL, NULL, dgettext("hildon-fm", "sfil_ib_readonly_location"));
                } else {
                        hildon_banner_show_information 
                                (NULL, NULL, dgettext("hildon-fm", "sfil_ib_readonly_location"));
                } else {
-                       GList *node = NULL;
+                       TnyIterator *iter;
 
 
-                       for (node = mime_parts; node != NULL; node = g_list_next (node)) {
-                               TnyMimePart *mime_part = (TnyMimePart *) node->data;
-                               
+                       iter = tny_list_create_iterator (mime_parts);
+                       while (!tny_iterator_is_done (iter)) {
+                               TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
+
+                               tny_iterator_next (iter);
                                if (tny_mime_part_is_attachment (mime_part)) {
                                        SaveMimePartPair *pair;
 
                                if (tny_mime_part_is_attachment (mime_part)) {
                                        SaveMimePartPair *pair;
 
-                                       if ((mime_parts->next != NULL) &&
-                                           (tny_mime_part_get_filename (mime_part) == NULL))
+                                       if ((!tny_iterator_is_done (iter)) &&
+                                           (tny_mime_part_get_filename (mime_part) == NULL)) {
+                                               g_object_unref (mime_part);
                                                continue;
                                                continue;
+                                       }
                                        
                                        pair = g_slice_new0 (SaveMimePartPair);
                                        
                                        pair = g_slice_new0 (SaveMimePartPair);
-                                       if (mime_parts->next == NULL) {
+                                       if (tny_iterator_is_done (iter)) {
                                                pair->filename = g_strdup (chooser_uri);
                                        } else {
                                                pair->filename = 
                                                        g_build_filename (chooser_uri,
                                                                          tny_mime_part_get_filename (mime_part), NULL);
                                        }
                                                pair->filename = g_strdup (chooser_uri);
                                        } else {
                                                pair->filename = 
                                                        g_build_filename (chooser_uri,
                                                                          tny_mime_part_get_filename (mime_part), NULL);
                                        }
-                                       pair->part = g_object_ref (mime_part);
+                                       pair->part = mime_part;
                                        files_to_save = g_list_prepend (files_to_save, pair);
                                }
                        }
                                        files_to_save = g_list_prepend (files_to_save, pair);
                                }
                        }
+                       g_object_unref (iter);
                }
                g_free (chooser_uri);
        }
 
        gtk_widget_destroy (save_dialog);
 
                }
                g_free (chooser_uri);
        }
 
        gtk_widget_destroy (save_dialog);
 
-       if (clean_list) {
-               g_list_foreach (mime_parts, (GFunc) g_object_unref, NULL);
-               g_list_free (mime_parts);
-       }
+       g_object_unref (mime_parts);
 
        if (files_to_save != NULL) {
                SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
 
        if (files_to_save != NULL) {
                SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
@@ -2505,6 +2633,9 @@ show_remove_attachment_information (gpointer userdata)
        ModestMsgViewWindow *window = (ModestMsgViewWindow *) userdata;
        ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
        ModestMsgViewWindow *window = (ModestMsgViewWindow *) userdata;
        ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
+       /* We're outside the main lock */
+       gdk_threads_enter ();
+
        if (priv->remove_attachment_banner != NULL) {
                gtk_widget_destroy (priv->remove_attachment_banner);
                g_object_unref (priv->remove_attachment_banner);
        if (priv->remove_attachment_banner != NULL) {
                gtk_widget_destroy (priv->remove_attachment_banner);
                g_object_unref (priv->remove_attachment_banner);
@@ -2513,6 +2644,8 @@ show_remove_attachment_information (gpointer userdata)
        priv->remove_attachment_banner = g_object_ref (
                hildon_banner_show_animation (NULL, NULL, _("mcen_ib_removing_attachment")));
 
        priv->remove_attachment_banner = g_object_ref (
                hildon_banner_show_animation (NULL, NULL, _("mcen_ib_removing_attachment")));
 
+       gdk_threads_leave ();
+
        return FALSE;
 }
 
        return FALSE;
 }
 
@@ -2520,11 +2653,12 @@ void
 modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean get_all)
 {
        ModestMsgViewWindowPrivate *priv;
 modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean get_all)
 {
        ModestMsgViewWindowPrivate *priv;
-       GList *mime_parts = NULL, *node;
+       TnyList *mime_parts = NULL;
        gchar *confirmation_message;
        gint response;
        gint n_attachments;
        TnyMsg *msg;
        gchar *confirmation_message;
        gint response;
        gint n_attachments;
        TnyMsg *msg;
+       TnyIterator *iter;
 /*     TnyFolder *folder; */
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
 /*     TnyFolder *folder; */
 
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
@@ -2536,37 +2670,42 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
                mime_parts = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
                
        /* Remove already purged messages from mime parts list */
                mime_parts = modest_msg_view_get_selected_attachments (MODEST_MSG_VIEW (priv->msg_view));
                
        /* Remove already purged messages from mime parts list */
-       node = mime_parts;
-       while (node != NULL) {
-               TnyMimePart *part = TNY_MIME_PART (node->data);
+       iter = tny_list_create_iterator (mime_parts);
+       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)) {
-                       GList *deleted_node = node;
-                       node = g_list_next (node);
-                       g_object_unref (part);
-                       mime_parts = g_list_delete_link (mime_parts, deleted_node);
-               } else {
-                       node = g_list_next (node);
+                       tny_list_remove (mime_parts, (GObject *) part);
                }
                }
+               g_object_unref (part);
        }
        }
+       g_object_unref (iter);
 
 
-       if (mime_parts == NULL)
+       if (tny_list_get_length (mime_parts) == 0) {
+               g_object_unref (mime_parts);
                return;
                return;
+       }
 
 
-       n_attachments = g_list_length (mime_parts);
+       n_attachments = tny_list_get_length (mime_parts);
        if (n_attachments == 1) {
                const gchar *filename;
        if (n_attachments == 1) {
                const gchar *filename;
+               TnyMimePart *part;
 
 
-               if (TNY_IS_MSG (mime_parts->data)) {
+               iter = tny_list_create_iterator (mime_parts);
+               part = (TnyMimePart *) tny_iterator_get_current (iter);
+               g_object_unref (iter);
+               if (TNY_IS_MSG (part)) {
                        TnyHeader *header;
                        TnyHeader *header;
-                       header = tny_msg_get_header (TNY_MSG (mime_parts->data));
+                       header = tny_msg_get_header (TNY_MSG (part));
                        filename = tny_header_get_subject (header);
                        g_object_unref (header);
                        if (filename == NULL)
                                filename = _("mail_va_no_subject");
                } else {
                        filename = tny_header_get_subject (header);
                        g_object_unref (header);
                        if (filename == NULL)
                                filename = _("mail_va_no_subject");
                } else {
-                       filename = tny_mime_part_get_filename (TNY_MIME_PART (mime_parts->data));
+                       filename = tny_mime_part_get_filename (TNY_MIME_PART (part));
                }
                confirmation_message = g_strdup_printf (_("mcen_nc_purge_file_text"), filename);
                }
                confirmation_message = g_strdup_printf (_("mcen_nc_purge_file_text"), filename);
+               g_object_unref (part);
        } else {
                confirmation_message = g_strdup_printf (ngettext("mcen_nc_purge_file_text", 
                                                                 "mcen_nc_purge_files_text", 
        } else {
                confirmation_message = g_strdup_printf (ngettext("mcen_nc_purge_file_text", 
                                                                 "mcen_nc_purge_files_text", 
@@ -2576,8 +2715,10 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
                                                            confirmation_message);
        g_free (confirmation_message);
 
                                                            confirmation_message);
        g_free (confirmation_message);
 
-       if (response != GTK_RESPONSE_OK)
+       if (response != GTK_RESPONSE_OK) {
+               g_object_unref (mime_parts);
                return;
                return;
+       }
 
        priv->purge_timeout = g_timeout_add (2000, show_remove_attachment_information, window);
 /*     folder = tny_msg_get_folder (msg); */
 
        priv->purge_timeout = g_timeout_add (2000, show_remove_attachment_information, window);
 /*     folder = tny_msg_get_folder (msg); */
@@ -2585,18 +2726,25 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
 /*     tny_folder_refresh (folder, NULL); */
 /*     g_object_unref (folder); */
        
 /*     tny_folder_refresh (folder, NULL); */
 /*     g_object_unref (folder); */
        
-       for (node = mime_parts; node != NULL; node = g_list_next (node)) {
-               tny_mime_part_set_purged (TNY_MIME_PART (node->data));
+       iter = tny_list_create_iterator (mime_parts);
+       while (!tny_iterator_is_done (iter)) {
+               TnyMimePart *part;
+
+               part = (TnyMimePart *) tny_iterator_get_current (iter);
+               tny_mime_part_set_purged (TNY_MIME_PART (part));
 /*             modest_msg_view_remove_attachment (MODEST_MSG_VIEW (priv->msg_view), node->data); */
 /*             modest_msg_view_remove_attachment (MODEST_MSG_VIEW (priv->msg_view), node->data); */
+               g_object_unref (part);
+               tny_iterator_next (iter);
        }
        }
+       g_object_unref (iter);
 
        msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
        tny_msg_view_clear (TNY_MSG_VIEW (priv->msg_view));
        tny_msg_rewrite_cache (msg);
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
 
        msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
        tny_msg_view_clear (TNY_MSG_VIEW (priv->msg_view));
        tny_msg_rewrite_cache (msg);
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
+       g_object_unref (msg);
 
 
-       g_list_foreach (mime_parts, (GFunc) g_object_unref, NULL);
-       g_list_free (mime_parts);
+       g_object_unref (mime_parts);
 
        if (priv->purge_timeout > 0) {
                g_source_remove (priv->purge_timeout);
 
        if (priv->purge_timeout > 0) {
                g_source_remove (priv->purge_timeout);
@@ -2620,8 +2768,9 @@ update_window_title (ModestMsgViewWindow *window)
        TnyMsg *msg = NULL;
        TnyHeader *header = NULL;
        const gchar *subject = NULL;
        TnyMsg *msg = NULL;
        TnyHeader *header = NULL;
        const gchar *subject = NULL;
-
+       
        msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
        msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
+
        if (msg != NULL) {
                header = tny_msg_get_header (msg);
                subject = tny_header_get_subject (header);
        if (msg != NULL) {
                header = tny_msg_get_header (msg);
                subject = tny_header_get_subject (header);
@@ -2634,16 +2783,11 @@ update_window_title (ModestMsgViewWindow *window)
        gtk_window_set_title (GTK_WINDOW (window), subject);
 }
 
        gtk_window_set_title (GTK_WINDOW (window), subject);
 }
 
-static void on_move_focus (ModestMsgViewWindow *window,
+
+static void on_move_focus (GtkWidget *widget,
                           GtkDirectionType direction,
                           gpointer userdata)
 {
                           GtkDirectionType direction,
                           gpointer userdata)
 {
-       GtkWidget *current_focus = NULL;
-
-       current_focus = gtk_window_get_focus (GTK_WINDOW (window));
-       if ((current_focus != NULL) &&
-           MODEST_IS_ATTACHMENTS_VIEW (current_focus)) {
-               g_signal_stop_emission_by_name (G_OBJECT (window), "move-focus");
-       }
+       g_signal_stop_emission_by_name (G_OBJECT (widget), "move-focus");
 }
 
 }