* Migrated Modest to the new send queue API
[modest] / src / modest-mail-operation.c
index 32b2c78..15a6307 100644 (file)
@@ -160,18 +160,25 @@ typedef struct _RefreshAsyncHelper {
        gpointer user_data;
 } RefreshAsyncHelper;
 
-typedef struct _XFerMsgAsyncHelper
+typedef struct _XFerMsgsAsyncHelper
 {
        ModestMailOperation *mail_op;
        TnyList *headers;
        TnyFolder *dest_folder;
-       XferAsyncUserCallback user_callback;    
+       XferMsgsAsyncUserCallback user_callback;        
        gboolean delete;
        gpointer user_data;
        gint last_total_bytes;
        gint sum_total_bytes;
        gint total_bytes;
-} XFerMsgAsyncHelper;
+} XFerMsgsAsyncHelper;
+
+typedef struct _XFerFolderAsyncHelper
+{
+       ModestMailOperation *mail_op;
+       XferFolderAsyncUserCallback user_callback;      
+       gpointer user_data;
+} XFerFolderAsyncHelper;
 
 typedef void (*ModestMailOperationCreateMsgCallback) (ModestMailOperation *mail_op,
                                                      TnyMsg *msg,
@@ -499,21 +506,18 @@ modest_mail_operation_cancel (ModestMailOperation *self)
        /* Set new status */
        priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
        
-       /* Cancel the mail operation. We need to wrap it between this
-          start/stop operations to allow following calls to the
-          account */
+       /* Cancel the mail operation */
        g_return_val_if_fail (priv->account, FALSE);
+       tny_account_cancel (priv->account);
 
        if (priv->op_type == MODEST_MAIL_OPERATION_TYPE_SEND) {
                ModestTnySendQueue *queue;
                queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (priv->account));
-               /* Cancel sending without removing the item */
-               tny_send_queue_cancel (TNY_SEND_QUEUE (queue), FALSE, NULL);
-       } else {
-               /* Cancel operation */
-               tny_account_cancel (priv->account);
-       }
 
+               /* Cancel the sending of the following next messages */
+               tny_send_queue_cancel (TNY_SEND_QUEUE (queue), TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, NULL);
+       }
+       
        return canceled;
 }
 
@@ -635,20 +639,21 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
        } else {
                /* Add the msg to the queue */
                modest_mail_operation_notify_start (self);
-               modest_tny_send_queue_add (MODEST_TNY_SEND_QUEUE(send_queue), 
-                                          msg, 
-                                          &(priv->error));
-
-               priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
 
                info = g_slice_new0 (SendMsgInfo);
 
                info->mail_op = g_object_ref (self);
                info->msg = g_object_ref (msg);
                info->msg_sent_handler = g_signal_connect (G_OBJECT (send_queue), "msg-sent",
-                                                          G_CALLBACK (send_mail_msg_sent_handler), info);
+                               G_CALLBACK (send_mail_msg_sent_handler), info);
                info->error_happened_handler = g_signal_connect (G_OBJECT (send_queue), "error-happened",
-                                                                G_CALLBACK (send_mail_error_happened_handler), info);
+                               G_CALLBACK (send_mail_error_happened_handler), info);
+
+               modest_tny_send_queue_add (MODEST_TNY_SEND_QUEUE(send_queue), 
+                               msg, 
+                               &(priv->error));
+
+               priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
        }
 
 }
@@ -698,6 +703,11 @@ send_mail_error_happened_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg
        SendMsgInfo *info = (SendMsgInfo *) userdata;
        TnyHeader *hdr1, *hdr2;
        const char *msgid1, *msgid2;
+
+       if (!TNY_IS_MSG(msg)) {
+               g_warning ("%s: did not receive a valid msg", __FUNCTION__);
+               return;
+       }
        
        hdr1 = tny_msg_get_header(msg);
        hdr2 = tny_msg_get_header(info->msg);
@@ -859,7 +869,7 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self,
        SendNewMailInfo *info = (SendNewMailInfo *) userdata;
        TnyFolder *draft_folder = NULL;
        TnyFolder *outbox_folder = NULL;
