* src/maemo/modest-msg-view-window.c
[modest] / src / maemo / modest-msg-view-window.c
index 4877456..4cef99b 100644 (file)
@@ -39,7 +39,6 @@
 #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>
@@ -48,7 +47,7 @@
 #include <modest-tny-folder.h>
 #include <modest-text-utils.h>
 #include <modest-account-mgr-helpers.h>
-#include "modest-progress-bar-widget.h"
+#include "modest-progress-bar.h"
 #include "modest-defs.h"
 #include "modest-hildon-includes.h"
 #include "modest-ui-dimming-manager.h"
 #include <modest-tny-account.h>
 #include <modest-mime-part-view.h>
 #include <modest-isearch-view.h>
+#include <modest-tny-mime-part.h>
 #include <math.h>
 #include <errno.h>
 #include <glib/gstdio.h>
+#include <modest-debug.h>
 
 #define DEFAULT_FOLDER "MyDocs/.documents"
 
@@ -473,8 +474,8 @@ set_toolbar_mode (ModestMsgViewWindow *self,
        /* Sets current toolbar mode */
        priv->current_toolbar_mode = mode;
 
-       /* Update window dimming state */
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (self));
+       /* Update toolbar dimming state */
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
 
        switch (mode) {
        case TOOLBAR_MODE_NORMAL:               
@@ -539,10 +540,8 @@ init_window (ModestMsgViewWindow *obj)
 {
        GtkWidget *main_vbox;
        ModestMsgViewWindowPrivate *priv;
-       ModestWindowPrivate *parent_priv;
 
        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);
@@ -691,7 +690,8 @@ select_next_valid_row (GtkTreeModel *model,
                       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);
@@ -717,6 +717,8 @@ select_next_valid_row (GtkTreeModel *model,
 
        /* Free */
        gtk_tree_path_free (path);
+       if (next)
+               gtk_tree_path_free (next);
 
        return retval;
 }
@@ -724,13 +726,14 @@ select_next_valid_row (GtkTreeModel *model,
 /* TODO: This should be in _init(), with the parameters as properties. */
 static void
 modest_msg_view_window_construct (ModestMsgViewWindow *self, 
-                           const gchar *modest_account_name,
-                           const gchar *msg_uid)
+                                 const gchar *modest_account_name,
+                                 const gchar *msg_uid)
 {
        GObject *obj = NULL;
        ModestMsgViewWindowPrivate *priv = NULL;
        ModestWindowPrivate *parent_priv = NULL;
-       ModestDimmingRulesGroup *window_rules_group = NULL;
+       ModestDimmingRulesGroup *menu_rules_group = NULL;
+       ModestDimmingRulesGroup *toolbar_rules_group = NULL;
        ModestDimmingRulesGroup *clipboard_rules_group = NULL;
 
        obj = G_OBJECT (self);
@@ -745,27 +748,30 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        gtk_widget_show (parent_priv->menubar);
        parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
 
-       window_rules_group = modest_dimming_rules_group_new ("ModestWindowDimmingRules", TRUE);
-       clipboard_rules_group = modest_dimming_rules_group_new ("ModestClipboardDimmingRules", FALSE);
+       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 (window_rules_group, 
-                                             modest_msg_view_toolbar_dimming_entries,
-                                             G_N_ELEMENTS (modest_msg_view_toolbar_dimming_entries),
-                                             MODEST_WINDOW (self));
-       modest_dimming_rules_group_add_rules (window_rules_group, 
+       modest_dimming_rules_group_add_rules (menu_rules_group, 
                                              modest_msg_view_menu_dimming_entries,
                                              G_N_ELEMENTS (modest_msg_view_menu_dimming_entries),
                                              MODEST_WINDOW (self));
+       modest_dimming_rules_group_add_rules (toolbar_rules_group, 
+                                             modest_msg_view_toolbar_dimming_entries,
+                                             G_N_ELEMENTS (modest_msg_view_toolbar_dimming_entries),
+                                             MODEST_WINDOW (self));
        modest_dimming_rules_group_add_rules (clipboard_rules_group, 
                                              modest_msg_view_clipboard_dimming_entries,
                                              G_N_ELEMENTS (modest_msg_view_clipboard_dimming_entries),
                                              MODEST_WINDOW (self));
 
        /* Insert dimming rules group for this window */
-       modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, window_rules_group);
+       modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
+       modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
        modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
-       g_object_unref (window_rules_group);
+       g_object_unref (menu_rules_group);
+       g_object_unref (toolbar_rules_group);
        g_object_unref (clipboard_rules_group);
 
        restore_settings (MODEST_MSG_VIEW_WINDOW(obj));
@@ -820,7 +826,6 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
        /* 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));
 
 
@@ -841,6 +846,10 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        ModestWindow *main_window = NULL;
        ModestWindowMgr *mgr = NULL;
 
+       MODEST_DEBUG_BLOCK (
+              modest_tny_mime_part_to_string (TNY_MIME_PART (msg), 0);
+       );
+
        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);
@@ -861,11 +870,16 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        
        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_object_unref(header_folder);
+               /* This could happen if the header folder was
+                  unseleted before opening this msg window (for
+                  example if the user selects an account in the
+                  folder view of the main window */
+               if (header_folder) {
+                       priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) == TNY_FOLDER_TYPE_OUTBOX);
+                       priv->header_folder_id = tny_folder_get_id(header_folder);
+                       g_assert(priv->header_folder_id != NULL);
+                       g_object_unref(header_folder);
+               }
        }
 
        priv->header_model = g_object_ref(model);
