This commit implements a new handling of image attachments. We follow
[modest] / src / modest-mail-operation.c
index d589f23..678e9c2 100644 (file)
@@ -45,6 +45,7 @@
 #include <camel/camel-stream-mem.h>
 #include <glib/gi18n.h>
 #include "modest-platform.h"
+#include "modest-account-mgr-helpers.h"
 #include <modest-tny-account.h>
 #include <modest-tny-send-queue.h>
 #include <modest-runtime.h>
@@ -129,7 +130,7 @@ typedef struct _XFerMsgAsyncHelper
        ModestMailOperation *mail_op;
        TnyList *headers;
        TnyFolder *dest_folder;
-       XferMsgsAsynUserCallback user_callback; 
+       XferAsyncUserCallback user_callback;    
        gboolean delete;
        gpointer user_data;
 } XFerMsgAsyncHelper;
@@ -143,6 +144,7 @@ static void          modest_mail_operation_create_msg (ModestMailOperation *self
                                                       const gchar *cc, const gchar *bcc,
                                                       const gchar *subject, const gchar *plain_body,
                                                       const gchar *html_body, const GList *attachments_list,
+                                                      const GList *images_list,
                                                       TnyHeaderFlags priority_flags,
                                                       ModestMailOperationCreateMsgCallback callback,
                                                       gpointer userdata);
@@ -159,6 +161,7 @@ typedef struct
        gchar *plain_body;
        gchar *html_body;
        GList *attachments_list;
+       GList *images_list;
        TnyHeaderFlags priority_flags;
        ModestMailOperationCreateMsgCallback callback;
        gpointer userdata;
@@ -358,7 +361,7 @@ modest_mail_operation_get_source (ModestMailOperation *self)
                return NULL;
        }
        
-       return g_object_ref (priv->source);
+       return (priv->source) ? g_object_ref (priv->source) : NULL;
 }
 
 ModestMailOperationStatus
@@ -563,7 +566,10 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
                /* TODO: connect to the msg-sent in order to know when
                   the mail operation is finished */
 
-               tny_send_queue_add (send_queue, msg, &(priv->error));
+/*             tny_send_queue_add (send_queue, msg, &(priv->error)); */
+               modest_tny_send_queue_add (MODEST_TNY_SEND_QUEUE(send_queue), 
+                                          msg, 
+                                          &(priv->error));
 
                /* TODO: we're setting always success, do the check in
                   the handler */
@@ -588,12 +594,12 @@ idle_create_msg_cb (gpointer idle_data)
 
        gdk_threads_enter (); /* CHECKED */
        info->callback (info->mail_op, info->msg, info->userdata);
-       gdk_threads_leave (); /* CHECKED */
 
        g_object_unref (info->mail_op);
        if (info->msg)
                g_object_unref (info->msg);
        g_slice_free (CreateMsgIdleInfo, info);
+       gdk_threads_leave (); /* CHECKED */
 
        return FALSE;
 }