-       TnyHeader *header;
+       TnyHeader *header = NULL;
        GError *err = NULL;
 
        if (!msg) {
@@ -869,15 +879,37 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self,
        /* Call mail operation */
        modest_mail_operation_send_mail (self, info->transport_account, msg);
 
-       /* Remove old mail from its source folder */
-       draft_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account),
-                                                             TNY_FOLDER_TYPE_DRAFTS);
-       outbox_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account),
-                                                              TNY_FOLDER_TYPE_OUTBOX);
        if (info->draft_msg != NULL) {
                TnyFolder *folder = NULL;
                TnyFolder *src_folder = NULL;
                TnyFolderType folder_type;              
+               TnyTransportAccount *transport_account = NULL;
+
+               /* To remove the old mail from its source folder, we need to get the
+                * transport account of the original draft message (the transport account
+                * might have been changed by the user) */
+               header = tny_msg_get_header (info->draft_msg);
+               transport_account = modest_tny_account_store_get_transport_account_from_outbox_header(
+                       modest_runtime_get_account_store(), header);
+               if (transport_account == NULL)
+                       transport_account = g_object_ref(info->transport_account);
+               draft_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account),
+                                                                     TNY_FOLDER_TYPE_DRAFTS);
+               outbox_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account),
+                                                                      TNY_FOLDER_TYPE_OUTBOX);
+               g_object_unref(transport_account);
+
+               if (!draft_folder) {
+                       g_warning ("%s: modest_tny_account_get_special_folder(..) returned a NULL drafts folder",
+                                  __FUNCTION__);
+                       goto end;
+               }
+               if (!outbox_folder) {
+                       g_warning ("%s: modest_tny_account_get_special_folder(..) returned a NULL outbox folder",
+                                  __FUNCTION__);
+                       goto end;
+               }
+
                folder = tny_msg_get_folder (info->draft_msg);          
                if (folder == NULL) goto end;
                folder_type = modest_tny_folder_guess_folder_type (folder);
@@ -892,17 +924,17 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self,
 
                /* Note: This can fail (with a warning) if the message is not really already in a folder,
                 * because this function requires it to have a UID. */          
-               header = tny_msg_get_header (info->draft_msg);
                tny_folder_remove_msg (src_folder, header, NULL);
 
                tny_folder_sync (folder, TRUE, &err); /* FALSE --> don't expunge */
 /*             tny_folder_sync_async (src_folder, TRUE, NULL, NULL, NULL);  /\* expunge *\/ */
                
-               g_object_unref (header);
                g_object_unref (folder);
        }
 
 end:
+       if (header)
+               g_object_unref (header);
        if (err != NULL)
                g_error_free(err);      
        if (info->draft_msg)
@@ -1025,10 +1057,10 @@ modest_mail_operation_save_to_drafts_add_msg_cb(TnyFolder *self,
                g_object_unref (G_OBJECT(info->drafts));
        if (info->msg)
                g_object_unref (G_OBJECT (info->msg));
-       g_slice_free (SaveToDraftsAddMsgInfo, info);
 
        modest_mail_operation_notify_end (info->mailop);
        g_object_unref(info->mailop);
+       g_slice_free (SaveToDraftsAddMsgInfo, info);
 }
 
 typedef struct
@@ -1051,13 +1083,15 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self,
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
 
        if (!msg) {
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED,
-                            "modest: failed to create a new msg\n");
+               if (!(priv->error)) {
+                       g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                                    MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED,
+                                    "modest: failed to create a new msg\n");
+               }
        } else {
                drafts = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account),
                                                                TNY_FOLDER_TYPE_DRAFTS);
