Another check for instance != NULL before unref (fix 8 for NB#126941)
[modest] / src / hildon2 / modest-msg-view-window.c
index 70effef..feb88c3 100644 (file)
@@ -125,26 +125,25 @@ struct _ModestMsgViewWindowPrivate {
 
 static void  modest_msg_view_window_class_init   (ModestMsgViewWindowClass *klass);
 static void  modest_msg_view_window_init         (ModestMsgViewWindow *obj);
-static void  modest_header_view_observer_init(
-               ModestHeaderViewObserverIface *iface_class);
+static void  modest_header_view_observer_init    (ModestHeaderViewObserverIface *iface_class);
 static void  modest_msg_view_window_finalize     (GObject *obj);
-static void  modest_msg_view_window_toggle_find_toolbar (GtkToggleAction *obj,
-                                                        gpointer data);
-static void  modest_msg_view_window_find_toolbar_close (GtkWidget *widget,
-                                                       ModestMsgViewWindow *obj);
+static void  modest_msg_view_window_show_find_toolbar   (GtkWidget *obj, gpointer data);
+static void  modest_msg_view_window_find_toolbar_close  (GtkWidget *widget,
+                                                        ModestMsgViewWindow *obj);
 static void  modest_msg_view_window_find_toolbar_search (GtkWidget *widget,
-                                                       ModestMsgViewWindow *obj);
-
+                                                        ModestMsgViewWindow *obj);
+static void  modest_msg_view_window_toggle_find_toolbar (GtkWidget *obj,
+                                                        gpointer data);
 static void modest_msg_view_window_disconnect_signals (ModestWindow *self);
 
-static gdouble modest_msg_view_window_get_zoom (ModestWindow *window);
-static void modest_msg_view_window_set_zoom (ModestWindow *window,
-                                            gdouble zoom);
+static gdouble modest_msg_view_window_get_zoom    (ModestWindow *window);
+static void modest_msg_view_window_set_zoom       (ModestWindow *window,
+                                                  gdouble zoom);
 static gboolean modest_msg_view_window_zoom_minus (ModestWindow *window);
-static gboolean modest_msg_view_window_zoom_plus (ModestWindow *window);
-static gboolean modest_msg_view_window_key_event (GtkWidget *window,
-                                                 GdkEventKey *event,
-                                                 gpointer userdata);
+static gboolean modest_msg_view_window_zoom_plus  (ModestWindow *window);
+static gboolean modest_msg_view_window_key_event  (GtkWidget *window,
+                                                  GdkEventKey *event,
+                                                  gpointer userdata);
 static void modest_msg_view_window_update_priority (ModestMsgViewWindow *window);
 
 static void modest_msg_view_window_show_toolbar   (ModestWindow *window,
@@ -203,7 +202,6 @@ static void set_progress_hint    (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);
@@ -222,6 +220,8 @@ static gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
 static gboolean message_reader (ModestMsgViewWindow *window,
                                ModestMsgViewWindowPrivate *priv,
                                TnyHeader *header,
+                               const gchar *msg_uid,
+                               TnyFolder *folder,
                                GtkTreeRowReference *row_reference);
 
 static void setup_menu (ModestMsgViewWindow *self);
@@ -394,7 +394,6 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        ModestWindowPrivate *parent_priv = NULL;
        GtkActionGroup *action_group = NULL;
        GError *error = NULL;
-       GdkPixbuf *window_icon;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj);
        parent_priv = MODEST_WINDOW_GET_PRIVATE(obj);
@@ -457,33 +456,11 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj)
        /* Init window */
        init_window (MODEST_MSG_VIEW_WINDOW(obj));
        
-       /* Set window icon */
-       window_icon = modest_platform_get_icon (MODEST_APP_MSG_VIEW_ICON, MODEST_ICON_SIZE_BIG); 
-       if (window_icon) {
-               gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
-               g_object_unref (window_icon);
-       }       
-       
        hildon_program_add_window (hildon_program_get_instance(),
                                   HILDON_WINDOW(obj));
 
 }
 