@@ -905,9 +919,10 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
        gtk_widget_show_all (GTK_WIDGET (window));
        modest_msg_view_window_update_priority (window);
 
-       /* Check window dimming rules */
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (window));
-       modest_window_check_dimming_rules_group (MODEST_WINDOW (window), "ModestClipboardDimmingRules");
+       /* Check dimming rules */
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
+       modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
 
        return MODEST_WINDOW(window);
 }
@@ -937,6 +952,8 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg,
        update_window_title (window);
        modest_msg_view_window_update_priority (window);
 
+       gtk_widget_show_all (GTK_WIDGET (window));
+
 
        return MODEST_WINDOW(window);
 }
@@ -960,9 +977,12 @@ modest_msg_view_window_new_for_attachment (TnyMsg *msg,
        tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
        update_window_title (MODEST_MSG_VIEW_WINDOW (obj));
 
-       /* Check window dimming rules */
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (obj));
-       modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), "ModestClipboardDimmingRules");
+       gtk_widget_show_all (GTK_WIDGET (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);
 }
@@ -972,14 +992,14 @@ void modest_msg_view_window_on_row_changed(
                GtkTreePath *arg1,
                GtkTreeIter *arg2,
                ModestMsgViewWindow *window){
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
 }
 
 void modest_msg_view_window_on_row_deleted(
                GtkTreeModel *header_model,
                GtkTreePath *arg1,
                ModestMsgViewWindow *window){
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
 }
 
 /* On insertions we check if the folder still has the message we are
@@ -1017,7 +1037,7 @@ void modest_msg_view_window_on_row_inserted(
                        select_next_valid_row (priv->header_model,
                                               &(priv->next_row_reference), FALSE);
                }
-               modest_ui_actions_check_window_dimming_rules (
+               modest_ui_actions_check_toolbar_dimming_rules (
                                MODEST_WINDOW (window));
                return;
        }
@@ -1067,7 +1087,7 @@ void modest_msg_view_window_on_row_inserted(
        select_next_valid_row (priv->header_model,
                        &(priv->next_row_reference), FALSE);
 
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
 }
 
 void modest_msg_view_window_on_row_reordered(
@@ -1076,7 +1096,7 @@ void modest_msg_view_window_on_row_reordered(
                GtkTreeIter *arg2,
                gpointer arg3,
                ModestMsgViewWindow *window){
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
 }
 
 /* The modest_msg_view_window_update_model_replaced implements update
@@ -1088,10 +1108,10 @@ void modest_msg_view_window_on_row_reordered(
  * the new model. In this case the view will be detached from it's
  * header folder. From this point the next/prev buttons are dimmed.
  */
