Fixes NB#137624, crash when creating a new folder in offline mode
[modest] / src / modest-ui-actions.c
index b191daa..8e4185b 100644 (file)
@@ -46,6 +46,7 @@
 #include "modest-platform.h"
 #include "modest-debug.h"
 #include <tny-mime-part.h>
+#include <tny-error.h>
 #include <tny-camel-folder.h>
 #include <tny-camel-imap-folder.h>
 #include <tny-camel-pop-folder.h>
@@ -87,7 +88,6 @@
 
 #include <gtkhtml/gtkhtml.h>
 
-#define MIN_FREE_SPACE 5 * 1024 * 1024
 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
 
 typedef struct _GetMsgAsyncHelper {
@@ -521,7 +521,6 @@ modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
 
 
        if (response == GTK_RESPONSE_OK) {
-               ModestWindow *main_window = NULL;
                ModestWindowMgr *mgr = NULL;
                GtkTreeModel *model = NULL;
                GtkTreeSelection *sel = NULL;
@@ -552,7 +551,7 @@ modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
                }
 
                /* Disable window dimming management */
-               modest_window_disable_dimming (MODEST_WINDOW(win));
+               modest_window_disable_dimming (win);
 
                /* Remove each header. If it's a view window header_view == NULL */
                mail_op = modest_mail_operation_new ((GObject *) win);
@@ -565,18 +564,14 @@ modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
                if (sel != NULL) {
                        gtk_tree_selection_unselect_all (sel);
                }
-               modest_window_enable_dimming (MODEST_WINDOW(win));
+               modest_window_enable_dimming (win);
 
                if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
                        modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
 
                        /* Get main window */
                        mgr = modest_runtime_get_window_mgr ();
-                       main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
                } else if (MODEST_IS_MAIN_WINDOW (win)) {
-                       /* Move cursor to next row */
-                       main_window = win;
-
                        /* Select next or previous row */
                        if (gtk_tree_row_reference_valid (next_row_reference)) {
                                gtk_tree_selection_select_path (sel, next_path);
@@ -597,10 +592,8 @@ modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
                }
 
                /* Update toolbar dimming state */
-               if (main_window) {
-                       modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
-                       modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
-               }
+               modest_ui_actions_check_menu_dimming_rules (win);
+               modest_ui_actions_check_toolbar_dimming_rules (win);
 
                /* Free */
                g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
@@ -707,12 +700,8 @@ modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
        clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
        selection = gtk_clipboard_wait_for_text (clipboard);
 
-       /* Question: why is the clipboard being used here?
-        * It doesn't really make a lot of sense. */
-
-       if (selection)
-       {
-               modest_address_book_add_address (selection);
+       if (selection) {
+               modest_address_book_add_address (selection, (GtkWindow *) win);
                g_free (selection);
        }
 }
@@ -768,6 +757,54 @@ modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
 #endif /* !MODEST_TOOLKIT_GTK */
 }
 
+static guint64
+count_part_size (const gchar *part)
+{
+       GnomeVFSURI *vfs_uri;
+       gchar *escaped_filename;
+       gchar *filename;
+       GnomeVFSFileInfo *info;
+       guint64 result;
+
+       /* Estimation of attachment size if we cannot get it from file info */
+       result = 32768;
+
+       vfs_uri = gnome_vfs_uri_new (part);
+
+       escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
+       filename = gnome_vfs_unescape_string_for_display (escaped_filename);
+       g_free (escaped_filename);
+       gnome_vfs_uri_unref (vfs_uri);
+
+       info = gnome_vfs_file_info_new ();
+       
+       if (gnome_vfs_get_file_info (part, 
+                                    info, 
+                                    GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
+           == GNOME_VFS_OK) {
+               if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
+                       result = info->size;
+               }
+       }
+       g_free (filename);
+       gnome_vfs_file_info_unref (info);
+
+       return result;
+}
+
+static guint64 
+count_parts_size (GSList *parts)
+{
+       GSList *node;
+       guint64 result = 0;
+
+       for (node = parts; node != NULL; node = g_slist_next (node)) {
+               result += count_part_size ((const gchar *) node->data);
+       }
+
+       return result;
+}
+
 void
 modest_ui_actions_compose_msg(ModestWindow *win,
                              const gchar *to_str,
@@ -790,11 +827,37 @@ modest_ui_actions_compose_msg(ModestWindow *win,
        ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
        ModestTnyAccountStore *store = modest_runtime_get_account_store();
        GnomeVFSFileSize total_size, allowed_size;
+       guint64 available_disk, expected_size, parts_size;
+       guint parts_count;
 
        /* we check for low-mem */
        if (modest_platform_check_memory_low (win, TRUE))
                goto cleanup;
 
+       available_disk = modest_utils_get_available_space (NULL);
+       parts_count = g_slist_length (attachments);
+       parts_size = count_parts_size (attachments);
+       expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
+
+       /* Double check: disk full condition or message too big */
+       if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
+           expected_size > available_disk) {
+               gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
+               modest_platform_system_banner (NULL, NULL, msg);
+               g_free (msg);
+
+               return;
+       }
+
+       if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
+               modest_platform_run_information_dialog (
+                       GTK_WINDOW(win),
+                       _("mail_ib_error_attachment_size"),
+                       TRUE);
+               return;
+       }
+
+
 #ifdef MODEST_TOOLKIT_HILDON2
        if (win)
                account_name = g_strdup (modest_window_get_active_account(win));