@@ -609,11 +615,12 @@ create_msg_thread (gpointer thread_data)
        if (info->html_body == NULL) {
                new_msg = modest_tny_msg_new (info->to, info->from, info->cc, 
                                              info->bcc, info->subject, info->plain_body, 
-                                             info->attachments_list); /* FIXME: attachments */
+                                             info->attachments_list);
        } else {
                new_msg = modest_tny_msg_new_html_plain (info->to, info->from, info->cc,
                                                         info->bcc, info->subject, info->html_body,
-                                                        info->plain_body, info->attachments_list);
+                                                        info->plain_body, info->attachments_list,
+                                                        info->images_list);
        }
 
        if (new_msg) {
@@ -648,6 +655,8 @@ create_msg_thread (gpointer thread_data)
        g_free (info->subject);
        g_list_foreach (info->attachments_list, (GFunc) g_object_unref, NULL);
        g_list_free (info->attachments_list);
+       g_list_foreach (info->images_list, (GFunc) g_object_unref, NULL);
+       g_list_free (info->images_list);
 
        if (info->callback) {
                CreateMsgIdleInfo *idle_info;
@@ -676,6 +685,7 @@ modest_mail_operation_create_msg (ModestMailOperation *self,
                                  const gchar *subject, const gchar *plain_body,
                                  const gchar *html_body,
                                  const GList *attachments_list,
+                                 const GList *images_list,
                                  TnyHeaderFlags priority_flags,
                                  ModestMailOperationCreateMsgCallback callback,
                                  gpointer userdata)
@@ -695,6 +705,8 @@ modest_mail_operation_create_msg (ModestMailOperation *self,
        info->html_body = g_strdup (html_body);
        info->attachments_list = g_list_copy ((GList *) attachments_list);
        g_list_foreach (info->attachments_list, (GFunc) g_object_ref, NULL);
+       info->images_list = g_list_copy ((GList *) images_list);
+       g_list_foreach (info->images_list, (GFunc) g_object_ref, NULL);
        info->priority_flags = priority_flags;
 
        info->callback = callback;
@@ -778,6 +790,7 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
                                     const gchar *subject, const gchar *plain_body,
                                     const gchar *html_body,
                                     const GList *attachments_list,
+                                    const GList *images_list,
                                     TnyHeaderFlags priority_flags)
 {
        ModestMailOperationPrivate *priv = NULL;
@@ -805,7 +818,7 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
        if (draft_msg)
                g_object_ref (draft_msg);
        modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body,
-                                         attachments_list, priority_flags,
+                                         attachments_list, images_list, priority_flags,
                                          modest_mail_operation_send_new_mail_cb, info);
 
 }
@@ -823,7 +836,7 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self,
                                         gpointer userdata)
 {
        TnyFolder *src_folder = NULL;
-       TnyFolder *folder = NULL;
+       TnyFolder *drafts = NULL;
        TnyHeader *header = NULL;
        ModestMailOperationPrivate *priv = NULL;
        SaveToDraftsInfo *info = (SaveToDraftsInfo *) userdata;
@@ -837,8 +850,9 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self,
                goto end;
        }
 
-       folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_DRAFTS);
-       if (!folder) {
+       drafts = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), 
+                                                       TNY_FOLDER_TYPE_DRAFTS);
+       if (!drafts) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
                             MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
@@ -847,19 +861,18 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self,
        }
 
        if (!priv->error)
-               tny_folder_add_msg (folder, msg, &(priv->error));
+               tny_folder_add_msg (drafts, msg, &(priv->error));
 
        if ((!priv->error) && (info->draft_msg != NULL)) {
                header = tny_msg_get_header (info->draft_msg);
                src_folder = tny_header_get_folder (header); 
 
-               /* Remove the old draft expunging it */
+               /* Remove the old draft */
                tny_folder_remove_msg (src_folder, header, NULL);
-/*             tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED); */
-/*             tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); */
 
-               tny_folder_sync (folder, TRUE, &(priv->error)); /* FALSE --> don't expunge */
-               tny_folder_sync_async (src_folder, TRUE, NULL, NULL, NULL);  /* expunge */
+               /* Synchronize to expunge and to update the msg counts */
+               tny_folder_sync_async (drafts, TRUE, NULL, NULL, NULL);
+               tny_folder_sync_async (src_folder, TRUE, NULL, NULL, NULL);
 
                g_object_unref (header);
        }
@@ -874,8 +887,8 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self,
 
 
 end:
-       if (folder)
-               g_object_unref (G_OBJECT(folder));
+       if (drafts)
+               g_object_unref (G_OBJECT(drafts));
        if (src_folder)
                g_object_unref (G_OBJECT(src_folder));
        if (info->edit_window)
@@ -899,6 +912,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self,
                                      const gchar *subject, const gchar *plain_body,
                                      const gchar *html_body,
                                      const GList *attachments_list,
+                                     const GList *images_list,
                                      TnyHeaderFlags priority_flags)
 {
        ModestMailOperationPrivate *priv = NULL;
@@ -922,7 +936,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self,
                g_object_ref (edit_window);
 
        modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body,
-                                         attachments_list, priority_flags,
+                                         attachments_list, images_list, priority_flags,
                                          modest_mail_operation_save_to_drafts_cb, info);
 
 }