-               if (!drafts) {
+               if (!drafts && !(priv->error)) {
                        g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
                                     MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
                                     "modest: failed to create a new msg\n");
@@ -1260,6 +1294,61 @@ update_account_get_msg_async_cb (TnyFolder *folder,
        g_slice_free (GetMsgInfo, msg_info);
 }
 
+typedef struct {
+       guint error_handler;
+       guint sent_handler;
+       ModestMailOperation *mail_op;
+} UpdateAccountSendQueueFlushInfo;
+
+static void
+update_account_finalize (TnySendQueue *queue,
+                        UpdateAccountSendQueueFlushInfo *info)
+{
+       ModestMailOperationPrivate *priv;
+
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
+       priv->done++;
+
+       /* The last one finish the mail operation */
+       if (priv->done == priv->total) {
+               /* Notify end */
+               modest_mail_operation_notify_end (info->mail_op);
+               
+               /* Free */
+               g_object_unref (info->mail_op);
+               g_signal_handler_disconnect (queue, info->error_handler);
+               g_signal_handler_disconnect (queue, info->sent_handler);
+               g_slice_free (UpdateAccountSendQueueFlushInfo, info);
+       }
+}
+
+static void
+update_account_on_msg_sent_cb (TnySendQueue *queue, 
+                              TnyHeader *header, 
+                              TnyMsg *msg,
+                              guint nth, 
+                              guint total, 
+                              gpointer user_data)
+{
+       UpdateAccountSendQueueFlushInfo *info;
+       info = (UpdateAccountSendQueueFlushInfo *) user_data;
+
+       update_account_finalize (queue, info);
+}
+
+static void     
+update_account_on_error_happened_cb (TnySendQueue *queue, 
+                                    TnyHeader *header, 
+                                    TnyMsg *msg,
+                                    GError *error, 
+                                    gpointer user_data)
+{
+       UpdateAccountSendQueueFlushInfo *info;
+       info = (UpdateAccountSendQueueFlushInfo *) user_data;
+
+       update_account_finalize (queue, info);
+}
+
 
 static void
 inbox_refreshed_cb (TnyFolder *inbox, 
@@ -1277,7 +1366,7 @@ inbox_refreshed_cb (TnyFolder *inbox,
        TnyList *new_headers = NULL;
        gboolean headers_only, ignore_limit;
        TnyTransportAccount *transport_account;
-       ModestTnySendQueue *send_queue;
+       gboolean end_operation;
 
        info = (UpdateAccountInfo *) user_data;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
@@ -1388,18 +1477,54 @@ inbox_refreshed_cb (TnyFolder *inbox,
        g_ptr_array_free (new_headers_array, FALSE);
 
  send_mail:
-       /* Send mails */
-       priv->done = 0;
-       priv->total = 0;
-
        /* Get the transport account */
        transport_account = (TnyTransportAccount *)
                modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
                                                                                    info->account_name);
-       
-       /* Try to send */
-       send_queue = modest_runtime_get_send_queue (transport_account);
-       modest_tny_send_queue_try_to_send (send_queue);
+
+       if (transport_account) {
+               ModestTnySendQueue *send_queue;
+               TnyFolder *outbox;
+               guint num_messages;
+
+               send_queue = modest_runtime_get_send_queue (transport_account);
+
+               /* Get outbox folder */
+               outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (send_queue));
+               num_messages = tny_folder_get_all_count (outbox);
+               g_object_unref (outbox);
+
+               if (num_messages == 0) {
+                       end_operation = TRUE;
+               } else {
+                       UpdateAccountSendQueueFlushInfo *send_info;
+
+                       end_operation = FALSE;
+                       /* Send mails */
+                       priv->done = 0;
+                       priv->total = num_messages;
+                       g_object_unref (priv->account);
+                       priv->account = TNY_ACCOUNT (transport_account);
+
+                       /* Create the info object */
+                       send_info = g_slice_new (UpdateAccountSendQueueFlushInfo);
+                       send_info->error_handler = g_signal_connect (send_queue, "error-happened", 
+                                                                    G_CALLBACK (update_account_on_error_happened_cb), 
+                                                                    send_info);
+                       send_info->sent_handler = g_signal_connect (send_queue, "msg-sent", 
+                                                                   G_CALLBACK (update_account_on_msg_sent_cb), 
+                                                                   send_info);
+                       send_info->mail_op = g_object_ref (info->mail_op);
+
+                       /* Reenable suspended items */
+                       modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
+
+                       /* Try to send */
+                       tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
+               }
+       } else {
+               end_operation = TRUE;
+       }
 
        /* Check if the operation was a success */
        if (!priv->error)
@@ -1413,7 +1538,8 @@ inbox_refreshed_cb (TnyFolder *inbox,
                info->callback (info->mail_op, new_headers, info->user_data);
 
        /* Notify about operation end */
-       modest_mail_operation_notify_end (info->mail_op);
+       if (end_operation)
+               modest_mail_operation_notify_end (info->mail_op);
 
        /* Frees */
        if (new_headers)
@@ -1448,8 +1574,9 @@ recurse_folders_async_cb (TnyFolderStore *folder_store,
                        /* Add pending call */
                        info->pending_calls++;
                        
-                       tny_folder_store_get_folders_async (folder, folders, recurse_folders_async_cb, 
-                                                           NULL, NULL, info);
+                       tny_folder_store_get_folders_async (folder, folders, NULL,
+                                                           recurse_folders_async_cb, 
+                                                           NULL, info);
                        
                        g_object_unref (G_OBJECT (folder));
                        
@@ -1524,13 +1651,14 @@ modest_mail_operation_update_account (ModestMailOperation *self,
        ModestTnyAccountStore *account_store = NULL;
        TnyStoreAccount *store_account = NULL;
        TnyList *folders;
+       ModestMailOperationState *state;
 
        /* Init mail operation */
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
        priv->total = 0;
        priv->done  = 0;
        priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
-       priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE;
+       priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE;
 
        /* Get the store account */
        account_store = modest_runtime_get_account_store ();
@@ -1556,21 +1684,20 @@ modest_mail_operation_update_account (ModestMailOperation *self,
        modest_mail_operation_notify_start (self);
 
        /* notify about the start of the operation */ 
-       ModestMailOperationState *state;
        state = modest_mail_operation_clone_state (self);
        state->done = 0;
        state->total = 0;
 
        /* Start notifying progress */
-       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 
-                       0, state, NULL);
+       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL);
        g_slice_free (ModestMailOperationState, state);
        
-       /* Get all folders and continue in the callback */    
+       /* Get all folders and continue in the callback */ 
        folders = tny_simple_list_new ();
        tny_folder_store_get_folders_async (TNY_FOLDER_STORE (store_account),
-                               folders, recurse_folders_async_cb, 
-                               NULL, NULL, info);
+                                           folders, NULL,
+                                           recurse_folders_async_cb, 
+                                           NULL, info);
 }
 
 /*
@@ -1771,6 +1898,8 @@ modest_mail_operation_remove_folder (ModestMailOperation *self,
                                                    TNY_FOLDER_STORE (trash_folder), 
                                                    TRUE, NULL, NULL);
                        g_object_unref (trash_folder);
+               } else {
+                       g_warning ("%s: modest_tny_account_get_special_folder(..) returned a NULL trash folder", __FUNCTION__);
                }
        } else {
                TnyFolderStore *parent = tny_folder_get_folder_store (folder);
@@ -1801,12 +1930,12 @@ transfer_folder_status_cb (GObject *obj,
        ModestMailOperation *self;
        ModestMailOperationPrivate *priv;
        ModestMailOperationState *state;
-       XFerMsgAsyncHelper *helper;
+       XFerFolderAsyncHelper *helper;
 
        g_return_if_fail (status != NULL);
        g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER);
 
-       helper = (XFerMsgAsyncHelper *) user_data;
+       helper = (XFerFolderAsyncHelper *) user_data;
        g_return_if_fail (helper != NULL);
 
        self = helper->mail_op;
@@ -1838,11 +1967,11 @@ transfer_folder_cb (TnyFolder *folder,
                    GError *err, 
                    gpointer user_data)
 {
-       XFerMsgAsyncHelper *helper;
+       XFerFolderAsyncHelper *helper;
        ModestMailOperation *self = NULL;
        ModestMailOperationPrivate *priv = NULL;
 
-       helper = (XFerMsgAsyncHelper *) user_data;
+       helper = (XFerFolderAsyncHelper *) user_data;
        g_return_if_fail (helper != NULL);       
 
        self = helper->mail_op;
@@ -1873,13 +2002,13 @@ transfer_folder_cb (TnyFolder *folder,
                 * which is already GDK locked by Tinymail */
 
                /* no gdk_threads_enter (), CHECKED */
-               helper->user_callback (self, helper->user_data);
+               helper->user_callback (self, new_folder, helper->user_data);
                /* no gdk_threads_leave () , CHECKED */
        }
 
        /* Free */
        g_object_unref (helper->mail_op);
-       g_slice_free   (XFerMsgAsyncHelper, helper);
+       g_slice_free   (XFerFolderAsyncHelper, helper);
 }
 
 /**
@@ -1928,12 +2057,12 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
                                   TnyFolder *folder,
                                   TnyFolderStore *parent,
                                   gboolean delete_original,
-                                  XferAsyncUserCallback user_callback,
+                                  XferFolderAsyncUserCallback user_callback,
                                   gpointer user_data)
 {
        ModestMailOperationPrivate *priv = NULL;
        ModestTnyFolderRules parent_rules = 0, rules; 
-       XFerMsgAsyncHelper *helper = NULL;
+       XFerFolderAsyncHelper *helper = NULL;
        const gchar *folder_name = NULL;
        const gchar *error_msg;
 
@@ -1985,10 +2114,8 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
                goto error;
        } else {
                /* Create the helper */