-
-static gboolean
-set_toolbar_transfer_mode (ModestMsgViewWindow *self)
-{
-       ModestMsgViewWindowPrivate *priv = NULL;
-       
-       g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE);
-
-       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
-
-       set_progress_hint (self, TRUE);
-       
-       return FALSE;
-}
-
 static void
 update_progress_hint (ModestMsgViewWindow *self)
 {
@@ -781,6 +758,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self,
                          G_CALLBACK (modest_ui_actions_on_details), obj);
        g_signal_connect (G_OBJECT(priv->msg_view), "link_contextual",
                          G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj);
+       g_signal_connect (G_OBJECT(priv->msg_view), "limit_error",
+                         G_CALLBACK (modest_ui_actions_on_limit_error), obj);
        g_signal_connect (G_OBJECT (priv->msg_view), "fetch_image",
                          G_CALLBACK (on_fetch_image), obj);
 
@@ -923,6 +902,84 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg,
 }
 
 ModestWindow *
+modest_msg_view_window_new_from_uid (const gchar *modest_account_name,
+                                    const gchar *mailbox,
+                                    const gchar *msg_uid)
+{
+       ModestMsgViewWindow *window = NULL;
+       ModestMsgViewWindowPrivate *priv = NULL;
+       ModestWindowMgr *mgr = NULL;
+       gboolean is_merge;
+       TnyAccount *account = 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, mailbox, msg_uid);
+
+       priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+
+
+
+       is_merge = g_str_has_prefix (msg_uid, "merge:");
+
+       /* Get the account */
+       if (!is_merge)
+               account = tny_account_store_find_account (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
+                                                         msg_uid);
+
+       
+       if (is_merge || account) {
+               TnyFolder *folder = NULL;
+
+               /* Try to get the message, if it's already downloaded
+                  we don't need to connect */
+               if (account) {
+                       folder = modest_tny_folder_store_find_folder_from_uri (TNY_FOLDER_STORE (account), msg_uid);
+               } else {
+                       ModestTnyAccountStore *account_store;
+                       ModestTnyLocalFoldersAccount *local_folders_account;
+
+                       account_store = modest_runtime_get_account_store ();
+                       local_folders_account = MODEST_TNY_LOCAL_FOLDERS_ACCOUNT (
+                               modest_tny_account_store_get_local_folders_account (account_store));
+                       folder = modest_tny_local_folders_account_get_merged_outbox (local_folders_account);
+                       g_object_unref (local_folders_account);
+               }
+               if (folder) {
+                       TnyDevice *device;
+                       gboolean device_online;
+
+                       device = modest_runtime_get_device();
+                       device_online = tny_device_is_online (device);
+                       if (device_online) {
+                               message_reader (window, priv, NULL, msg_uid, folder, NULL);
+                       } else {
+                               TnyMsg *msg = tny_folder_find_msg (folder, msg_uid, NULL);
+                               if (msg) {
+                                       tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg);
+                                       update_window_title (MODEST_MSG_VIEW_WINDOW (window));
+                                       update_branding (MODEST_MSG_VIEW_WINDOW (window));
+                                       g_object_unref (msg);
+                               } else {
+                                       message_reader (window, priv, NULL, msg_uid, folder, NULL);
+                               }
+                       }
+                       g_object_unref (folder);
+               }
+
+       }
+
+       /* Check dimming rules */
+       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
+       modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
+       modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
+
+       return MODEST_WINDOW(window);
+}
+
+ModestWindow *
 modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
                                             const gchar *modest_account_name,
                                             const gchar *mailbox,
@@ -1006,7 +1063,7 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
                gtk_tree_model_get (priv->header_model, &iter, 
                                    TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
                                    &header, -1);
-               message_reader (window, priv, header, row_reference);
+               message_reader (window, priv, header, NULL, NULL, row_reference);
                g_object_unref (header);
        }
        gtk_tree_path_free (path);
@@ -1020,7 +1077,7 @@ modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
 }
 
 ModestWindow *