@@ -938,7 +952,7 @@ typedef struct
        gchar *account_name;
        UpdateAccountCallback callback;
        gpointer user_data;
-       gint new_headers;
+       TnyList *new_headers;
 } UpdateAccountInfo;
 
 typedef struct
@@ -1150,7 +1164,7 @@ set_last_updated_idle (gpointer data)
 {
 
        /* This is a GDK lock because we are an idle callback and
-        * modest_account_mgr_set_int can contain Gtk+ code */
+        * modest_account_mgr_set_last_updated can issue Gtk+ code */
 
        gdk_threads_enter (); /* CHECKED - please recheck */
 
@@ -1158,11 +1172,9 @@ set_last_updated_idle (gpointer data)
           the time when this idle was called, it's just an
           approximation and it won't be very different */
 
-       modest_account_mgr_set_int (modest_runtime_get_account_mgr (), 
-                                   (gchar *) data, 
-                                   MODEST_ACCOUNT_LAST_UPDATED, 
-                                   time(NULL), 
-                                   TRUE);
+       modest_account_mgr_set_last_updated (modest_runtime_get_account_mgr (), 
+                                            (gchar *) data, 
+                                            time (NULL));
 
        gdk_threads_leave (); /* CHECKED - please recheck */
 
@@ -1187,56 +1199,33 @@ idle_update_account_cb (gpointer data)
 
        /* Frees */
        g_object_unref (idle_info->mail_op);
+       if (idle_info->new_headers)
+               g_object_unref (idle_info->new_headers);
        g_free (idle_info);
 
        return FALSE;
 }
 
-
-static gpointer
-update_account_thread (gpointer thr_user_data)
+static TnyList *
+get_all_folders_from_account (TnyStoreAccount *account,
+                             GError **error)
 {
-       static gboolean first_time = TRUE;
-       UpdateAccountInfo *info = NULL;
        TnyList *all_folders = NULL;
-       GPtrArray *new_headers = NULL;
        TnyIterator *iter = NULL;
        TnyFolderStoreQuery *query = NULL;
-       ModestMailOperationPrivate *priv = NULL;
-       ModestTnySendQueue *send_queue = NULL;
-       gint num_new_headers = 0;
-
-       info = (UpdateAccountInfo *) thr_user_data;
-       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
 
-       /* Get account and set it into mail_operation */
-       priv->account = g_object_ref (info->account);
-
-       /*
-        * Previousl, we did this for POP3, to do a logout-login upon send/receive, 
-        * because many POP-servers (like Gmail) do not
-        * show any updates unless we do that.
-        * But that didn't work with gmail anyway, 
-        * and tinymail now takes care of this itself by disconnecting 
-        * automatically after using the connection.
-        */
-       /*
-       if (!first_time && TNY_IS_CAMEL_POP_STORE_ACCOUNT (priv->account)) 
-               tny_camel_pop_store_account_reconnect (TNY_CAMEL_POP_STORE_ACCOUNT(priv->account));
-       */
-
-       /* Get all the folders. We can do it synchronously because
-          we're already running in a different thread than the UI */
        all_folders = tny_simple_list_new ();
        query = tny_folder_store_query_new ();
        tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
-       tny_folder_store_get_folders (TNY_FOLDER_STORE (info->account),
+       tny_folder_store_get_folders (TNY_FOLDER_STORE (account),
                                      all_folders,
                                      query,
-                                     &(priv->error));
-       if (priv->error) {
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               goto out;
+                                     error);
+
+       if (*error) {
+               if (all_folders)
+                       g_object_unref (all_folders);
+               return NULL;
        }
 
        iter = tny_list_create_iterator (all_folders);
@@ -1250,140 +1239,158 @@ update_account_thread (gpointer thr_user_data)
        }
        g_object_unref (G_OBJECT (iter));
 
+       return all_folders;
+}
+
+
+static gpointer
+update_account_thread (gpointer thr_user_data)
+{
+       static gboolean first_time = TRUE;
+       UpdateAccountInfo *info = NULL;
+       TnyList *all_folders = NULL, *new_headers = NULL;
+       GPtrArray *new_headers_array = NULL;
+       TnyIterator *iter = NULL;
+       ModestMailOperationPrivate *priv = NULL;
+       ModestTnySendQueue *send_queue = NULL;
+       gint i = 0, timeout = 0;
+
+       info = (UpdateAccountInfo *) thr_user_data;
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
+
+       /* Get account and set it into mail_operation */
+       priv->account = g_object_ref (info->account);
+
+       /* Get all the folders. We can do it synchronously because
+          we're already running in a different thread than the UI */
+       all_folders = get_all_folders_from_account (info->account, &(priv->error));
+       if (!all_folders) {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               goto out;
+       }
+
        /* Update status and notify. We need to call the notification
           with a source function in order to call it from the main
           loop. We need that in order not to get into trouble with
           Gtk+. We use a timeout in order to provide more status
           information, because the sync tinymail call does not
           provide it for the moment */
-       gint timeout = g_timeout_add (100, idle_notify_progress, info->mail_op);
+       timeout = g_timeout_add (100, idle_notify_progress, info->mail_op);
 
-       /* Refresh folders */
-       num_new_headers = 0;
-       new_headers = g_ptr_array_new ();
+       new_headers_array = g_ptr_array_new ();
        iter = tny_list_create_iterator (all_folders);
 
        while (!tny_iterator_is_done (iter) && !priv->error && 
               priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
 
-               InternalFolderObserver *observer;
-               TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
+               TnyFolderType folder_type;
+               TnyFolder *folder = NULL;
 
-               /* Refresh the folder */
-               /* Our observer receives notification of new emails during folder refreshes,
-                * so we can use observer->new_headers.
-                */
-               observer = g_object_new (internal_folder_observer_get_type (), NULL);
-               tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer));
-               
-               /* This gets the status information (headers) from the server.
-                * We use the blocking version, because we are already in a separate 
-                * thread.
-                */
+               folder = TNY_FOLDER (tny_iterator_get_current (iter));
+               folder_type = tny_folder_get_folder_type (folder);
 