@@ -831,9 +894,12 @@ modest_ui_actions_compose_msg(ModestWindow *win,
        signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
        g_free (recipient);
        if (body_str != NULL) {
-               body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
+               body = use_signature ? g_strconcat(body_str, "\n",
+                                                  MODEST_TEXT_UTILS_SIGNATURE_MARKER,
+                                                  "\n", signature, NULL) : g_strdup(body_str);
        } else {
-               body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
+               body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
+                                                  "\n", signature, NULL) : g_strdup("");
        }
 
        msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
@@ -856,16 +922,18 @@ modest_ui_actions_compose_msg(ModestWindow *win,
        gtk_widget_show_all (GTK_WIDGET (msg_win));
 
        while (attachments) {
-               total_size +=
+               GnomeVFSFileSize att_size;
+               att_size =
                        modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
                                                               attachments->data, allowed_size);
+               total_size += att_size;
 
-               if (total_size > allowed_size) {
-                       g_warning ("%s: total size: %u",
-                                  __FUNCTION__, (unsigned int)total_size);
+               if (att_size > allowed_size) {
+                       g_debug ("%s: total size: %u",
+                                __FUNCTION__, (unsigned int)total_size);
                        break;
                }
-               allowed_size -= total_size;
+               allowed_size -= att_size;
 
                attachments = g_slist_next(attachments);
        }
@@ -922,18 +990,27 @@ modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
                              error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
                        gchar *subject, *msg, *format = NULL;
                        TnyAccount *account;
-                       subject = tny_header_dup_subject (header);
+
+                       subject = (header) ? tny_header_dup_subject (header) : NULL;
                        if (!subject)
                                subject = g_strdup (_("mail_va_no_subject"));
 
                        account = modest_mail_operation_get_account (mail_op);
                        if (account) {
-                               ModestProtocol *protocol;
-                               ModestProtocolType proto;
-                               proto = modest_tny_account_get_protocol_type (account);
-                               protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
-                               if (protocol)
-                                 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
+                               ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
+                               ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
+
+                               if (protocol) {
+                                       if (tny_account_get_connection_status (account) ==
+                                           TNY_CONNECTION_STATUS_CONNECTED) {
+                                               format = modest_protocol_get_translation (protocol,
+                                                                                         MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
+                                                                                         subject);
+                                       } else {
+                                               format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
+                                                                         tny_account_get_hostname (account));
+                                       }
+                               }
                                g_object_unref (account);
                        }
 
@@ -966,6 +1043,7 @@ typedef struct {
 typedef struct {
        GtkTreeModel *model;
        TnyHeader *header;
+       ModestWindow *caller_window;
        OpenMsgBannerInfo *banner_info;
        GtkTreeRowReference *rowref;
 } OpenMsgHelper;
@@ -1173,78 +1251,6 @@ cleanup:
        g_object_unref (parent_win);
 }
 
-static gboolean
-is_memory_full_error (GError *error, ModestMailOperation *mail_op)
-{
-       gboolean enough_free_space = TRUE;
-       GnomeVFSURI *cache_dir_uri;
-       const gchar *cache_dir = NULL;
-       GnomeVFSFileSize free_space;
-       TnyAccountStore *acc_store;
-
-       acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
-
-       /* Cache dir is different in case we're using an external storage (like MMC account) */
-       if (mail_op) {
-               TnyAccount *account = modest_mail_operation_get_account (mail_op);
-               if (account) {
-                       if (modest_tny_account_is_memory_card_account (account)) {
-                               cache_dir = g_getenv (MODEST_MMC1_VOLUMEPATH_ENV);
-                       }
-                       g_object_unref (account);
-               }
-       }
-
-       /* Get the default local cache dir */
-       if (!cache_dir)
-               cache_dir = tny_account_store_get_cache_dir (acc_store);
-
-       cache_dir_uri = gnome_vfs_uri_new (cache_dir);
-       if (cache_dir_uri) {
-               if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
-                       if (free_space < MIN_FREE_SPACE)
-                               enough_free_space = FALSE;
-               }
-               gnome_vfs_uri_unref (cache_dir_uri);
-       }
-
-       if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
-            /* When asking for a mail and no space left on device
-               tinymail returns this error */
-            error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
-            /* When the folder summary could not be read or
-               written */
-            error->code == TNY_IO_ERROR_WRITE ||
-            error->code == TNY_IO_ERROR_READ) &&
-           !enough_free_space) {
-               return TRUE;
-       } else {
-               return FALSE;
-       }
-}
-
-static gboolean
-check_memory_full_error (GtkWidget *parent_window, GError *err)
-{
-       if (err == NULL)
-               return FALSE;
-
-       if (is_memory_full_error (err, NULL)) {
-               gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
-               modest_platform_information_banner (parent_window, NULL, msg);
-               g_free (msg);
-       } else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
-               /* If the account was created in memory full
-                  conditions then tinymail won't be able to
-                  connect so it'll return this error code */
-               modest_platform_information_banner (parent_window,
-                                                   NULL, _("emev_ui_imap_inbox_select_error"));
-       else
-               return FALSE;
-
-       return TRUE;
-}
-
 void
 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
                                                 gpointer user_data)
@@ -1260,7 +1266,9 @@ modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
        /* If the mail op has been cancelled then it's not an error:
           don't show any message */
        if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