-modest_msg_view_window_new_for_search_result (TnyMsg *msg, 
+modest_msg_view_window_new_for_search_result (TnyMsg *msg,
                                              const gchar *modest_account_name,
                                              const gchar *mailbox,
                                              const gchar *msg_uid)
@@ -1229,41 +1286,41 @@ modest_msg_view_window_on_row_reordered (GtkTreeModel *header_model,
                                         gpointer arg3,
                                         ModestMsgViewWindow *window)
 {
-       ModestMsgViewWindowPrivate *priv = NULL; 
+       ModestMsgViewWindowPrivate *priv = NULL;
        gboolean already_changed = FALSE;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(window);
 
        /* If the current row was reordered select the proper next
           valid row. The same if the next row reference changes */
-       if (priv->row_reference && 
-           gtk_tree_row_reference_valid (priv->row_reference)) {
-               GtkTreePath *path;
-               path = gtk_tree_row_reference_get_path (priv->row_reference);
-               if (gtk_tree_path_compare (path, arg1) == 0) {
-                       if (priv->next_row_reference) {
-                               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 (header_model, &(priv->next_row_reference), FALSE, priv->is_outbox);
-                       already_changed = TRUE;
-               }
-               gtk_tree_path_free (path);
-       }
-       if (!already_changed &&
-           priv->next_row_reference &&
+       if (!priv->row_reference ||
+           !gtk_tree_row_reference_valid (priv->row_reference))
+               return;
+
+       if (priv->next_row_reference &&
            gtk_tree_row_reference_valid (priv->next_row_reference)) {
-               GtkTreePath *path;
-               path = gtk_tree_row_reference_get_path (priv->next_row_reference);
-               if (gtk_tree_path_compare (path, arg1) == 0) {
-                       if (priv->next_row_reference) {
-                               gtk_tree_row_reference_free (priv->next_row_reference);
-                       }
+               GtkTreePath *cur, *next;
+               /* Check that the order is still the correct one */
+               cur = gtk_tree_row_reference_get_path (priv->row_reference);
+               next = gtk_tree_row_reference_get_path (priv->next_row_reference);
+               gtk_tree_path_next (cur);
+               if (gtk_tree_path_compare (cur, next) != 0) {
+                       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 (header_model, &(priv->next_row_reference), FALSE, priv->is_outbox);
+                       already_changed = TRUE;
                }
-               gtk_tree_path_free (path);
+               gtk_tree_path_free (cur);
+               gtk_tree_path_free (next);
+       } else {
+               if (priv->next_row_reference)
+                       gtk_tree_row_reference_free (priv->next_row_reference);
+               /* Update next row reference */
+               priv->next_row_reference = gtk_tree_row_reference_copy (priv->row_reference);
+               select_next_valid_row (header_model, &(priv->next_row_reference), FALSE, priv->is_outbox);
+               already_changed = TRUE;
        }
+
        check_dimming_rules_after_change (window);
 }
 
@@ -1428,46 +1485,44 @@ modest_msg_view_window_get_message_uid (ModestMsgViewWindow *self)
        return (const gchar*) priv->msg_uid;
 }
 
-static void 
-modest_msg_view_window_toggle_find_toolbar (GtkToggleAction *toggle,
+/* Used for the Ctrl+F accelerator */
+static void
+modest_msg_view_window_toggle_find_toolbar (GtkWidget *obj,
                                            gpointer data)
 {
        ModestMsgViewWindow *window = MODEST_MSG_VIEW_WINDOW (data);
        ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
-       ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
-       gboolean is_active;
-       GtkAction *action;
 
-       is_active = gtk_toggle_action_get_active (toggle);
-
-       if (is_active) {
-               gtk_widget_show (priv->find_toolbar);
-               hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
-       } else {
-               gtk_widget_hide (priv->find_toolbar);
-               modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
-       }
+       if (GTK_WIDGET_VISIBLE (priv->find_toolbar)) {
+               modest_msg_view_window_find_toolbar_close (obj, data);
+       } else {
+               modest_msg_view_window_show_find_toolbar (obj, data);
+       }
+}
 
-       /* update the toggle buttons status */
-       action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage");
-       if (action)
-               modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active);
+/* Handler for menu option */
+static void
+modest_msg_view_window_show_find_toolbar (GtkWidget *obj,
+                                         gpointer data)
+{
+       ModestMsgViewWindow *window = MODEST_MSG_VIEW_WINDOW (data);
+       ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
 
+       gtk_widget_show (priv->find_toolbar);
+       hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
 }
 
+/* Handler for click on the "X" close button in find toolbar */
 static void
 modest_msg_view_window_find_toolbar_close (GtkWidget *widget,
                                           ModestMsgViewWindow *obj)
 {
-       GtkToggleAction *toggle;
-       ModestWindowPrivate *parent_priv;
        ModestMsgViewWindowPrivate *priv;
 
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (obj);
-       parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
 
-       toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"));
-       gtk_toggle_action_set_active (toggle, FALSE);
+       /* Hide toolbar */
+       gtk_widget_hide (priv->find_toolbar);
        modest_msg_view_grab_focus (MODEST_MSG_VIEW (priv->msg_view));
 }
 
@@ -1818,6 +1873,8 @@ modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window)
 
 typedef struct {
        TnyHeader *header;
+       gchar *msg_uid;
+       TnyFolder *folder;
        GtkTreeRowReference *row_reference;
 } MsgReaderInfo;
 
@@ -1838,7 +1895,8 @@ message_reader_performer (gboolean canceled,
        }
 
        /* Register the header - it'll be unregistered in the callback */
-       modest_window_mgr_register_header (modest_runtime_get_window_mgr (), info->header, NULL);
+       if (info->header)
+               modest_window_mgr_register_header (modest_runtime_get_window_mgr (), info->header, NULL);
 
        /* New mail operation */
        mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
@@ -1846,7 +1904,10 @@ message_reader_performer (gboolean canceled,
                                                                 NULL, NULL);
 
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
-       modest_mail_operation_get_msg (mail_op, info->header, TRUE, view_msg_cb, info->row_reference);
+       if (info->header)
+               modest_mail_operation_get_msg (mail_op, info->header, TRUE, view_msg_cb, info->row_reference);
+       else
+               modest_mail_operation_find_msg (mail_op, info->folder, info->msg_uid, TRUE, view_msg_cb, NULL);
        g_object_unref (mail_op);
 
        /* Update dimming rules */
@@ -1855,7 +1916,11 @@ message_reader_performer (gboolean canceled,
 
  frees:
        /* Frees. The row_reference will be freed by the view_msg_cb callback */
-       g_object_unref (info->header);
+       g_free (info->msg_uid);
+       if (info->folder)
+               g_object_unref (info->folder);
+       if (info->header)
+               g_object_unref (info->header);
        g_slice_free (MsgReaderInfo, info);
 }
 
@@ -1876,22 +1941,27 @@ static gboolean
 message_reader (ModestMsgViewWindow *window,
                ModestMsgViewWindowPrivate *priv,
                TnyHeader *header,
+               const gchar *msg_uid,
+               TnyFolder *folder,
                GtkTreeRowReference *row_reference)
 {
        ModestWindowMgr *mgr;
        TnyAccount *account;
-       TnyFolder *folder;
        MsgReaderInfo *info;
 
-       g_return_val_if_fail (row_reference != NULL, FALSE);
-
        /* We set the header from model while we're loading */
        tny_header_view_set_header (TNY_HEADER_VIEW (priv->msg_view), header);
        gtk_window_set_title (GTK_WINDOW (window), _CS("ckdg_pb_updating"));
 
+       if (header)
+               folder = NULL;
+
+       if (folder)
+               g_object_ref (folder);
+
        mgr = modest_runtime_get_window_mgr ();
        /* Msg download completed */
-       if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED)) {
+       if (!header || !(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED)) {
 
                /* Ask the user if he wants to download the message if
                   we're not online */
@@ -1905,10 +1975,24 @@ message_reader (ModestMsgViewWindow *window,
                                return FALSE;
                        }
 
-                       folder = tny_header_get_folder (header);
+                       if (header) {
+                               folder = tny_header_get_folder (header);
+                       }
                        info = g_slice_new (MsgReaderInfo);
-                       info->header = g_object_ref (header);
-                       info->row_reference = gtk_tree_row_reference_copy (row_reference);
+                       info->msg_uid = g_strdup (msg_uid);
+                       if (header)
+                               info->header = g_object_ref (header);
+                       else
+                               info->header = NULL;    
+                       if (folder)
+                               info->folder = g_object_ref (folder);
+                       else
+                               info->folder = NULL;
+                       if (row_reference) {
+                               info->row_reference = gtk_tree_row_reference_copy (row_reference);
+                       } else {
+                               info->row_reference = NULL;
+                       }
 
                        /* Offer the connection dialog if necessary */
                        modest_platform_connect_if_remote_and_perform ((GtkWindow *) window, 
@@ -1921,15 +2005,29 @@ message_reader (ModestMsgViewWindow *window,
                }
        }
 
-       folder = tny_header_get_folder (header);
+       if (header) {
+               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);
+       info->msg_uid = g_strdup (msg_uid);
+       if (folder)
+               info->folder = g_object_ref (folder);
+       else
+               info->folder = NULL;
+       if (header)
+               info->header = g_object_ref (header);
+       else
+               info->header = NULL;
+       if (row_reference)
+               info->row_reference = gtk_tree_row_reference_copy (row_reference);
+       else
+               info->row_reference = NULL;
 
        message_reader_performer (FALSE, NULL, (GtkWindow *) window, account, info);
        g_object_unref (account);
-       g_object_unref (folder);
+       if (folder)
+               g_object_unref (folder);
 
        return TRUE;
 }
@@ -1979,7 +2077,7 @@ modest_msg_view_window_select_next_message (ModestMsgViewWindow *window)
                            &header, -1);
        
        /* Read the message & show it */
-       if (!message_reader (window, priv, header, row_reference)) {
+       if (!message_reader (window, priv, header, NULL, NULL, row_reference)) {
                retval = FALSE;
        }
        gtk_tree_row_reference_free (row_reference);
@@ -2020,7 +2118,7 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window)
                                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);