-               if (!g_ascii_strcasecmp (info->retrieve_type, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES) || 
-                   !g_ascii_strcasecmp (info->retrieve_type, MODEST_ACCOUNT_RETRIEVE_VALUE_MESSAGES_AND_ATTACHMENTS)) {
-                       TnyIterator *iter;
+               /* Refresh it only if it's the INBOX */
+               if (folder_type == TNY_FOLDER_TYPE_INBOX) {
+                       InternalFolderObserver *observer = NULL;
+                       TnyIterator *new_headers_iter = NULL;
 
-                       /* If the retrieve type is full messages, refresh and get the messages */
+                       /* Refresh the folder. Our observer receives
+                        * the new emails during folder refreshes, so
+                        * we can use observer->new_headers
+                        */
+                       observer = g_object_new (internal_folder_observer_get_type (), NULL);
+                       tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer));
+               
                        tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
 
-                       iter = tny_list_create_iterator (observer->new_headers);
-                       while (!tny_iterator_is_done (iter)) {
-                               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
-                                
+                       new_headers_iter = tny_list_create_iterator (observer->new_headers);
+                       while (!tny_iterator_is_done (new_headers_iter)) {
+                               TnyHeader *header = NULL;
+
+                               header = TNY_HEADER (tny_iterator_get_current (new_headers_iter));
                                /* Apply per-message size limits */
                                if (tny_header_get_message_size (header) < info->max_size)
-                                       g_ptr_array_add (new_headers, g_object_ref (header));
-
+                                       g_ptr_array_add (new_headers_array, g_object_ref (header));
+                               
                                g_object_unref (header);
-                               tny_iterator_next (iter);
+                               tny_iterator_next (new_headers_iter);
                        }
-                       g_object_unref (iter);
+                       g_object_unref (new_headers_iter);
+
+                       tny_folder_remove_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer));
+                       g_object_unref (observer);
                } else {
-                       /* We do not need to do it the first time
+                       /* We no not need to do it the first time,
                           because it's automatically done by the tree
                           model */
-                       if (G_UNLIKELY (!first_time))
-                               tny_folder_poke_status (TNY_FOLDER (folder));
+                       if (G_LIKELY (!first_time))
+                               tny_folder_poke_status (folder);
                }