-               helper = g_slice_new0 (XFerMsgAsyncHelper);
+               helper = g_slice_new0 (XFerFolderAsyncHelper);
                helper->mail_op = g_object_ref (self);
-               helper->dest_folder = NULL;
-               helper->headers = NULL;
                helper->user_callback = user_callback;
                helper->user_data = user_data;
                
@@ -2013,7 +2140,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
 
        /* Call the user callback if exists */
        if (user_callback)
-               user_callback (self, user_data);
+               user_callback (self, NULL, user_data);
 
        /* Notify the queue */
        modest_mail_operation_notify_end (self);
@@ -2022,11 +2149,13 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self,
 void
 modest_mail_operation_rename_folder (ModestMailOperation *self,
                                     TnyFolder *folder,
-                                    const gchar *name)
+                                    const gchar *name,
+                                    XferFolderAsyncUserCallback user_callback,
+                                    gpointer user_data)
 {
        ModestMailOperationPrivate *priv;
        ModestTnyFolderRules rules;
-       XFerMsgAsyncHelper *helper;
+       XFerFolderAsyncHelper *helper;
 
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
@@ -2041,21 +2170,9 @@ modest_mail_operation_rename_folder (ModestMailOperation *self,
        /* Check folder rules */
        rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
        if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
-               /* 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,
-                            _("FIXME: unable to rename"));
-
-               /* Notify about operation end */
-               modest_mail_operation_notify_end (self);
+               goto error;
        } else if (!strcmp (name, " ") || strchr (name, '/')) {
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
-                            _("FIXME: unable to rename"));
-               /* Notify about operation end */
-               modest_mail_operation_notify_end (self);
+               goto error;
        } else {
                TnyFolderStore *into;
 
@@ -2065,12 +2182,10 @@ modest_mail_operation_rename_folder (ModestMailOperation *self,
                   special local folder */
                if (new_name_valid_if_local_account (priv, into, name)) {
                        /* Create the helper */
-                       helper = g_slice_new0 (XFerMsgAsyncHelper);
+                       helper = g_slice_new0 (XFerFolderAsyncHelper);
                        helper->mail_op = g_object_ref(self);
-                       helper->dest_folder = NULL;
-                       helper->headers = NULL;
-                       helper->user_callback = NULL;
-                       helper->user_data = NULL;
+                       helper->user_callback = user_callback;
+                       helper->user_data = user_data;
                
                        /* Rename. Camel handles folder subscription/unsubscription */
                        modest_mail_operation_notify_start (self);
@@ -2079,10 +2194,24 @@ modest_mail_operation_rename_folder (ModestMailOperation *self,
                                               transfer_folder_status_cb,
                                               helper);
                } else {
-                       modest_mail_operation_notify_end (self);
+                       goto error;
                }
                g_object_unref (into);
+
+               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,
+                    _("FIXME: unable to rename"));
+       
+       if (user_callback)
+               user_callback (self, NULL, user_data);
+
+       /* Notify about operation end */
+       modest_mail_operation_notify_end (self);
 }
 
 /* ******************************************************************* */