+                               retval = message_reader (window, priv, header, NULL, NULL, row_reference);
                                gtk_tree_row_reference_free (row_reference);
                        } else {
                                finished = FALSE;
@@ -2050,7 +2148,8 @@ view_msg_cb (ModestMailOperation *mail_op,
 
        row_reference = (GtkTreeRowReference *) user_data;
        if (canceled) {
-               gtk_tree_row_reference_free (row_reference);
+               if (row_reference)
+                       gtk_tree_row_reference_free (row_reference);
                self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
                if (self) {
                        /* Restore window title */
@@ -2062,7 +2161,8 @@ view_msg_cb (ModestMailOperation *mail_op,
 
        /* If there was any error */
        if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
-               gtk_tree_row_reference_free (row_reference);
+               if (row_reference)
+                       gtk_tree_row_reference_free (row_reference);
                self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op);
                if (self) {
                        /* Restore window title */
@@ -2113,7 +2213,8 @@ view_msg_cb (ModestMailOperation *mail_op,
 
        /* Frees */
        g_object_unref (self);
-       gtk_tree_row_reference_free (row_reference);            
+       if (row_reference)
+               gtk_tree_row_reference_free (row_reference);            
 }
 
 TnyFolderType
@@ -2205,7 +2306,7 @@ toolbar_resize (ModestMsgViewWindow *self)
                gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
                gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
                gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
-               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo");
+               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReplyAll");
                gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
                gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
                gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
@@ -2213,7 +2314,7 @@ toolbar_resize (ModestMsgViewWindow *self)
                gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
                gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
                gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
-               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FindInMessage");
+               widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDownloadExternalImages");
                gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
                gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
                gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
@@ -2351,8 +2452,10 @@ on_mail_operation_started (ModestMailOperation *mail_op,
        tmp = priv->progress_widgets;
        source = modest_mail_operation_get_source(mail_op);
        if (G_OBJECT (self) == source) {
-               if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
-                       set_toolbar_transfer_mode(self);
+               if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE ||
+                   op_type == MODEST_MAIL_OPERATION_TYPE_OPEN ||
+                   op_type == MODEST_MAIL_OPERATION_TYPE_DELETE) {
+                       set_progress_hint (self, TRUE);
                        while (tmp) {
                                modest_progress_object_add_operation (
                                                MODEST_PROGRESS_OBJECT (tmp->data),
@@ -2362,9 +2465,12 @@ on_mail_operation_started (ModestMailOperation *mail_op,
                }
        }
        g_object_unref (source);
+
+       /* Update dimming rules */
+       check_dimming_rules_after_change (self);
 }
 
-static void 
+static void
 on_mail_operation_finished (ModestMailOperation *mail_op,
                            gpointer user_data)
 {
@@ -2372,13 +2478,15 @@ on_mail_operation_finished (ModestMailOperation *mail_op,
        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) {
+
+       if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE ||
+           op_type == MODEST_MAIL_OPERATION_TYPE_OPEN ||
+           op_type == MODEST_MAIL_OPERATION_TYPE_DELETE) {
                while (tmp) {
                        modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
                                                                 mail_op);
@@ -2397,7 +2505,6 @@ on_mail_operation_finished (ModestMailOperation *mail_op,
           won't let the user delete the message that has been
           readed for example */
        check_dimming_rules_after_change (self);
-
 }
 
 static void
@@ -2666,6 +2773,7 @@ typedef struct
 {
        GList *pairs;
        GnomeVFSResult result;
+       gchar *uri;
 } SaveMimePartInfo;
 
 static void save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct);
@@ -2686,6 +2794,7 @@ save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
        }
        g_list_free (info->pairs);
        info->pairs = NULL;
+       g_free (info->uri);
        if (with_struct) {
                g_slice_free (SaveMimePartInfo, info);
        }
@@ -2694,25 +2803,27 @@ save_mime_part_info_free (SaveMimePartInfo *info, gboolean with_struct)
 static gboolean
 idle_save_mime_part_show_result (SaveMimePartInfo *info)
 {
-       if (info->pairs != NULL) {
-               save_mime_part_to_file (info);
-       } else {
-               /* This is a GDK lock because we are an idle callback and
-                * hildon_banner_show_information is or does Gtk+ code */
+       /* 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 (info->result == GNOME_VFS_OK) {
-                       hildon_banner_show_information (NULL, NULL, _CS("sfil_ib_saved"));
-               } else if (info->result == GNOME_VFS_ERROR_NO_SPACE) {
-                       gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
-                       modest_platform_information_banner (NULL, NULL, msg);
-                       g_free (msg);
-               } else {
-                       hildon_banner_show_information (NULL, NULL, _("mail_ib_file_operation_failed"));
-               }
-               gdk_threads_leave (); /* CHECKED */
+       gdk_threads_enter (); /* CHECKED */
+       if (info->result == GNOME_VFS_OK) {
+               hildon_banner_show_information (NULL, NULL, _CS("sfil_ib_saved"));
+       } else if (info->result == GNOME_VFS_ERROR_NO_SPACE) {
+               gchar *msg = NULL;
+
+               /* Check if the uri belongs to the external mmc */
+               if (g_str_has_prefix (info->uri, g_getenv (MODEST_MMC1_VOLUMEPATH_ENV)))
+                       msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+               else
+                       msg = g_strdup (_KR("cerm_memory_card_full"));
+               modest_platform_information_banner (NULL, NULL, msg);
+               g_free (msg);
+       } else {
+               hildon_banner_show_information (NULL, NULL, _("mail_ib_file_operation_failed"));
        }
+       save_mime_part_info_free (info, FALSE);
+       gdk_threads_leave (); /* CHECKED */
 
        return FALSE;
 }
@@ -2740,15 +2851,19 @@ save_mime_part_to_file (SaveMimePartInfo *info)
                        }
                }
                g_object_unref (G_OBJECT (stream));
-               g_object_unref (pair->part);
-               g_slice_free (SaveMimePartPair, pair);
-               info->pairs = g_list_delete_link (info->pairs, info->pairs);
        } else {
-               g_warning ("Could not create save attachment %s: %s\n", pair->filename, gnome_vfs_result_to_string (info->result));
-               save_mime_part_info_free (info, FALSE);
+               g_warning ("Could not create save attachment %s: %s\n", 
+                          pair->filename, gnome_vfs_result_to_string (info->result));
+       }
+
+       /* Go on saving remaining files */
+       info->pairs = g_list_remove_link (info->pairs, info->pairs);
+       if (info->pairs != NULL) {
+               save_mime_part_to_file (info);
+       } else {
+               g_idle_add ((GSourceFunc) idle_save_mime_part_show_result, info);
        }
 
-       g_idle_add ((GSourceFunc) idle_save_mime_part_show_result, info);
        return NULL;
 }
 
@@ -2860,14 +2975,15 @@ save_attachments_response (GtkDialog *dialog,
                }
                g_object_unref (iter);
        }
-       g_free (chooser_uri);
 
        if (files_to_save != NULL) {
                SaveMimePartInfo *info = g_slice_new0 (SaveMimePartInfo);
                info->pairs = files_to_save;
                info->result = TRUE;
+               info->uri = g_strdup (chooser_uri);
                save_mime_parts_to_file_with_checks ((GtkWindow *) dialog, info);
        }
+       g_free (chooser_uri);
 
  end:
        /* Free and close the dialog */
@@ -3308,9 +3424,19 @@ setup_menu (ModestMsgViewWindow *self)
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(self));
 
        /* Settings menu buttons */
-       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_replytoall"), NULL,
-                                          APP_MENU_CALLBACK (modest_ui_actions_on_reply_all),
-                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_reply_msg));
+       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_find"), NULL,
+                                          APP_MENU_CALLBACK (modest_msg_view_window_show_find_toolbar),
+                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_find_in_msg));
+
+       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self),
+                                          dngettext(GETTEXT_PACKAGE,
+                                                    "mcen_me_move_message",
+                                                    "mcen_me_move_messages",
+                                                    1),
+                                          NULL,
+                                          APP_MENU_CALLBACK (modest_ui_actions_on_move_to),
+                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_move_to));
+
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_forward"), "<Control>d",
                                           APP_MENU_CALLBACK (modest_ui_actions_on_forward),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_reply_msg));