-
-               tny_folder_remove_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer));
-               g_object_unref (observer);
-               observer = NULL;                        
-
-               if (folder)
-                       g_object_unref (G_OBJECT (folder));
-
-               if (priv->error)
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               g_object_unref (folder);
 
                tny_iterator_next (iter);
        }
-
        g_object_unref (G_OBJECT (iter));
        g_source_remove (timeout);
 
        if (priv->status != MODEST_MAIL_OPERATION_STATUS_CANCELED && 
            priv->status != MODEST_MAIL_OPERATION_STATUS_FAILED &&
-           new_headers->len > 0) {
+           new_headers_array->len > 0) {
                gint msg_num = 0;
 
                /* Order by date */
-               g_ptr_array_sort (new_headers, (GCompareFunc) compare_headers_by_date);
-
-               /* Apply message count limit */
-               /* If the number of messages exceeds the maximum, ask the
-                * user to download them all,
-                * as per the UI spec "Retrieval Limits" section in 4.4: 
-                */
-               if (new_headers->len > info->retrieve_limit) {
-                       /* TODO: Ask the user, instead of just
-                        * failing, showing
-                        * mail_nc_msg_count_limit_exceeded, with 'Get
-                        * all' and 'Newest only' buttons. */
-                       g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_RETRIEVAL_NUMBER_LIMIT,
-                            "The number of messages to retrieve exceeds the chosen limit for account %s\n", 
-                            tny_account_get_name (TNY_ACCOUNT (info->transport_account)));
-                       priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-                       goto out;
+               g_ptr_array_sort (new_headers_array, (GCompareFunc) compare_headers_by_date);
+
+               /* TODO: Ask the user, instead of just failing,
+                * showing mail_nc_msg_count_limit_exceeded, with 'Get
+                * all' and 'Newest only' buttons. */
+               if (new_headers_array->len > info->retrieve_limit) {
+                       /* TODO */
                }
-               
-               priv->done = 0;
-               priv->total = MIN (new_headers->len, info->retrieve_limit);
-               while (msg_num < priv->total) {
-
-                       TnyHeader *header = TNY_HEADER (g_ptr_array_index (new_headers, msg_num));
-                       TnyFolder *folder = tny_header_get_folder (header);
-                       TnyMsg *msg       = tny_folder_get_msg (folder, header, NULL);
-                       ModestMailOperationState *state;
-                       ModestPair* pair;
-
-                       priv->done++;
-                       /* We can not just use the mail operation because the
-                          values of done and total could change before the
-                          idle is called */
-                       state = modest_mail_operation_clone_state (info->mail_op);
-                       pair = modest_pair_new (g_object_ref (info->mail_op), state, FALSE);
-                       g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_notify_progress_once,
-                                        pair, (GDestroyNotify) modest_pair_free);
-
-                       g_object_unref (msg);
-                       g_object_unref (folder);
 
-                       msg_num++;
+               /* Should be get only the headers or the message as well? */
+               if (g_ascii_strcasecmp (info->retrieve_type, 
+                                       MODEST_ACCOUNT_RETRIEVE_VALUE_HEADERS_ONLY) != 0) {     
+                       priv->done = 0;
+                       priv->total = MIN (new_headers_array->len, info->retrieve_limit);
+                       while (msg_num < priv->total) {
+
+                               TnyHeader *header = TNY_HEADER (g_ptr_array_index (new_headers_array, msg_num));
+                               TnyFolder *folder = tny_header_get_folder (header);
+                               TnyMsg *msg       = tny_folder_get_msg (folder, header, NULL);
+                               ModestMailOperationState *state;
+                               ModestPair* pair;
+
+                               priv->done++;
+                               /* We can not just use the mail operation because the
+                                  values of done and total could change before the
+                                  idle is called */
+                               state = modest_mail_operation_clone_state (info->mail_op);
+                               pair = modest_pair_new (g_object_ref (info->mail_op), state, FALSE);
+                               g_idle_add_full (G_PRIORITY_HIGH_IDLE, idle_notify_progress_once,
+                                                pair, (GDestroyNotify) modest_pair_free);
+
+                               g_object_unref (msg);
+                               g_object_unref (folder);
+
+                               msg_num++;
+                       }
                }
        }
 