@@ -2222,12 +2351,11 @@ modest_mail_operation_get_msgs_full (ModestMailOperation *self,
                                     GDestroyNotify notify)
 {
        ModestMailOperationPrivate *priv = NULL;
-       gboolean size_ok = TRUE;
-       gint max_size;
+       gint msg_list_size;
        TnyIterator *iter = NULL;
        
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
-       
+
        /* Init mail operation */
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
        priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
@@ -2254,83 +2382,43 @@ modest_mail_operation_get_msgs_full (ModestMailOperation *self,
                }
        }
 
-       /* Get msg size limit */
-       max_size  = modest_conf_get_int (modest_runtime_get_conf (), 
-                                        MODEST_CONF_MSG_SIZE_LIMIT, 
-                                        &(priv->error));
-       if (priv->error) {
-               g_clear_error (&(priv->error));
-               max_size = G_MAXINT;
-       } else {
-               max_size = max_size * KB;
-       }
-
-       /* Check message size limits. If there is only one message
-          always retrieve it */
-       if (iter != NULL) {
-               while (!tny_iterator_is_done (iter) && size_ok) {
-                       TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
-                       if (header) {
-                               if (tny_header_get_message_size (header) >= max_size)
-                                       size_ok = FALSE;
-                               g_object_unref (header);
-                       }
-
-                       tny_iterator_next (iter);
-               }
-               g_object_unref (iter);
-       }
+       msg_list_size = compute_message_list_size (header_list);
 