-void modest_msg_view_window_update_model_replaced(
-               ModestHeaderViewObserver *observer,
-               GtkTreeModel *model,
-               const gchar *tny_folder_id){
+void 
+modest_msg_view_window_update_model_replaced(ModestHeaderViewObserver *observer,
+                                            GtkTreeModel *model,
+                                            const gchar *tny_folder_id){
        ModestMsgViewWindowPrivate *priv = NULL; 
        ModestMsgViewWindow *window = NULL;
 
@@ -1105,7 +1125,8 @@ 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. */
-       if(tny_folder_id == NULL || !g_str_equal(tny_folder_id, priv->header_folder_id))
+       if(tny_folder_id == NULL || 
+          (priv->header_folder_id && !g_str_equal(tny_folder_id, priv->header_folder_id)))
                return;
        
        /* Model is changed(replaced), so we should forget the old
@@ -1135,13 +1156,13 @@ void modest_msg_view_window_update_model_replaced(
        g_object_unref(priv->header_model);
        priv->header_model = NULL;
        if (priv->row_reference)
-               g_object_unref(priv->row_reference);
+               gtk_tree_row_reference_free (priv->row_reference);
        priv->row_reference = NULL;
        if (priv->next_row_reference)
-               g_object_unref(priv->next_row_reference);
+               gtk_tree_row_reference_free (priv->next_row_reference);
        priv->next_row_reference = NULL;
 
-       modest_ui_actions_check_window_dimming_rules(MODEST_WINDOW(window));
+       modest_ui_actions_check_toolbar_dimming_rules(MODEST_WINDOW(window));
 
        g_assert(model != NULL);
 
@@ -1180,7 +1201,9 @@ 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 (priv->header_model == NULL || priv->row_reference == NULL) {
+       if (priv->header_model == NULL || 
+           priv->row_reference == NULL ||
+           !gtk_tree_row_reference_valid (priv->row_reference)) {
                msg = modest_msg_view_window_get_message (self);
                if (msg) {
                        header = tny_msg_get_header (msg);
@@ -1190,12 +1213,6 @@ modest_msg_view_window_get_header (ModestMsgViewWindow *self)
        }
 
        /* Get iter of the currently selected message in the header view: */
-       /* TODO: Why not just give this window a ref of the TnyHeader or TnyMessage,
-        * instead of sometimes retrieving it from the header view?
-        * Then we wouldn't be dependent on the message actually still being selected 
-        * in the header view. murrayc. */
-       if (!gtk_tree_row_reference_valid (priv->row_reference))
-               return NULL;
        path = gtk_tree_row_reference_get_path (priv->row_reference);
        g_return_val_if_fail (path != NULL, NULL);
        gtk_tree_model_get_iter (priv->header_model, 
@@ -1591,13 +1608,49 @@ modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window)
        return is_first_selected;
 }
 
+typedef struct {
+       TnyHeader *header;
+       GtkTreeRowReference *row_reference;
+} MsgReaderInfo;
+
+static void
+message_reader_performer (gboolean canceled, 
+                         GError *err,
+                         GtkWindow *parent_window, 
+                         TnyAccount *account, 
+                         gpointer user_data)
+{
+       ModestMailOperation *mail_op = NULL;
+       MsgReaderInfo *info;
+
+       info = (MsgReaderInfo *) user_data;
+       if (canceled || err) {
+               goto frees;
+       }
+
+       /* New mail operation */
+       mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
+                                                                modest_ui_actions_disk_operations_error_handler, 
+                                                                NULL, NULL);
+                               
+       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
+       modest_mail_operation_get_msg (mail_op, info->header, view_msg_cb, info->row_reference);
+       g_object_unref (mail_op);
+
+ frees:
+       /* Frees. The row_reference will be freed by the view_msg_cb callback */
+       g_object_unref (info->header);
+       g_slice_free (MsgReaderInfo, info);
+}
+
+
 /**
  * Reads the message whose summary item is @header. It takes care of
  * several things, among others:
  *
  * If the message was not previously downloaded then ask the user
  * before downloading. If there is no connection launch the connection
- * dialog. Update window dimming rules.
+ * dialog. Update toolbar dimming rules.
  *
  * Returns: TRUE if the mail operation was started, otherwise if the
  * user do not want to download the message, or if the user do not
@@ -1609,10 +1662,12 @@ message_reader (ModestMsgViewWindow *window,
                TnyHeader *header,
                GtkTreeRowReference *row_reference)
 {
-       ModestMailOperation *mail_op = NULL;
        gboolean already_showing = FALSE;
        ModestWindow *msg_window = NULL;
        ModestWindowMgr *mgr;
+       TnyAccount *account;
+       TnyFolder *folder;
+       MsgReaderInfo *info;
 
        g_return_val_if_fail (row_reference != NULL, FALSE);
 
@@ -1631,7 +1686,6 @@ message_reader (ModestMsgViewWindow *window,
                /* Ask the user if he wants to download the message if
                   we're not online */
                if (!tny_device_is_online (modest_runtime_get_device())) {
-                       TnyFolder *folder = NULL;
                        GtkResponseType response;
 
                        response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
@@ -1639,30 +1693,31 @@ message_reader (ModestMsgViewWindow *window,
                        if (response == GTK_RESPONSE_CANCEL)
                                return FALSE;
                
-                       /* Offer the connection dialog if necessary */
                        folder = tny_header_get_folder (header);
-                       if (folder) {
-                               if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, 
-                                                                                             TNY_FOLDER_STORE (folder))) {
-                                       g_object_unref (folder);
-                                       return FALSE;
-                               }
-                               g_object_unref (folder);
-                       }
+                       info = g_slice_new (MsgReaderInfo);
+                       info->header = g_object_ref (header);
+                       info->row_reference = gtk_tree_row_reference_copy (row_reference);
+
+                       /* Offer the connection dialog if necessary */
+                       modest_platform_connect_if_remote_and_perform ((GtkWindow *) window, 
+                                                                      TRUE,
+                                                                      TNY_FOLDER_STORE (folder),
+                                                                      message_reader_performer, 
+                                                                      info);
+                       g_object_unref (folder);
+                       return TRUE;
                }
        }