-       /* Get the number of new headers and free them */
-       num_new_headers = new_headers->len;
-       g_ptr_array_foreach (new_headers, (GFunc) g_object_unref, NULL);
-       g_ptr_array_free (new_headers, FALSE);
-       
        if (priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED)
                goto out;
 
+       /* Copy the headers to a list and free the array */
+       new_headers = tny_simple_list_new ();
+       for (i=0; i < new_headers_array->len; i++) {
+               TnyHeader *header = TNY_HEADER (g_ptr_array_index (new_headers_array, i));
+               tny_list_append (new_headers, G_OBJECT (header));
+       }
+       g_ptr_array_foreach (new_headers_array, (GFunc) g_object_unref, NULL);
+       g_ptr_array_free (new_headers_array, FALSE);
+       
+
        /* Perform send (if operation was not cancelled) */
        priv->done = 0;
        priv->total = 0;
@@ -1421,7 +1428,7 @@ update_account_thread (gpointer thr_user_data)
                /* This thread is not in the main lock */
                idle_info = g_malloc0 (sizeof (UpdateAccountInfo));
                idle_info->mail_op = g_object_ref (info->mail_op);
-               idle_info->new_headers = num_new_headers;
+               idle_info->new_headers = (new_headers) ? g_object_ref (new_headers) : NULL;
                idle_info->callback = info->callback;
                idle_info->user_data = info->user_data;
                g_idle_add (idle_update_account_cb, idle_info);
@@ -1433,8 +1440,10 @@ update_account_thread (gpointer thr_user_data)
        g_idle_add (idle_notify_queue, g_object_ref (info->mail_op));
 
        /* Frees */
-       g_object_unref (query);
-       g_object_unref (all_folders);
+       if (new_headers)
+               g_object_unref (new_headers);
+       if (all_folders)
+               g_object_unref (all_folders);
        g_object_unref (info->account);
        g_object_unref (info->transport_account);
        g_free (info->retrieve_type);
@@ -1469,19 +1478,12 @@ modest_mail_operation_update_account (ModestMailOperation *self,
        priv->done  = 0;
        priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
 
-       /* Get the Modest account */
+       /* Get the store account */
        store_account = (TnyStoreAccount *)
                modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
                                                                     account_name,
                                                                     TNY_ACCOUNT_TYPE_STORE);
                                                                     