-       if (size_ok) {
-               const gint msg_list_size = compute_message_list_size (header_list);
+       modest_mail_operation_notify_start (self);
+       iter = tny_list_create_iterator (header_list);
+       while (!tny_iterator_is_done (iter)) {
+               /* notify about the start of the operation */
+               ModestMailOperationState *state;
+               state = modest_mail_operation_clone_state (self);
+               state->done = 0;
+               state->total = 0;
+               g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL],
+                              0, state, NULL);
 
-               modest_mail_operation_notify_start (self);
-               iter = tny_list_create_iterator (header_list);
-               while (!tny_iterator_is_done (iter)) { 
-                       /* notify about the start of the operation */ 
-                       ModestMailOperationState *state;
-                       state = modest_mail_operation_clone_state (self);
-                       state->done = 0;
-                       state->total = 0;
-                       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 
-                                       0, state, NULL);
-                       
-                       GetMsgInfo *msg_info = NULL;
-                       TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
-                       TnyFolder *folder = tny_header_get_folder (header);
-                       
-                       /* Create the message info */
-                       msg_info = g_slice_new0 (GetMsgInfo);
-                       msg_info->mail_op = g_object_ref (self);
-                       msg_info->header = g_object_ref (header);
-                       msg_info->user_callback = user_callback;
-                       msg_info->user_data = user_data;
-                       msg_info->destroy_notify = notify;
-                       msg_info->last_total_bytes = 0;
-                       msg_info->sum_total_bytes = 0;
-                       msg_info->total_bytes = msg_list_size;
-                       
-                       /* The callback will call it per each header */
-                       tny_folder_get_msg_async (folder, header, get_msg_async_cb, get_msg_status_cb, msg_info);
-                       
-                       /* Free and go on */
-                       g_object_unref (header);
-                       g_object_unref (folder);
-                       tny_iterator_next (iter);
-               }
-               g_object_unref (iter);
-       } else {
-               /* Set status failed and set an error */
-               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
-               /* FIXME: the error msg is different for pop */
-               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
-                            MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT,
-                            _("emev_ni_ui_imap_msg_size_exceed_error"));
-               /* Remove from queue and free resources */
-               modest_mail_operation_notify_end (self);
-               if (notify)
-                       notify (user_data);
+               GetMsgInfo *msg_info = NULL;
+               TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
+               TnyFolder *folder = tny_header_get_folder (header);
+
+               /* Create the message info */
+               msg_info = g_slice_new0 (GetMsgInfo);
+               msg_info->mail_op = g_object_ref (self);
+               msg_info->header = g_object_ref (header);
+               msg_info->user_callback = user_callback;
+               msg_info->user_data = user_data;
+               msg_info->destroy_notify = notify;
+               msg_info->last_total_bytes = 0;
+               msg_info->sum_total_bytes = 0;
+               msg_info->total_bytes = msg_list_size;
+
+               /* The callback will call it per each header */
+               tny_folder_get_msg_async (folder, header, get_msg_async_cb, get_msg_status_cb, msg_info);
+
+               /* Free and go on */
+               g_object_unref (header);
+               g_object_unref (folder);
+               tny_iterator_next (iter);
        }
+       g_object_unref (iter);
 }
 
 