@@ -3318,6 +3444,7 @@ setup_menu (ModestMsgViewWindow *self)
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_mark_as_read"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_on_mark_as_read),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_mark_as_read_msg_in_view));
+
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_mark_as_unread"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_on_mark_as_unread),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_mark_as_unread_msg_in_view));
@@ -3336,9 +3463,6 @@ setup_menu (ModestMsgViewWindow *self)
                                           APP_MENU_CALLBACK (modest_ui_actions_add_to_contacts),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_add_to_contacts));
 
-       modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mail_bd_external_images"), NULL,
-                                          APP_MENU_CALLBACK (modest_ui_actions_on_fetch_images),
-                                          MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_fetch_images));
        modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_ti_message_properties"), NULL,
                                           APP_MENU_CALLBACK (modest_ui_actions_on_details),
                                           MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_details));
@@ -3401,7 +3525,7 @@ modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
                        gtk_widget_destroy (picker_dialog);
 
                        if (selected)
-                               modest_address_book_add_address (selected);
+                               modest_address_book_add_address (selected, (GtkWindow *) self);
                        g_free (selected);
 
                } else {
@@ -3457,7 +3581,7 @@ modest_msg_view_window_reload (ModestMsgViewWindow *self)
        priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
        header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (self));     
 
-       if (!message_reader (self, priv, header, priv->row_reference)) {
+       if (!message_reader (self, priv, header, NULL, NULL, priv->row_reference)) {
                g_warning ("Shouldn't happen, trying to reload a message failed");
        }
 
@@ -3481,7 +3605,7 @@ update_branding (ModestMsgViewWindow *self)
        mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (self));
 
        mgr = modest_runtime_get_account_mgr ();
-       
+
        if (modest_account_mgr_account_is_multimailbox (mgr, account, &protocol)) {
                if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
                        service_name = modest_account_protocol_get_service_name (MODEST_ACCOUNT_PROTOCOL (protocol),