-
-       /* New mail operation */
-       mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(window),
-                                                                modest_ui_actions_get_msgs_full_error_handler, 
-                                                                NULL, NULL);
-                               
-       modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
-       modest_mail_operation_get_msg (mail_op, header, view_msg_cb, row_reference);
-       g_object_unref (mail_op);
-
-       /* Update window dimming rules */
-       modest_ui_actions_check_window_dimming_rules (MODEST_WINDOW (window));
+       
+       folder = tny_header_get_folder (header);
+       account = tny_folder_get_account (folder);
+       info = g_slice_new (MsgReaderInfo);
+       info->header = g_object_ref (header);
+       info->row_reference = gtk_tree_row_reference_copy (row_reference);
+       
+       message_reader_performer (FALSE, NULL, (GtkWindow *) window, account, info);
+       g_object_unref (account);
+       g_object_unref (folder);
 
        return TRUE;
 }
@@ -1714,8 +1769,8 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window)
        /* Read the message & show it */
        if (!message_reader (window, priv, header, row_reference)) {
                retval = FALSE;
-               gtk_tree_row_reference_free (row_reference);
        }
+       gtk_tree_row_reference_free (row_reference);
 
        /* Free */
        g_object_unref (header);
@@ -1728,7 +1783,8 @@ 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);
@@ -1738,7 +1794,7 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window)
                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;
 
@@ -1746,29 +1802,23 @@ 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);
-               if (!header)
-                       break;
-               if (!msg_is_visible (header, priv->is_outbox)) {
-                       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);
+                               gtk_tree_row_reference_free (row_reference);
+                       } else {
+                               finished = FALSE;
+                       }
                        g_object_unref (header);
-                       break;
                }
-
-               gtk_tree_path_free (path);
-               g_object_unref (header);
-
-               return TRUE;
        }
 
        gtk_tree_path_free (path);
-       return FALSE;
+       return retval;
 }
 
 static void