@@ -2410,7 +2498,7 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
                                   TnyList *headers,
                                  gboolean remove_to_trash /*ignored*/)
 {
-       TnyFolder *folder;
+       TnyFolder *folder = NULL;
        ModestMailOperationPrivate *priv;
        TnyIterator *iter = NULL;
        TnyHeader *header = NULL;
@@ -2423,14 +2511,23 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
        if (remove_to_trash)
                g_warning ("remove to trash is not implemented");
 
+       if (tny_list_get_length(headers) == 0) {
+               g_warning ("%s: list of headers is empty\n", __FUNCTION__);
+               goto cleanup; /* nothing to do */
+       }
+       
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
-
        remove_headers = g_object_ref(headers);
 
        /* Get folder from first header and sync it */
-       iter = tny_list_create_iterator (headers);
+       iter = tny_list_create_iterator (headers);      
        header = TNY_HEADER (tny_iterator_get_current (iter));
-       folder = tny_header_get_folder (header);
+
+       folder = tny_header_get_folder (header);        
+       if (!TNY_IS_FOLDER(folder)) {
+               g_warning ("%s: could not get folder for header\n", __FUNCTION__);
+               goto cleanup;
+       }
 
        /* Don't remove messages that are being sent */
        if (modest_tny_folder_is_local_folder (folder)) {
@@ -2475,17 +2572,21 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
        if (!priv->error) {
                gboolean expunge, leave_on_server;
                const gchar *account_name;
+               const gchar *proto;
                TnyAccount *account;
-               ModestTransportStoreProtocol account_proto;
+               ModestTransportStoreProtocol account_proto = MODEST_PROTOCOL_TRANSPORT_STORE_UNKNOWN;
                
                account = tny_folder_get_account (folder);
                account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
                leave_on_server =
                        modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
-                                       account_name);
-
-               account_proto = modest_protocol_info_get_transport_store_protocol (tny_account_get_proto (account));
-
+                                                               account_name);
+               
+               proto = tny_account_get_proto (account);
+               if (proto) {
+                       account_proto = modest_protocol_info_get_transport_store_protocol (proto);
+               }
+               
                if (((account_proto == MODEST_PROTOCOL_STORE_POP) && !leave_on_server) ||
                    modest_tny_folder_is_remote_folder (folder) == FALSE)
                        expunge = TRUE;
@@ -2506,10 +2607,15 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
 
        /* Free */
-       g_object_unref (remove_headers);
-       g_object_unref (header);
-       g_object_unref (iter);
-       g_object_unref (G_OBJECT (folder));
+cleanup:
+       if (remove_headers)
+               g_object_unref (remove_headers);
+       if (header)
+               g_object_unref (header);
+       if (iter)
+               g_object_unref (iter);
+       if (folder)
+               g_object_unref (folder);
 
        /* Notify about operation end */
        modest_mail_operation_notify_end (self);
@@ -2525,13 +2631,18 @@ notify_progress_of_multiple_messages (ModestMailOperation *self,
 {
        ModestMailOperationPrivate *priv;
        ModestMailOperationState *state;
-       gboolean is_num_bytes;
+       gboolean is_num_bytes = FALSE;
 
        priv =  MODEST_MAIL_OPERATION_GET_PRIVATE (self);
 
        /* We know that tinymail sends us information about
-          transferred bytes with this particular message */
-       is_num_bytes = (g_ascii_strcasecmp (status->message, "Retrieving message") == 0);
+        *  transferred bytes with this particular message
+        *  
+        *  (FIXME: this is very ugly, and no I (djcb) didn't write this code,
+        *  I just added the 'if' so we don't get runtime warning)
+        */
+       if (status->message)
+               is_num_bytes = (g_ascii_strcasecmp (status->message, "Retrieving message") == 0);
 
        state = modest_mail_operation_clone_state (self);
        if (is_num_bytes && !((status->position == 1) && (status->of_total == 100))) {
@@ -2567,12 +2678,12 @@ transfer_msgs_status_cb (GObject *obj,
                         TnyStatus *status,  
                         gpointer user_data)
 {
-       XFerMsgAsyncHelper *helper;
+       XFerMsgsAsyncHelper *helper;
 
        g_return_if_fail (status != NULL);
        g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS);
 
-       helper = (XFerMsgAsyncHelper *) user_data;
+       helper = (XFerMsgsAsyncHelper *) user_data;
        g_return_if_fail (helper != NULL);       
 
        /* Notify progress */
@@ -2584,13 +2695,13 @@ transfer_msgs_status_cb (GObject *obj,
 static void
 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer user_data)
 {
-       XFerMsgAsyncHelper *helper;
+       XFerMsgsAsyncHelper *helper;
        ModestMailOperation *self;
        ModestMailOperationPrivate *priv;
        TnyIterator *iter = NULL;
        TnyHeader *header = NULL;
 
-       helper = (XFerMsgAsyncHelper *) user_data;
+       helper = (XFerMsgsAsyncHelper *) user_data;
        self = helper->mail_op;
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
@@ -2627,7 +2738,6 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u
 
                        tny_iterator_next (iter);
                }
-
        }
                
 
@@ -2655,7 +2765,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 (XFerMsgsAsyncHelper, helper);
 }
 
 static guint
@@ -2696,13 +2806,13 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
                                 TnyList *headers, 
                                 TnyFolder *folder, 
                                 gboolean delete_original,
-                                XferAsyncUserCallback user_callback,
+                                XferMsgsAsyncUserCallback user_callback,
                                 gpointer user_data)
 {
        ModestMailOperationPrivate *priv = NULL;
        TnyIterator *iter = NULL;
        TnyFolder *src_folder = NULL;
-       XFerMsgAsyncHelper *helper = NULL;
+       XFerMsgsAsyncHelper *helper = NULL;
        TnyHeader *header = NULL;
        ModestTnyFolderRules rules = 0;
 
@@ -2764,7 +2874,7 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self,
        }
 
        /* Create the helper */
-       helper = g_slice_new0 (XFerMsgAsyncHelper);
+       helper = g_slice_new0 (XFerMsgsAsyncHelper);
        helper->mail_op = g_object_ref(self);
        helper->dest_folder = g_object_ref(folder);
        helper->headers = g_object_ref(headers);
@@ -2989,3 +3099,45 @@ modest_mail_operation_noop (ModestMailOperation *self)
        modest_mail_operation_notify_start (self);
        modest_mail_operation_notify_end (self);
 }
+
+
+gchar*
+modest_mail_operation_to_string (ModestMailOperation *self)
+{
+       const gchar *type, *status, *account_id;
+       ModestMailOperationPrivate *priv = NULL;
+       
+       g_return_val_if_fail (self, NULL);
+
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
+       /* new operations don't have anything interesting */
+       if (priv->op_type == MODEST_MAIL_OPERATION_TYPE_UNKNOWN)
+               return g_strdup_printf ("%p <new operation>", self);
+       
+       switch (priv->op_type) {
+       case MODEST_MAIL_OPERATION_TYPE_SEND:    type= "SEND";    break;
+       case MODEST_MAIL_OPERATION_TYPE_RECEIVE: type= "RECEIVE"; break;
+       case MODEST_MAIL_OPERATION_TYPE_OPEN:    type= "OPEN";    break;
+       case MODEST_MAIL_OPERATION_TYPE_DELETE:  type= "DELETE";  break;
+       case MODEST_MAIL_OPERATION_TYPE_INFO:    type= "INFO";    break;
+       case MODEST_MAIL_OPERATION_TYPE_UNKNOWN: type= "UNKNOWN"; break;
+       default: type = "UNEXPECTED"; break;
+       }
+
+       switch (priv->status) {
+       case MODEST_MAIL_OPERATION_STATUS_INVALID:              status= "INVALID"; break;
+       case MODEST_MAIL_OPERATION_STATUS_SUCCESS:              status= "SUCCESS"; break;
+       case MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS: status= "FINISHED-WITH-ERRORS"; break;
+       case MODEST_MAIL_OPERATION_STATUS_FAILED:               status= "FAILED"; break;
+       case MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS:          status= "IN-PROGRESS"; break;
+       case MODEST_MAIL_OPERATION_STATUS_CANCELED:             status= "CANCELLED"; break;
+       default:                                                status= "UNEXPECTED"; break;
+       } 
+
+       account_id = priv->account ? tny_account_get_id (priv->account) : "";
+
+       return g_strdup_printf ("%p \"%s\" (%s) [%s] {%d/%d} '%s'", self, account_id,type, status,
+                               priv->done, priv->total,
+                               priv->error && priv->error->message ? priv->error->message : "");
+}