-               if (is_memory_full_error ((GError *) error, mail_op)) {
+               TnyAccount *account = modest_mail_operation_get_account (mail_op);
+               if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
+                                                                (GError *) error, account)) {
                        gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
                        modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
                        g_free (msg);
@@ -1275,6 +1283,8 @@ modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
                        modest_platform_information_banner ((GtkWidget *) win,
                                                            NULL, user_data);
                }
+               if (account)
+                       g_object_unref (account);
        }
 
        if (win)
@@ -1338,10 +1348,22 @@ get_account_from_header (TnyHeader *header)
 }
 
 static void
+caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
+{
+       if (helper->caller_window)
+               helper->caller_window = NULL;
+}
+
+static void
 open_msg_helper_destroyer (gpointer user_data)
 {
        OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
 
+       if (helper->caller_window) {
+               g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
+               helper->caller_window = NULL;
+       }
+
        if (helper->banner_info) {
                g_free (helper->banner_info->message);
                if (helper->banner_info->idle_handler > 0) {
@@ -1381,13 +1403,15 @@ open_msg_performer(gboolean canceled,
        helper = (OpenMsgHelper *) user_data;
 
        status = tny_account_get_connection_status (account);
-       if (err || canceled) {
+       if (err || canceled || helper->caller_window == NULL) {
                modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
                /* Free the helper */
                open_msg_helper_destroyer (helper);
 
-               /* In memory full conditions we could get this error here */
-               check_memory_full_error ((GtkWidget *) parent_window, err);
+               /* In disk full conditions we could get this error here */
+               modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                               (GtkWidget *) parent_window, err,
+                                                               account, NULL);
 
                goto clean;
        }
@@ -1520,7 +1544,7 @@ open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWind
        OpenMsgHelper *helper;
        ModestWindow *window;
 
-       g_return_if_fail (header != NULL && rowref != NULL);
+       g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
 
        mgr = modest_runtime_get_window_mgr ();
 
@@ -1578,6 +1602,8 @@ open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWind
           (the user could switch between folders) */
        helper = g_slice_new (OpenMsgHelper);
        helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
+       helper->caller_window = win;
+       g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
        helper->header = g_object_ref (header);
        helper->rowref = gtk_tree_row_reference_copy (rowref);
        helper->banner_info = NULL;
@@ -1731,20 +1757,27 @@ reply_forward_cb (ModestMailOperation *mail_op,
 
        /* Create reply mail */
        switch (rf_helper->action) {
+               /* Use the msg_header to ensure that we have all the
+                  information. The summary can lack some data */
+               TnyHeader *msg_header;
        case ACTION_REPLY:
+               msg_header = tny_msg_get_header (msg);
                new_msg =
-                       modest_tny_msg_create_reply_msg (msg, header, from,
+                       modest_tny_msg_create_reply_msg (msg, msg_header, from,
                                                         (use_signature) ? signature : NULL,
                                                         rf_helper->reply_forward_type,
                                                         MODEST_TNY_MSG_REPLY_MODE_SENDER);
+               g_object_unref (msg_header);
                break;
        case ACTION_REPLY_TO_ALL:
+               msg_header = tny_msg_get_header (msg);
                new_msg =
-                       modest_tny_msg_create_reply_msg (msg, header, from,
+                       modest_tny_msg_create_reply_msg (msg, msg_header, from,
                                                         (use_signature) ? signature : NULL,
                                                         rf_helper->reply_forward_type,
                                                         MODEST_TNY_MSG_REPLY_MODE_ALL);
                edit_type = MODEST_EDIT_TYPE_REPLY;
+               g_object_unref (msg_header);
                break;
        case ACTION_FORWARD:
                new_msg =
@@ -1895,7 +1928,7 @@ reply_forward (ReplyForwardAction action, ModestWindow *win)
        ReplyForwardHelper *rf_helper = NULL;
        guint reply_forward_type;
 
-       g_return_if_fail (MODEST_IS_WINDOW(win));
+       g_return_if_fail (win && MODEST_IS_WINDOW(win));
 
        /* we check for low-mem; in that case, show a warning, and don't allow
         * reply/forward (because it could potentially require a lot of memory */
@@ -2015,7 +2048,7 @@ reply_forward (ReplyForwardAction action, ModestWindow *win)
                        if (folder)
                                g_object_unref (folder);
                } else {
-                       reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
+                       reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
                }
                /* Frees */
                g_object_unref (header_list);
@@ -2118,18 +2151,50 @@ modest_ui_actions_on_sort (GtkAction *action,
        modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
 }
 
+static gboolean
+idle_refresh_folder (gpointer source)
+{
+       ModestHeaderView *header_view = NULL;
+
+       /* If the window still exists */
+       if (!GTK_IS_WIDGET (source) ||
+           !GTK_WIDGET_VISIBLE (source))
+               return FALSE;
+
+       /* Refresh the current view */
+#ifdef MODEST_TOOLKIT_HILDON2
+       if (MODEST_IS_HEADER_WINDOW (source))
+               header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
+#else
+       if (MODEST_IS_MAIN_WINDOW (source))
+               header_view = modest_main_window_get_child_widget ((ModestMainWindow *) source,
+                                                                  MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
+#endif
+       if (header_view) {
+               TnyFolder *folder = modest_header_view_get_folder (header_view);
+               if (folder) {
+                       /* We must clear first, because otherwise set_folder will ignore
+                          the change as the folders are the same */
+                       modest_header_view_clear (header_view);
+                       modest_header_view_set_folder (header_view, folder, TRUE,
+                                                      (ModestWindow *) source, NULL, NULL);
+                       g_object_unref (folder);
+               }
+       }
+
+       return FALSE;
+}
+
 static void
-new_messages_arrived (ModestMailOperation *self,
-                     TnyList *new_headers,
-                     gpointer user_data)
+update_account_cb (ModestMailOperation *self,
+                  TnyList *new_headers,
+                  gpointer user_data)
 {
        GObject *source;
        gboolean show_visual_notifications;
 
        source = modest_mail_operation_get_source (self);
        show_visual_notifications = (source) ? FALSE : TRUE;
-       if (source)
-               g_object_unref (source);
 
        /* Notify new messages have been downloaded. If the
           send&receive was invoked by the user then do not show any
@@ -2150,43 +2215,43 @@ new_messages_arrived (ModestMailOperation *self,
                        flags = tny_header_get_flags (header);
 
                        if (!(flags & TNY_HEADER_FLAG_SEEN)) {
-                               tny_list_append (actually_new_list, G_OBJECT (header));
+                               /* Messages are ordered from most
+                                  recent to oldest. But we want to
+                                  show notifications starting from
+                                  the oldest message. That's why we
+                                  reverse the list */
+                               tny_list_prepend (actually_new_list, G_OBJECT (header));
                        }
                        g_object_unref (header);
-                       
                }
                g_object_unref (iterator);
 
                if (tny_list_get_length (actually_new_list) > 0) {
-                       modest_platform_on_new_headers_received (actually_new_list,
-                                                                show_visual_notifications);
+                       GList *new_headers_list = NULL;
+
+                       new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
+
+                       /* Send notifications */
+                       if (new_headers_list) {
+                               modest_platform_on_new_headers_received (new_headers_list,
+                                                                        show_visual_notifications);
+                               /* Free the list */
+                               modest_utils_free_notification_list (new_headers_list);
+                       }
                }
                g_object_unref (actually_new_list);
        }
 
-}
-
-gboolean
-retrieve_all_messages_cb (GObject *source,
-                         guint num_msgs,
-                         guint retrieve_limit)
-{
-       GtkWindow *window;
-       gchar *msg;
-       gint response;
-
-       window = GTK_WINDOW (source);
-       msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
-                              num_msgs, retrieve_limit);
-
-       /* Ask the user if they want to retrieve all the messages */
-       response =
-               modest_platform_run_confirmation_dialog_with_buttons (window, msg,
-                                                                     _("mcen_bd_get_all"),
-                                                                     _("mcen_bd_newest_only"));
-       /* Free and return */
-       g_free (msg);
-       return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
+       if (source) {
+               /* Refresh the current folder in an idle. We do this
+                  in order to avoid refresh cancelations if the
+                  currently viewed folder is the inbox */
+               g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+                                idle_refresh_folder,
+                                g_object_ref (source),
+                                g_object_unref);
+               g_object_unref (source);
+       }
 }
 
 typedef struct {
@@ -2210,8 +2275,10 @@ do_send_receive_performer (gboolean canceled,
        info = (SendReceiveInfo *) user_data;
 
        if (err || canceled) {
-               /* In memory full conditions we could get this error here */
-               check_memory_full_error ((GtkWidget *) parent_window, err);
+               /* In disk full conditions we could get this error here */
+               modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                               (GtkWidget *) parent_window, err,
+                                                               account, NULL);
 
                if (info->mail_op) {
                        modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
@@ -2232,8 +2299,7 @@ do_send_receive_performer (gboolean canceled,
 
        /* Send & receive. */
        modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
-                                             (info->win) ? retrieve_all_messages_cb : NULL,
-                                             new_messages_arrived, info->win);
+                                             update_account_cb, info->win);
 
  clean:
        /* Frees */
@@ -2264,6 +2330,7 @@ modest_ui_actions_do_send_receive (const gchar *account_name,
        gchar *acc_name = NULL;
        SendReceiveInfo *info;
        ModestTnyAccountStore *acc_store;
+       TnyAccount *account;
 
        /* If no account name was provided then get the current account, and if
           there is no current account then pick the default one: */
@@ -2273,7 +2340,7 @@ modest_ui_actions_do_send_receive (const gchar *account_name,
                if (!acc_name)
                        acc_name  = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
                if (!acc_name) {
-                       g_printerr ("modest: cannot get default account\n");
+                       modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
                        return;
                }
        } else {
@@ -2281,6 +2348,31 @@ modest_ui_actions_do_send_receive (const gchar *account_name,
        }
 
        acc_store = modest_runtime_get_account_store ();
+       account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
+
+       if (!account) {
+               g_free (acc_name);
+               modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
+               return;
+       }
+
+       /* Do not automatically refresh accounts that are flagged as
+          NO_AUTO_UPDATE. This could be useful for accounts that
+          handle their own update times */
+       if (!interactive) {
+               ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
+               if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
+                       const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
+                       ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
+
+                       if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
+                               g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
+                               g_object_unref (account);
+                               g_free (acc_name);
+                               return;
+                       }
+               }
+       }
 
        /* Create the info for the connect and perform */
        info = g_slice_new (SendReceiveInfo);
@@ -2288,8 +2380,7 @@ modest_ui_actions_do_send_receive (const gchar *account_name,
        info->win = (win) ? g_object_ref (win) : NULL;
        info->poke_status = poke_status;
        info->interactive = interactive;
-       info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
-                                                                    TNY_ACCOUNT_TYPE_STORE);
+       info->account = account;
        /* We need to create the operation here, because otherwise it
           could happen that the queue emits the queue-empty signal
           while we're trying to connect the account */
@@ -2707,7 +2798,8 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
 #ifdef MODEST_TOOLKIT_GTK
                        if (modest_main_window_get_contents_style (main_window) ==
                            MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
-                               modest_widget_memory_save (conf, G_OBJECT (header_view),
+                               modest_widget_memory_save (modest_runtime_get_conf (), 
+                                                          G_OBJECT (header_view),
                                                           MODEST_CONF_HEADER_VIEW_KEY);
 #endif
                        modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
@@ -2770,7 +2862,7 @@ void
 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
                                     ModestWindow *win)
 {
-       /* g_message ("%s %s", __FUNCTION__, link); */
+       /* g_debug ("%s %s", __FUNCTION__, link); */
 }
 
 
@@ -2806,7 +2898,7 @@ modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
                                          const gchar *address,
                                          ModestWindow *win)
 {
-       /* g_message ("%s %s", __FUNCTION__, address); */
+       /* g_debug ("%s %s", __FUNCTION__, address); */
 }
 
 static void
@@ -2857,8 +2949,8 @@ enough_space_for_message (ModestMsgEditWindow *edit_window,
                                                      parts_count,
                                                      parts_size);
 
-       /* Double check: memory full condition or message too big */
-       if (available_disk < MIN_FREE_SPACE ||
+       /* Double check: disk full condition or message too big */
+       if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
            expected_size > available_disk) {
                gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
                modest_platform_information_banner (NULL, NULL, msg);
@@ -2886,7 +2978,7 @@ enough_space_for_message (ModestMsgEditWindow *edit_window,
        if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
                modest_platform_run_information_dialog (
                        GTK_WINDOW(edit_window),
-                       _KR("memr_ib_operation_disabled"),
+                       _("mail_ib_error_attachment_size"),
                        TRUE);
                return FALSE;
        }
@@ -3044,6 +3136,7 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
        ModestAccountMgr *account_mgr;
        gchar *account_name;
        ModestMailOperation *mail_operation;
+       gchar *recipients;
 
        g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
 
@@ -3052,6 +3145,24 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
 
        data = modest_msg_edit_window_get_msg_data (edit_window);
 
+       if (data->subject == NULL || data->subject[0] == '\0') {
+               /* Empty subject -> no send */
+               modest_msg_edit_window_free_msg_data (edit_window, data);
+               return FALSE;
+       }
+
+       recipients = g_strconcat (data->to?data->to:"", 
+                                 data->cc?data->cc:"",
+                                 data->bcc?data->bcc:"",
+                                 NULL);
+       if (recipients == NULL || recipients[0] == '\0') {
+               /* Empty subject -> no send */
+               g_free (recipients);
+               modest_msg_edit_window_free_msg_data (edit_window, data);
+               return FALSE;
+       }
+       g_free (recipients);
+
        /* Check size */
        if (!enough_space_for_message (edit_window, data)) {
                modest_msg_edit_window_free_msg_data (edit_window, data);
@@ -3302,7 +3413,8 @@ do_create_folder_cb (ModestMailOperation *mail_op,
 
        error = modest_mail_operation_get_error (mail_op);
        if (error) {
-
+               gboolean disk_full = FALSE;
+               TnyAccount *account;
                /* Show an error. If there was some problem writing to
                   disk, show it, otherwise show the generic folder
                   create error. We do it here and not in an error
@@ -3310,13 +3422,24 @@ do_create_folder_cb (ModestMailOperation *mail_op,
                   stop the main loop in a gtk_dialog_run and then,
                   the message won't be shown until that dialog is
                   closed */
-               modest_ui_actions_disk_operations_error_handler (mail_op,
-                                                                _("mail_in_ui_folder_create_error"));
-
-               if (!is_memory_full_error ((GError *) error, mail_op)) {
-                       /* Try again if there is no full memory condition */
+               account = modest_mail_operation_get_account (mail_op);
+               if (account) {
+                       disk_full =
+                               modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                                               (GtkWidget *) source_win,
+                                                                               (GError *) error,
+                                                                               account,
+                                                                               _("mail_in_ui_folder_create_error_memory"));
+                       g_object_unref (account);
+               }
+               if (!disk_full) {
+                       /* Show an error and try again if there is no
+                          full memory condition */
+                       modest_platform_information_banner ((GtkWidget *) source_win, NULL,
+                                                           _("mail_in_ui_folder_create_error"));
                        do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
                }
+
        } else {
                /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
                 * FIXME: any other? */
@@ -3359,8 +3482,23 @@ do_create_folder_performer (gboolean canceled,
        ModestMailOperation *mail_op;
 
        if (canceled || err) {
-               /* In memory full conditions we could get this error here */
-               check_memory_full_error ((GtkWidget *) parent_window, err);
+               /* In disk full conditions we could get this error here */
+               modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                               (GtkWidget *) parent_window, err,
+                                                               NULL, _("mail_in_ui_folder_create_error_memory"));
+
+               /* This happens if we have selected the outbox folder
+                  as the parent */
+               if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
+                   TNY_IS_MERGE_FOLDER (helper->parent)) {
+                       /* Show an error and retry */
+                       modest_platform_information_banner ((GtkWidget *) parent_window,
+                                                           NULL,
+                                                           _("mail_in_ui_folder_create_error"));
+
+                       do_create_folder (parent_window, helper->parent, helper->folder_name);
+               }
+
                goto frees;
        }
 
@@ -3474,13 +3612,15 @@ modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
        const GError *error = NULL;
        gchar *message = NULL;
        gboolean mem_full;
+       TnyAccount *account = modest_mail_operation_get_account (mail_op);
 
        /* Get error message */
        error = modest_mail_operation_get_error (mail_op);
        if (!error)
                g_return_if_reached ();
 
-       mem_full = is_memory_full_error ((GError *) error, mail_op);
+       mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
+                                                               (GError *) error, account);
        if (mem_full) {
                message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
        } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
@@ -3499,6 +3639,8 @@ modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
           will be destroyed so the banner won't appear */
        modest_platform_information_banner (NULL, NULL, message);
 
+       if (account)
+               g_object_unref (account);
        if (mem_full)
                g_free (message);
 }
@@ -3543,8 +3685,10 @@ on_rename_folder_performer (gboolean canceled,
        RenameFolderInfo *data = (RenameFolderInfo*)user_data;
 
        if (canceled || err) {
-               /* In memory full conditions we could get this error here */
-               check_memory_full_error ((GtkWidget *) parent_window, err);
+               /* In disk full conditions we could get this error here */
+               modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                               (GtkWidget *) parent_window, err,
+                                                               account, NULL);
        } else {
 
                mail_op =
@@ -3678,6 +3822,13 @@ on_delete_folder_cb (gboolean canceled,
        GtkTreeSelection *sel;
 
        if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
+               /* Note that the connection process can fail due to
+                  memory low conditions as it can not successfully
+                  store the summary */
+               if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                                    (GtkWidget*) parent_window, err,
+                                                                    account, NULL))
+                       g_debug ("Error connecting when trying to delete a folder");
                g_object_unref (G_OBJECT (info->folder));
                g_free (info);
                return;
@@ -3713,8 +3864,8 @@ on_delete_folder_cb (gboolean canceled,
 
        modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
 
-       g_object_unref (G_OBJECT (mail_op));
-       g_object_unref (G_OBJECT (info->folder));
+       g_object_unref (mail_op);
+       g_object_unref (info->folder);
        g_free (info);
 }
 
@@ -3764,22 +3915,23 @@ delete_folder (ModestWindow *window, gboolean move_to_trash)
        g_free (message);
 
        if (response == GTK_RESPONSE_OK) {
-               DeleteFolderInfo *info;
+               TnyAccount *account = NULL;
+               DeleteFolderInfo *info = NULL;
                info = g_new0(DeleteFolderInfo, 1);
-               info->folder = folder;
+               info->folder = g_object_ref (folder);
                info->move_to_trash = move_to_trash;
-               g_object_ref (G_OBJECT (info->folder));
-               TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
+
+               account = tny_folder_get_account (TNY_FOLDER (folder));
                modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
                                                               TRUE,
                                                               TNY_FOLDER_STORE (account),
                                                               on_delete_folder_cb, info);
                g_object_unref (account);
+               g_object_unref (folder);
                return TRUE;
        } else {
                return FALSE;
        }
-       g_object_unref (G_OBJECT (folder));
 }
 
 void
@@ -4692,6 +4844,16 @@ modest_ui_actions_on_details (GtkAction *action,
 }
 
 void
+modest_ui_actions_on_limit_error (GtkAction *action,
+                                 ModestWindow *win)
+{
+       g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
+
+       modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
+
+}
+
+void
 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
                                     ModestMsgEditWindow *window)
 {
@@ -4941,13 +5103,13 @@ on_move_to_dialog_response (GtkDialog *dialog,
        GtkWidget *parent_win;
        MoveToInfo *helper = NULL;
        ModestFolderView *folder_view;
+       gboolean unset_edit_mode = FALSE;
 
        helper = (MoveToInfo *) user_data;
 
        parent_win = (GtkWidget *) helper->win;
        folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
                                                             MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
-
        switch (response) {
                TnyFolderStore *dst_folder;
                TnyFolderStore *selected;
@@ -5002,6 +5164,7 @@ on_move_to_dialog_response (GtkDialog *dialog,
                if (dst_folder)
                        g_object_unref (dst_folder);
 
+               unset_edit_mode = TRUE;
                break;
        default:
                g_warning ("%s unexpected response id %d", __FUNCTION__, response);
@@ -5010,6 +5173,11 @@ on_move_to_dialog_response (GtkDialog *dialog,
        /* Free the helper and exit */
        if (helper->list)
                g_object_unref (helper->list);
+       if (unset_edit_mode) {
+#ifdef MODEST_TOOLKIT_HILDON2
+               modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
+#endif
+       }
        g_slice_free (MoveToInfo, helper);
        gtk_widget_destroy (GTK_WIDGET (dialog));
 }
@@ -5059,8 +5227,8 @@ create_move_to_dialog (GtkWindow *win,
 
                modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
                                              MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
-               modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
-                                                TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
+               /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
+               /*                               TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
 
                active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
                mgr = modest_runtime_get_account_mgr ();
@@ -5256,6 +5424,8 @@ modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
                                             gpointer user_data)
 {
        GObject *win = NULL;
+       const GError *error;
+       TnyAccount *account = NULL;
 
 #ifndef MODEST_TOOLKIT_HILDON2
        ModestWindow *main_window = NULL;
@@ -5263,6 +5433,8 @@ modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
        /* Disable next automatic folder selection */
        main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
                                                         FALSE); /* don't create */
+
+       /* Show notification dialog only if the main window exists */
        if (main_window) {
                GtkWidget *folder_view = NULL;
 
@@ -5276,11 +5448,23 @@ modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
                }
        }
 #endif
-       /* Show notification dialog only if the main window exists */
        win = modest_mail_operation_get_source (mail_op);
-       modest_platform_run_information_dialog ((GtkWindow *) win,
-                                               _("mail_in_ui_folder_move_target_error"),
-                                               FALSE);
+       error = modest_mail_operation_get_error (mail_op);
+
+       if (TNY_IS_FOLDER (user_data))
+               account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
+       else if (TNY_IS_ACCOUNT (user_data))
+               account = g_object_ref (user_data);
+
+       /* If it's not a disk full error then show a generic error */
+       if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                            (GtkWidget *) win, (GError *) error,
+                                                            account, NULL))
+               modest_platform_run_information_dialog ((GtkWindow *) win,
+                                                       _("mail_in_ui_folder_move_target_error"),
+                                                       FALSE);
+       if (account)
+               g_object_unref (account);
        if (win)
                g_object_unref (win);
 }
@@ -5409,7 +5593,7 @@ modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
                        modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
                else {
                        /* do nothing; uid was registered before, so window is probably on it's way */
-                       g_warning ("debug: header %p has already been registered", header);
+                       g_debug ("header %p has already been registered", header);
                }
        } else {
                ModestMailOperation *mail_op = NULL;
@@ -5513,15 +5697,20 @@ xfer_messages_error_handler (ModestMailOperation *mail_op,
 {
        GObject *win;
        const GError *error;
+       TnyAccount *account;
 
        win = modest_mail_operation_get_source (mail_op);
        error = modest_mail_operation_get_error (mail_op);
 
-       if (error && is_memory_full_error ((GError *) error, mail_op)) {
-               gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
-               modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
-               g_free (msg);
-       } else {
+       /* We cannot get the account from the mail op as that is the
+          source account and for checking memory full conditions we
+          need the destination one */
+       account = TNY_ACCOUNT (user_data);
+
+       if (error &&
+           !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                            (GtkWidget *) win, (GError*) error,
+                                                            account, _KR("cerm_memory_card_full"))) {
                modest_platform_run_information_dialog ((GtkWindow *) win,
                                                        _("mail_in_ui_folder_move_target_error"),
                                                        FALSE);
@@ -5556,7 +5745,9 @@ xfer_messages_performer  (gboolean canceled,
        helper = (XferMsgsHelper *) user_data;
 
        if (canceled || err) {
-               if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
+               if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                                    (GtkWidget *) parent_window, err,
+                                                                    account, NULL)) {
                        /* Show the proper error message */
                        modest_ui_actions_on_account_connection_error (parent_window, account);
                }
@@ -5568,8 +5759,7 @@ xfer_messages_performer  (gboolean canceled,
        /* tinymail will return NULL for local folders it seems */
        dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
                                                                                  modest_tny_account_get_protocol_type (dst_account),
-                                                                                 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
-       g_object_unref (dst_account);
+                                                                                 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
 
        if (dst_forbids_message_add) {
                modest_platform_information_banner (GTK_WIDGET (win),
@@ -5601,7 +5791,8 @@ xfer_messages_performer  (gboolean canceled,
        /* Perform the mail operation */
        mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
                                                                 xfer_messages_error_handler,
-                                                                movehelper, NULL);
+                                                                g_object_ref (dst_account),
+                                                                g_object_unref);
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
                                         mail_op);
 
@@ -5614,6 +5805,8 @@ xfer_messages_performer  (gboolean canceled,
 
        g_object_unref (G_OBJECT (mail_op));
  end:
+       if (dst_account)
+               g_object_unref (dst_account);
        g_object_unref (helper->dst_folder);
        g_object_unref (helper->headers);
        g_slice_free (XferMsgsHelper, helper);
@@ -5627,14 +5820,25 @@ typedef struct {
 } MoveFolderInfo;
 
 static void
-on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
-               TnyAccount *account, gpointer user_data)
+on_move_folder_cb (gboolean canceled,
+                  GError *err,
+                  GtkWindow *parent_window,
+                  TnyAccount *account,
+                  gpointer user_data)
 {
        MoveFolderInfo *info = (MoveFolderInfo*)user_data;
        GtkTreeSelection *sel;
        ModestMailOperation *mail_op = NULL;
 
        if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
+               /* Note that the connection process can fail due to
+                  memory low conditions as it can not successfully
+                  store the summary */
+               if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                                    (GtkWidget*) parent_window, err,
+                                                                    account, NULL))
+                       g_debug ("Error connecting when trying to move a folder");
+
                g_object_unref (G_OBJECT (info->src_folder));
                g_object_unref (G_OBJECT (info->dst_folder));
                g_free (info);
@@ -5665,15 +5869,10 @@ on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
 
        mail_op =
                modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
-                               modest_ui_actions_move_folder_error_handler,
-                               info->src_folder, NULL);
+                                                              modest_ui_actions_move_folder_error_handler,
+                                                              g_object_ref (info->dst_folder), g_object_unref);
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
-                       mail_op);
-
-       /* Select *after* the changes */
-       /* TODO: this function hangs UI after transfer */
-       /*                      modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
-       /*                                                        TNY_FOLDER (src_folder), TRUE); */
+                                        mail_op);
 
        if (MODEST_IS_MAIN_WINDOW (parent_window)) {
                modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
@@ -5969,7 +6168,7 @@ modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
        /* Show the dialog */
        gtk_widget_show (dialog);
 
-       return TRUE;
+       return FALSE;
 }
 
 /*
@@ -6152,7 +6351,9 @@ retrieve_msg_contents_performer (gboolean canceled,
        TnyList *headers = TNY_LIST (user_data);
 
        if (err || canceled) {
-               check_memory_full_error ((GtkWidget *) parent_window, err);
+               modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
+                                                               (GtkWidget *) parent_window, err,
+                                                               account, NULL);
                goto out;
        }
 
@@ -6702,20 +6903,47 @@ modest_ui_actions_on_delete_account (GtkWindow *parent_window,
                g_free (default_account_name);
 
                removed = modest_account_mgr_remove_account (account_mgr, account_name);
-               if (!removed)
+               if (removed) {
+                       /* Close all email notifications, we cannot
+                          distinguish if the notification belongs to
+                          this account or not, so for safety reasons
+                          we remove them all */
+                       modest_platform_remove_new_mail_notifications (FALSE);
+               } else {
                        g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
+               }
        }
        return removed;
 }
 