@@ -1783,13 +1833,13 @@ view_msg_cb (ModestMailOperation *mail_op,
        ModestMsgViewWindowPrivate *priv = NULL;
        GtkTreeRowReference *row_reference = NULL;
 
+       row_reference = (GtkTreeRowReference *) user_data;
        if (canceled) {
-               g_object_unref (self);
+               gtk_tree_row_reference_free (row_reference);
                return;
        }
        
        /* If there was any error */
-       row_reference = (GtkTreeRowReference *) user_data;
        if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
                gtk_tree_row_reference_free (row_reference);                    
                return;
@@ -1804,9 +1854,11 @@ view_msg_cb (ModestMailOperation *mail_op,
        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 */
@@ -1831,8 +1883,9 @@ view_msg_cb (ModestMailOperation *mail_op,
        g_signal_emit (G_OBJECT (self), signals[MSG_CHANGED_SIGNAL], 
                       0, priv->header_model, priv->row_reference);
 
-       /* Free new references */
+       /* Frees */
        g_object_unref (self);
+       gtk_tree_row_reference_free (row_reference);            
 }
 
 TnyFolderType
@@ -1852,7 +1905,7 @@ modest_msg_view_window_get_folder_type (ModestMsgViewWindow *window)
 
                folder = tny_msg_get_folder (msg);
                if (folder) {
-                       folder_type = tny_folder_get_folder_type (folder);
+                       folder_type = modest_tny_folder_guess_folder_type (folder);
                        g_object_unref (folder);
                }
                g_object_unref (msg);
@@ -2006,7 +2059,7 @@ modest_msg_view_window_show_toolbar (ModestWindow *self,
                toolbar_resize (MODEST_MSG_VIEW_WINDOW (self));
 
                /* Add ProgressBar (Transfer toolbar) */ 
-               priv->progress_bar = modest_progress_bar_widget_new ();
+               priv->progress_bar = modest_progress_bar_new ();
                gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
                placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressbarView");
                insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
@@ -2072,7 +2125,7 @@ modest_msg_view_window_clipboard_owner_change (GtkClipboard *clipboard,
        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 
@@ -2189,9 +2242,8 @@ on_mail_operation_finished (ModestMailOperation *mail_op,
        
        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);
+                       modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
+                                                                mail_op);
                        tmp = g_slist_next (tmp);
                }
 
@@ -2199,6 +2251,14 @@ on_mail_operation_finished (ModestMailOperation *mail_op,
                if (observers_empty (self)) {
                        set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
                }
+
+               /* Update dimming rules. We have to do this right here
+                  and not in view_msg_cb because at that point the
+                  transfer mode is still enabled so the dimming rule
+                  won't let the user delete the message that has been
+                  readed for example */
+               modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
+               modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
        }
 }
 
@@ -2300,7 +2360,7 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart
                return;
        }
 
-       if (!TNY_IS_MSG (mime_part)) {
+       if (!modest_tny_mime_part_is_msg (mime_part)) {
                gchar *filepath = NULL;
                const gchar *att_filename = tny_mime_part_get_filename (mime_part);
                const gchar *content_type;
@@ -2389,7 +2449,7 @@ typedef struct
 {
        GList *pairs;
        GtkWidget *banner;
-       gboolean result;
+       GnomeVFSResult result;
 } SaveMimePartInfo;
 
 static void save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct);
@@ -2412,7 +2472,6 @@ save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
        info->pairs = NULL;
        if (with_struct) {
                gtk_widget_destroy (info->banner);
-               g_object_unref (info->banner);
                g_slice_free (SaveMimePartInfo, info);
        }
 }
@@ -2423,16 +2482,16 @@ idle_save_mime_part_show_result (SaveMimePartInfo *info)
        if (info->pairs != NULL) {
                save_mime_part_to_file (info);
        } else {
-               gboolean result;
-               result = info->result;
-
                /* This is a GDK lock because we are an idle callback and
                 * hildon_banner_show_information is or does Gtk+ code */
 
                gdk_threads_enter (); /* CHECKED */
                save_mime_part_info_free (info, TRUE);
-               if (result) {
+               if (info->result == GNOME_VFS_OK) {
                        hildon_banner_show_information (NULL, NULL, _CS("sfil_ib_saved"));
+               } else if (info->result == GNOME_VFS_ERROR_NO_SPACE) {
+                       hildon_banner_show_information (NULL, NULL, dgettext("ke-recv", 
+                                                                            "cerm_device_memory_full"));
                } else {
                        hildon_banner_show_information (NULL, NULL, _("mail_ib_file_operation_failed"));
                }
@@ -2445,26 +2504,22 @@ idle_save_mime_part_show_result (SaveMimePartInfo *info)
 static gpointer
 save_mime_part_to_file (SaveMimePartInfo *info)
 {
-       GnomeVFSResult result;
        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, 0644);
-       if (result == GNOME_VFS_OK) {
+       info->result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0644);
+       if (info->result == GNOME_VFS_OK) {
                stream = tny_vfs_stream_new (handle);
                if (tny_mime_part_decode_to_stream (pair->part, stream, NULL) < 0) {
-                       decode_result = FALSE;
+                       info->result = GNOME_VFS_ERROR_IO;
                }
                g_object_unref (G_OBJECT (stream));
                g_object_unref (pair->part);
                g_slice_free (SaveMimePartPair, pair);
                info->pairs = g_list_delete_link (info->pairs, info->pairs);
-               info->result = decode_result;
        } else {
                save_mime_part_info_free (info, FALSE);
-               info->result = FALSE;
        }
 
        g_idle_add ((GSourceFunc) idle_save_mime_part_show_result, info);
@@ -2501,9 +2556,8 @@ save_mime_parts_to_file_with_checks (SaveMimePartInfo *info)
        } else {
                GtkWidget *banner = hildon_banner_show_animation (NULL, NULL, 
                                                                  _CS("sfil_ib_saving"));
-               info->banner = g_object_ref (banner);
+               info->banner = banner;
                g_thread_create ((GThreadFunc)save_mime_part_to_file, info, FALSE, NULL);
-               g_object_unref (banner);
        }
 
 }