-       /* Make sure that we have a connection, and request one 
-        * if necessary:
-        * TODO: Is there some way to trigger this for every attempt to 
-        * use the network? */
-       if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account)))
-               goto error;
-
        if (!store_account) {
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
                             MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
@@ -1520,12 +1522,10 @@ modest_mail_operation_update_account (ModestMailOperation *self,
 
        /* Get per-account retrieval type */
        mgr = modest_runtime_get_account_mgr ();
-       info->retrieve_type = modest_account_mgr_get_string (mgr, account_name, 
-                                                            MODEST_ACCOUNT_RETRIEVE, FALSE);
+       info->retrieve_type = modest_account_mgr_get_retrieve_type (mgr, account_name);
 
        /* Get per-account message amount retrieval limit */
-       info->retrieve_limit = modest_account_mgr_get_int (mgr, account_name, 
-                                                          MODEST_ACCOUNT_LIMIT_RETRIEVE, FALSE);
+       info->retrieve_limit = modest_account_mgr_get_retrieve_limit (mgr, account_name);
        if (info->retrieve_limit == 0)
                info->retrieve_limit = G_MAXINT;
                
@@ -1540,9 +1540,14 @@ modest_mail_operation_update_account (ModestMailOperation *self,
        return TRUE;
 
  error:
+       if (store_account)
+               g_object_unref (store_account);
+       if (transport_account)
+               g_object_unref (transport_account);
        priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-       if (callback) 
-               callback (self, 0, user_data);
+       if (callback) {
+               callback (self, NULL, user_data);
+       }
        modest_mail_operation_notify_end (self);
        return FALSE;
 }
@@ -1747,7 +1752,7 @@ transfer_folder_cb (TnyFolder *folder,
                 * which is already GDK locked by Tinymail */
 
                /* no gdk_threads_enter (), CHECKED */
-               helper->user_callback (priv->source, helper->user_data);
+               helper->user_callback (self, helper->user_data);
                /* no gdk_threads_leave () , CHECKED */
        }
 
@@ -1797,37 +1802,12 @@ new_name_valid_if_local_account (ModestMailOperationPrivate *priv,
                return TRUE;
 }
 
-/**
- * This function checks if @ancestor is an acestor of @folder and
- * returns TRUE in that case
- */
-static gboolean
-folder_is_ancestor (TnyFolder *folder,
-                   TnyFolderStore *ancestor)
-{
-       TnyFolder *tmp = NULL;
-       gboolean found = FALSE;
-
-       tmp = folder;
-       while (!found && tmp && !TNY_IS_ACCOUNT (tmp)) {
-               TnyFolderStore *folder_store;
-
-               folder_store = tny_folder_get_folder_store (tmp);
-               if (ancestor == folder_store)
-                       found = TRUE;
-               else
-                       tmp = g_object_ref (folder_store);
-               g_object_unref (folder_store);
-       }
-       return found;
-}
-
 void
 modest_mail_operation_xfer_folder (ModestMailOperation *self,
                                   TnyFolder *folder,
                                   TnyFolderStore *parent,
                                   gboolean delete_original,
-                                  XferMsgsAsynUserCallback user_callback,
+                                  XferAsyncUserCallback user_callback,
                                   gpointer user_data)
 {
        ModestMailOperationPrivate *priv = NULL;
@@ -1844,9 +1824,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
        folder_name = tny_folder_get_name (folder);
 
        /* Set the error msg */
-       error_msg = (delete_original) ? 
-               _("mail_in_ui_folder_move_target_error") : 
-               _("mail_in_ui_folder_copy_target_error");
+       error_msg = _("mail_in_ui_folder_move_target_error");
 
        /* Get account and set it into mail_operation */
        priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
@@ -1857,89 +1835,65 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
        if (TNY_IS_FOLDER (parent))
                parent_rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
        
-       /* The moveable restriction is applied also to copy operation */
+       /* Apply operation constraints */
        if ((gpointer) parent == (gpointer) folder ||
            (!TNY_IS_FOLDER_STORE (parent)) || 
            (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE)) {
-
-               /* Set status failed and set an error */
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
-                            error_msg);
-
-               /* Notify the queue */
-               modest_mail_operation_notify_end (self);
-
+               /* Folder rules */
+               goto error;
        } else if (TNY_IS_FOLDER (parent) && 
                   (parent_rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)) {
-
-               /* Set status failed and set an error */
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
-                            error_msg);
-
-               /* Notify the queue */
-               modest_mail_operation_notify_end (self);
+               /* Folder rules */
+               goto error;
 
        } else if (TNY_IS_FOLDER (parent) &&
                   TNY_IS_FOLDER_STORE (folder) &&
-                  folder_is_ancestor (TNY_FOLDER (parent), TNY_FOLDER_STORE (folder))) {
-               /* Set status failed and set an error */
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
-                            error_msg);
-
-               /* Notify the queue */
-               modest_mail_operation_notify_end (self);
-
+                  modest_tny_folder_is_ancestor (TNY_FOLDER (parent), 
+                                                 TNY_FOLDER_STORE (folder))) {
+               /* Do not move a parent into a child */
+               goto error;
        } else if (TNY_IS_FOLDER_STORE (parent) &&
                   modest_tny_folder_has_subfolder_with_name (parent, folder_name)) {
                /* Check that the new folder name is not used by any
-                   parent subfolder */
-
-               /* Set status failed and set an error */
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
-                            error_msg);
-
-               /* Notify the queue */
-               modest_mail_operation_notify_end (self);
-               
+                  parent subfolder */
+               goto error;     
        } else if (!(new_name_valid_if_local_account (priv, parent, folder_name))) {
                /* Check that the new folder name is not used by any
                   special local folder */
-
-               /* Set status failed and set an error */
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
-                            error_msg);
-
-               /* Notify the queue */
-               modest_mail_operation_notify_end (self);
+               goto error;
        } else {
                /* Create the helper */
                helper = g_slice_new0 (XFerMsgAsyncHelper);
-               helper->mail_op = g_object_ref(self);
+               helper->mail_op = g_object_ref (self);
                helper->dest_folder = NULL;
                helper->headers = NULL;
                helper->user_callback = user_callback;
                helper->user_data = user_data;
                
-               /* Move/Copy folder */          
+               /* Move/Copy folder */
                tny_folder_copy_async (folder,
                                       parent,
                                       tny_folder_get_name (folder),
                                       delete_original,
                                       transfer_folder_cb,
                                       transfer_folder_status_cb,
-                                      helper);         
-       } 
-       
+                                      helper);
+               return;
+       }
+
+ error:
+       /* Set status failed and set an error */
+       priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+       g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                    MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
+                    error_msg);
+
+       /* Call the user callback if exists */
+       if (user_callback)
+               user_callback (self, user_data);
+
+       /* Notify the queue */
+       modest_mail_operation_notify_end (self);
 }
 
 void