-void 
+static void
+on_fetch_images_performer (gboolean canceled,
+                          GError *err,
+                          GtkWindow *parent_window,
+                          TnyAccount *account,
+                          gpointer user_data)
+{
+       if (err || canceled) {
+               /* Show an unable to retrieve images ??? */
+               return;
+       }
+
+       /* Note that the user could have closed the window while connecting */
+       if (GTK_WIDGET_VISIBLE (parent_window))
+               modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
+       g_object_unref ((GObject *) user_data);
+}
+
+void
 modest_ui_actions_on_fetch_images (GtkAction *action,
                                   ModestWindow *window)
 {
        g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
 
-       modest_msg_view_window_fetch_images (MODEST_MSG_VIEW_WINDOW (window));
-
+       modest_platform_connect_and_perform ((GtkWindow *) window, TRUE, 
+                                            NULL,
+                                            on_fetch_images_performer, 
+                                            g_object_ref (window));
 }
 
 void
@@ -6735,3 +6963,89 @@ modest_ui_actions_on_reload_message (const gchar *msg_id)
 
        modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
 }
+
+/** Check whether any connections are active, and cancel them if 
+ * the user wishes.
+ * Returns TRUE is there was no problem, 
+ * or if an operation was cancelled so we can continue.
+ * Returns FALSE if the user chose to cancel his request instead.
+ */
+
+gboolean
+modest_ui_actions_check_for_active_account (ModestWindow *self,
+                                           const gchar* account_name)
+{
+       ModestTnySendQueue *send_queue;
+       ModestTnyAccountStore *acc_store;
+       ModestMailOperationQueue* queue;
+       TnyConnectionStatus store_conn_status;
+       TnyAccount *store_account = NULL, *transport_account = NULL;
+       gboolean retval = TRUE, sending = FALSE;
+
+       acc_store = modest_runtime_get_account_store ();
+       queue = modest_runtime_get_mail_operation_queue ();
+
+       store_account = 
+               modest_tny_account_store_get_server_account (acc_store,
+                                                            account_name,
+                                                            TNY_ACCOUNT_TYPE_STORE);
+
+       /* This could happen if the account was deleted before the
+          call to this function */
+       if (!store_account)
+               return FALSE;
+
+       transport_account = 
+               modest_tny_account_store_get_server_account (acc_store,
+                                                            account_name,
+                                                            TNY_ACCOUNT_TYPE_TRANSPORT);
+
+       /* This could happen if the account was deleted before the
+          call to this function */
+       if (!transport_account) {
+               g_object_unref (store_account);
+               return FALSE;
+       }
+
+       /* If the transport account was not used yet, then the send
+          queue could not exist (it's created on demand) */
+       send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
+       if (TNY_IS_SEND_QUEUE (send_queue))
+               sending = modest_tny_send_queue_sending_in_progress (send_queue);
+
+       store_conn_status = tny_account_get_connection_status (store_account);
+       if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
+               gint response;
+
+               response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self), 
+                                                               _("emev_nc_disconnect_account"));
+               if (response == GTK_RESPONSE_OK) {
+                       retval = TRUE;
+               } else {
+                       retval = FALSE;
+               }
+       }
+
+       if (retval) {
+
+               /* FIXME: We should only cancel those of this account */
+               modest_mail_operation_queue_cancel_all (queue);
+
+               /* Also disconnect the account */
+               if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
+                   (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
+                       tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
+                                                     FALSE, NULL, NULL);
+               }
+               if (sending) {
+                       tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
+                                                     FALSE, NULL, NULL);
+               }
+       }
+               
+       /* Frees */
+       g_object_unref (store_account);
+       g_object_unref (transport_account);
+       
+       return retval;
+}