@@ -2516,7 +2570,6 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m
        GList *files_to_save = NULL;
        GtkWidget *save_dialog = NULL;
        gchar *folder = NULL;
-       gboolean canceled = FALSE;
        const gchar *filename = NULL;
        gchar *save_multiple_str = NULL;
 
@@ -2538,11 +2591,15 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m
                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)) {
+               if (!modest_tny_mime_part_is_msg (mime_part) && 
+                   modest_tny_mime_part_is_attachment_for_modest (mime_part) &&
+                   !tny_mime_part_is_purged (mime_part)) {
                        filename = tny_mime_part_get_filename (mime_part);
                } else {
+                       /* TODO: show any error? */
                        g_warning ("Tried to save a non-file attachment");
-                       canceled = TRUE;
+                       g_object_unref (mime_parts);
+                       return;
                }
                g_object_unref (mime_part);
        } else {
@@ -2566,6 +2623,7 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m
        /* if multiple, set multiple string */
        if (save_multiple_str) {
                g_object_set (G_OBJECT (save_dialog), "save-multiple", save_multiple_str, NULL);
+               gtk_window_set_title (GTK_WINDOW (save_dialog), _FM("sfil_ti_save_objects_files"));
        }
                
        /* show dialog */
@@ -2582,27 +2640,24 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, TnyList *m
                        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)) {
+                               if ((modest_tny_mime_part_is_attachment_for_modest (mime_part)) &&
+                                   !tny_mime_part_is_purged (mime_part) &&
+                                   (tny_mime_part_get_filename (mime_part) != NULL)) {
                                        SaveMimePartPair *pair;
-
-                                       if ((!tny_iterator_is_done (iter)) &&
-                                           (tny_mime_part_get_filename (mime_part) == NULL)) {
-                                               g_object_unref (mime_part);
-                                               continue;
-                                       }
                                        
                                        pair = g_slice_new0 (SaveMimePartPair);
-                                       if (tny_iterator_is_done (iter)) {
-                                               pair->filename = g_strdup (chooser_uri);
+                                       if (save_multiple_str) {
+                                               gchar *escaped = gnome_vfs_escape_slashes (
+                                                       tny_mime_part_get_filename (mime_part));
+                                               pair->filename = g_build_filename (chooser_uri, escaped, NULL);
+                                               g_free (escaped);
                                        } else {
-                                               pair->filename = 
-                                                       g_build_filename (chooser_uri,
-                                                                         tny_mime_part_get_filename (mime_part), NULL);
+                                               pair->filename = g_strdup (chooser_uri);
                                        }
                                        pair->part = mime_part;
                                        files_to_save = g_list_prepend (files_to_save, pair);
                                }
+                               tny_iterator_next (iter);
                        }
                        g_object_unref (iter);
                }
@@ -2688,7 +2743,7 @@ modest_msg_view_window_remove_attachments (ModestMsgViewWindow *window, gboolean
                iter = tny_list_create_iterator (mime_parts);
                part = (TnyMimePart *) tny_iterator_get_current (iter);
                g_object_unref (iter);
-               if (TNY_IS_MSG (part)) {
+               if (modest_tny_mime_part_is_msg (part)) {
                        TnyHeader *header;
                        header = tny_msg_get_header (TNY_MSG (part));
                        filename = tny_header_get_subject (header);