@@ -2487,16 +2441,12 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
        /* remove message from folder */
        tny_folder_remove_msgs (folder, headers, &(priv->error));
        if (!priv->error) {
-               if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
-/*                     tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
-                       tny_folder_sync (folder, FALSE, &(priv->error)); /* FALSE --> don't expunge */
-               else if (TNY_IS_CAMEL_POP_FOLDER (folder))
-/*                     tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
-                       tny_folder_sync (folder, TRUE, &(priv->error)); /* TRUE --> expunge */
+               if (TNY_IS_CAMEL_IMAP_FOLDER (folder) || 
+                   TNY_IS_CAMEL_POP_FOLDER (folder))
+                       tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /* FALSE --> don't expunge */ 
                else
                        /* local folders */
-/*                     tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
-                       tny_folder_sync (folder, TRUE, &(priv->error)); /* TRUE --> expunge */
+                       tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /* TRUE --> expunge */
        }
        
        
@@ -2613,7 +2563,7 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u
                 * Tinymail already acquires the Gdk lock */
 
                /* no gdk_threads_enter (), CHECKED */
-               helper->user_callback (priv->source, helper->user_data);
+               helper->user_callback (self, helper->user_data);
                /* no gdk_threads_leave (), CHECKED */
        }
 
@@ -2628,8 +2578,7 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u
                g_object_unref (folder);
        if (iter)
                g_object_unref (iter);
-       g_slice_free   (XFerMsgAsyncHelper, helper);
-
+       g_slice_free (XFerMsgAsyncHelper, helper);
 }
 
 void
@@ -2637,7 +2586,7 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
                                 TnyList *headers, 
                                 TnyFolder *folder, 
                                 gboolean delete_original,
-                                XferMsgsAsynUserCallback user_callback,
+                                XferAsyncUserCallback user_callback,
                                 gpointer user_data)
 {
        ModestMailOperationPrivate *priv = NULL;
@@ -2646,9 +2595,6 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
        XFerMsgAsyncHelper *helper = NULL;
        TnyHeader *header = NULL;
        ModestTnyFolderRules rules = 0;
-       const gchar *id1 = NULL;
-       const gchar *id2 = NULL;
-       gboolean same_folder = FALSE;
 
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_LIST (headers));
@@ -2683,10 +2629,7 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
        g_object_unref (iter);
 
        /* Check folder source and destination */
-       id1 = tny_folder_get_id (src_folder);
-       id2 = tny_folder_get_id (TNY_FOLDER(folder));
-       same_folder = !g_ascii_strcasecmp (id1, id2);
-       if (same_folder) {
+       if (src_folder == folder) {
                /* Set status failed and set an error */
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,