Dbus open message faster user feedback (WIP 1)
[modest] / src / modest-mail-operation.c
index 75aa517..f74f11e 100644 (file)
@@ -45,6 +45,7 @@
 #include <tny-folder-observer.h>
 #include <camel/camel-stream-mem.h>
 #include <glib/gi18n.h>
+#include <modest-defs.h>
 #include "modest-platform.h"
 #include "modest-account-mgr-helpers.h"
 #include <modest-tny-account.h>
@@ -62,6 +63,9 @@
 #include <libgnomevfs/gnome-vfs.h>
 #include "modest-utils.h"
 #include "modest-debug.h"
+#ifdef MODEST_USE_LIBTIME
+#include <clockd/libtime.h>
+#endif
 
 #define KB 1024
 
@@ -230,6 +234,7 @@ static void          modest_mail_operation_create_msg (ModestMailOperation *self
                                                       const gchar *html_body, const GList *attachments_list,
                                                       const GList *images_list,
                                                       TnyHeaderFlags priority_flags,
+                                                      const gchar *references, const gchar *in_reply_to,
                                                       ModestMailOperationCreateMsgCallback callback,
                                                       gpointer userdata);
 
@@ -242,6 +247,8 @@ typedef struct
        gchar *cc;
        gchar *bcc;
        gchar *subject;
+       gchar *references;
+       gchar *in_reply_to;
        gchar *plain_body;
        gchar *html_body;
        GList *attachments_list;
@@ -658,7 +665,7 @@ send_mail_on_sync_async_cb (TnyFolder *folder,
        self = helper->mail_op;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
 
-       if (cancelled || err)
+       if (cancelled)
                goto end;
 
        if (err) {
@@ -743,7 +750,7 @@ send_mail_on_added_to_outbox (TnySendQueue *send_queue,
        self = helper->mail_op;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
 
-       if (cancelled || err)
+       if (cancelled)
                goto end;
 
        if (err) {
@@ -761,35 +768,39 @@ send_mail_on_added_to_outbox (TnySendQueue *send_queue,
                ModestTnySendQueue *queue;
 
                trans_account = (TnyTransportAccount *) modest_mail_operation_get_account (self);
-               queue = modest_runtime_get_send_queue (trans_account, TRUE);
-               if (queue) {
-                       RunQueueHelper *helper;
-
-                       /* Create the helper */
-                       helper = g_slice_new0 (RunQueueHelper);
-                       helper->queue = g_object_ref (queue);
-                       helper->self = g_object_ref (self);
-
-                       /* if sending is ongoing wait for the queue to
-                          stop. Otherwise wait for the queue-start
-                          signal. It could happen that the queue
-                          could not start, then check also the error
-                          happened signal */
-                       if (modest_tny_send_queue_sending_in_progress (queue)) {
-                               run_queue_start (TNY_SEND_QUEUE (queue), helper);
+               if (trans_account) {
+                       queue = modest_runtime_get_send_queue (trans_account, TRUE);
+                       if (queue) {
+                               RunQueueHelper *helper;
+
+                               /* Create the helper */
+                               helper = g_slice_new0 (RunQueueHelper);
+                               helper->queue = g_object_ref (queue);
+                               helper->self = g_object_ref (self);
+
+                               /* if sending is ongoing wait for the queue to
+                                  stop. Otherwise wait for the queue-start
+                                  signal. It could happen that the queue
+                                  could not start, then check also the error
+                                  happened signal */
+                               if (modest_tny_send_queue_sending_in_progress (queue)) {
+                                       run_queue_start (TNY_SEND_QUEUE (queue), helper);
+                               } else {
+                                       helper->start_handler = g_signal_connect (queue, "queue-start", 
+                                                                                 G_CALLBACK (run_queue_start), 
+                                                                                 helper);
+                                       helper->error_handler = g_signal_connect (queue, "error-happened", 
+                                                                                 G_CALLBACK (run_queue_error_happened), 
+                                                                                 helper);
+                               }
                        } else {
-                               helper->start_handler = g_signal_connect (queue, "queue-start", 
-                                                                         G_CALLBACK (run_queue_start), 
-                                                                         helper);
-                               helper->error_handler = g_signal_connect (queue, "error-happened", 
-                                                                         G_CALLBACK (run_queue_error_happened), 
-                                                                         helper);
+                               /* Finalize this mail operation */
+                               modest_mail_operation_notify_end (self);
                        }
+                       g_object_unref (trans_account);
                } else {
-                       /* Finalize this mail operation */
-                       modest_mail_operation_notify_end (self);
+                       g_warning ("No transport account for the operation");
                }
-               g_object_unref (trans_account);
        }
 
        g_object_unref (helper->mail_op);
@@ -827,12 +838,16 @@ create_msg_thread (gpointer thread_data)
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
        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->bcc, info->subject, 
+                                             info->references, info->in_reply_to,
+                                             info->plain_body, 
                                              info->attachments_list, &attached,
                                              &(priv->error));
        } else {
                new_msg = modest_tny_msg_new_html_plain (info->to, info->from, info->cc,
-                                                        info->bcc, info->subject, info->html_body,
+                                                        info->bcc, info->subject, 
+                                                        info->references, info->in_reply_to,
+                                                        info->html_body,
                                                         info->plain_body, info->attachments_list,
                                                         info->images_list, &attached,
                                                         &(priv->error));
@@ -866,6 +881,8 @@ create_msg_thread (gpointer thread_data)
        g_free (info->plain_body);
        g_free (info->html_body);
        g_free (info->subject);
+       g_free (info->references);
+       g_free (info->in_reply_to);
        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);
@@ -899,6 +916,8 @@ modest_mail_operation_create_msg (ModestMailOperation *self,
                                  const GList *attachments_list,
                                  const GList *images_list,
                                  TnyHeaderFlags priority_flags,
+                                 const gchar *references,
+                                 const gchar *in_reply_to,
                                  ModestMailOperationCreateMsgCallback callback,
                                  gpointer userdata)
 {
@@ -914,6 +933,8 @@ modest_mail_operation_create_msg (ModestMailOperation *self,
        info->subject = g_strdup (subject);
        info->plain_body = g_strdup (plain_body);
        info->html_body = g_strdup (html_body);
+       info->references = g_strdup (references);
+       info->in_reply_to = g_strdup (in_reply_to);
        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);
@@ -1073,6 +1094,8 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
                                     const gchar *html_body,
                                     const GList *attachments_list,
                                     const GList *images_list,
+                                    const gchar *references,
+                                    const gchar *in_reply_to,
                                     TnyHeaderFlags priority_flags)
 {
        ModestMailOperationPrivate *priv = NULL;
@@ -1109,6 +1132,7 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
 
        modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body,
                                          attachments_list, images_list, priority_flags,
+                                         references, in_reply_to,
                                          modest_mail_operation_send_new_mail_cb, info);
 
 }
@@ -1231,16 +1255,18 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self,
        }
 
        if (!priv->error || priv->error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
-               SaveToDraftsAddMsgInfo *cb_info = g_slice_new(SaveToDraftsAddMsgInfo);
-               cb_info->transport_account = g_object_ref(info->transport_account);
-               cb_info->draft_msg = info->draft_msg ? g_object_ref(info->draft_msg) : NULL;
-               cb_info->callback = info->callback;
-               cb_info->user_data = info->user_data;
-               cb_info->drafts = g_object_ref(drafts);
-               cb_info->msg = g_object_ref(msg);
-               cb_info->mailop = g_object_ref(self);
-               tny_folder_add_msg_async(drafts, msg, modest_mail_operation_save_to_drafts_add_msg_cb,
-                                        NULL, cb_info);
+               if (drafts) {
+                       SaveToDraftsAddMsgInfo *cb_info = g_slice_new(SaveToDraftsAddMsgInfo);
+                       cb_info->transport_account = g_object_ref(info->transport_account);
+                       cb_info->draft_msg = info->draft_msg ? g_object_ref(info->draft_msg) : NULL;
+                       cb_info->callback = info->callback;
+                       cb_info->user_data = info->user_data;
+                       cb_info->drafts = g_object_ref(drafts);
+                       cb_info->msg = g_object_ref(msg);
+                       cb_info->mailop = g_object_ref(self);
+                       tny_folder_add_msg_async(drafts, msg, modest_mail_operation_save_to_drafts_add_msg_cb,
+                                                NULL, cb_info);
+               }
        } else {
                /* Call the user callback */
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
@@ -1269,6 +1295,8 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self,
                                      const GList *attachments_list,
                                      const GList *images_list,
                                      TnyHeaderFlags priority_flags,
+                                     const gchar *references,
+                                     const gchar *in_reply_to,
                                      SaveToDraftstCallback callback,
                                      gpointer user_data)
 {
@@ -1294,6 +1322,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self,
        modest_mail_operation_notify_start (self);
        modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body,
                                          attachments_list, images_list, priority_flags,
+                                         references, in_reply_to,
                                          modest_mail_operation_save_to_drafts_cb, info);
 }
 
@@ -1432,13 +1461,16 @@ update_account_send_mail (UpdateAccountInfo *info)
                                g_warning ("%s: could not get outbox", __FUNCTION__);
                                num_messages = 0;
                        }
-               
+
                        if (num_messages != 0) {
+                               ModestMailOperation *mail_op;
                                /* Reenable suspended items */
-                               modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
-                               
+                               mail_op = modest_mail_operation_new (NULL);
+                               modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+                                                                mail_op);
+                               modest_mail_operation_queue_wakeup (mail_op, MODEST_TNY_SEND_QUEUE (send_queue));
+
                                /* Try to send */
-                               tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
                                modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue), 
                                                                                  info->interactive);
                        }
@@ -1535,20 +1567,18 @@ inbox_refreshed_cb (TnyFolder *inbox,
        UpdateAccountInfo *info;
        ModestMailOperationPrivate *priv;
        TnyIterator *new_headers_iter;
-       GPtrArray *new_headers_array = NULL;   
+       GPtrArray *new_headers_array = NULL;
        gint max_size, retrieve_limit, i;
        ModestAccountMgr *mgr;
        ModestAccountRetrieveType retrieve_type;
        TnyList *new_headers = NULL;
        gboolean headers_only, ignore_limit;
+       time_t time_to_store;
 
        info = (UpdateAccountInfo *) user_data;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
        mgr = modest_runtime_get_account_mgr ();
 
-       /* Set the last updated as the current time, do it even if the inbox refresh failed */
-       modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time (NULL));
-
        if (canceled || err) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                if (err)
@@ -1558,7 +1588,8 @@ inbox_refreshed_cb (TnyFolder *inbox,
                                     MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
                                     "canceled");
 
-               tny_folder_remove_observer (inbox, info->inbox_observer);
+               if (inbox)
+                       tny_folder_remove_observer (inbox, info->inbox_observer);
                g_object_unref (info->inbox_observer);
                info->inbox_observer = NULL;
 
@@ -1572,6 +1603,16 @@ inbox_refreshed_cb (TnyFolder *inbox,
                goto send_mail;
        }
 
+       /* Set the last updated as the current time */
+#ifdef MODEST_USE_LIBTIME
+       struct tm utc_tm;
+       time_get_utc (&utc_tm);
+       time_to_store = time_mktime (&utc_tm, "GMT");
+#else
+       time_to_store = time (NULL);
+#endif
+       modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time_to_store);
+
        /* Get the message max size */
        max_size  = modest_conf_get_int (modest_runtime_get_conf (),
                                         MODEST_CONF_MSG_SIZE_LIMIT, NULL);
@@ -1592,7 +1633,7 @@ inbox_refreshed_cb (TnyFolder *inbox,
                        /* Apply per-message size limits */
                        if (tny_header_get_message_size (header) < max_size)
                                g_ptr_array_add (new_headers_array, g_object_ref (header));
-                       
+
                        g_object_unref (header);
                        tny_iterator_next (new_headers_iter);
                }
@@ -1612,14 +1653,14 @@ inbox_refreshed_cb (TnyFolder *inbox,
        retrieve_limit = modest_account_mgr_get_retrieve_limit (mgr, info->account_name);
        if (retrieve_limit == 0)
                retrieve_limit = G_MAXINT;
-       
+
        /* Get per-account retrieval type */
        retrieve_type = modest_account_mgr_get_retrieve_type (mgr, info->account_name);
        headers_only = (retrieve_type == MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY);
 
        /* Order by date */
        g_ptr_array_sort (new_headers_array, (GCompareFunc) compare_headers_by_date);
-       
+
        /* Ask the users if they want to retrieve all the messages
           even though the limit was exceeded */
        ignore_limit = FALSE;
@@ -1642,7 +1683,7 @@ inbox_refreshed_cb (TnyFolder *inbox,
        }
        g_ptr_array_foreach (new_headers_array, (GFunc) g_object_unref, NULL);
        g_ptr_array_free (new_headers_array, FALSE);
-       
+
        if (!headers_only && (tny_list_get_length (new_headers) > 0)) {
                gint msg_num = 0;
                TnyIterator *iter;
@@ -1663,16 +1704,16 @@ inbox_refreshed_cb (TnyFolder *inbox,
                msg_info->more_msgs = g_object_ref (iter);
                msg_info->user_data = info;
 
-               while ((msg_num < priv->total ) && !tny_iterator_is_done (iter)) {              
+               while ((msg_num < priv->total ) && !tny_iterator_is_done (iter)) {
                        TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
                        TnyFolder *folder = tny_header_get_folder (header);
 
                        /* Get message in an async way */
-                       tny_folder_get_msg_async (folder, header, update_account_get_msg_async_cb, 
+                       tny_folder_get_msg_async (folder, header, update_account_get_msg_async_cb,
                                                  NULL, msg_info);
 
                        g_object_unref (folder);
-                       
+
                        msg_num++;
                        tny_iterator_next (iter);
                }
@@ -1686,11 +1727,11 @@ inbox_refreshed_cb (TnyFolder *inbox,
        /* If we don't have to retrieve the new messages then
           simply send mail */
        update_account_send_mail (info);
-       
+
        /* Check if the operation was a success */
        if (!priv->error)
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-       
+
        /* Call the user callback and free */
        update_account_notify_user_and_free (info, new_headers);
 }
@@ -1962,9 +2003,9 @@ compare_headers_by_date (gconstpointer a,
        /* We want the most recent ones (greater time_t) at the
           beginning */
        if (sent1 < sent2)
-               return 1;
-       else
                return -1;
+       else
+               return 1;
 }
 
 
@@ -2056,7 +2097,7 @@ modest_mail_operation_create_folder (ModestMailOperation *self,
                }
        }
 
-       if (!strcmp (name, " ") || strchr (name, '/')) {
+       if (!priv->error && (!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,
@@ -2187,7 +2228,6 @@ transfer_folder_status_cb (GObject *obj,
        g_slice_free (ModestMailOperationState, state);
 }
 
-
 static void
 transfer_folder_cb (TnyFolder *folder, 
                    gboolean cancelled, 
@@ -2201,7 +2241,7 @@ transfer_folder_cb (TnyFolder *folder,
        ModestMailOperationPrivate *priv = NULL;
 
        helper = (XFerFolderAsyncHelper *) user_data;
-       g_return_if_fail (helper != NULL);       
+       g_return_if_fail (helper != NULL);
 
        self = helper->mail_op;
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
@@ -2220,7 +2260,13 @@ transfer_folder_cb (TnyFolder *folder,
                priv->done = 1;
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
        }
-               
+
+       /* Update state of new folder */
+       if (new_folder) {
+               tny_folder_refresh_async (new_folder, NULL, NULL, NULL);
+               tny_folder_poke_status (new_folder);
+       }
+
        /* Notify about operation end */
        modest_mail_operation_notify_end (self);
 
@@ -2449,6 +2495,71 @@ modest_mail_operation_rename_folder (ModestMailOperation *self,
 /* ******************************************************************* */
 
 void 
+modest_mail_operation_find_msg (ModestMailOperation *self,
+                               TnyFolder *folder,
+                               const gchar *msg_uid,
+                               gboolean progress_feedback,
+                               GetMsgAsyncUserCallback user_callback,
+                               gpointer user_data)
+{
+       GetMsgInfo *helper = NULL;
+       ModestMailOperationPrivate *priv;
+       
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (msg_uid != NULL);
+       
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+       priv->total = 1;
+       priv->done = 0;
+
+       /* Check memory low */
+       if (_check_memory_low (self)) {
+               if (user_callback)
+                       user_callback (self, NULL, FALSE, NULL, priv->error, user_data);
+               modest_mail_operation_notify_end (self);
+               return;
+       }
+
+       /* Get account and set it into mail_operation */
+       priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder));
+       
+       /* Check for cached messages */
+       if (progress_feedback) {
+               priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE;
+       } else {
+               priv->op_type = MODEST_MAIL_OPERATION_TYPE_UNKNOWN;
+       }
+       
+       /* Create the helper */
+       helper = g_slice_new0 (GetMsgInfo);
+       helper->header = NULL;
+       helper->mail_op = g_object_ref (self);
+       helper->user_callback = user_callback;
+       helper->user_data = user_data;
+       helper->destroy_notify = NULL;
+       helper->last_total_bytes = 0;
+       helper->sum_total_bytes = 0;
+       helper->total_bytes = 0;
+       helper->more_msgs = NULL;
+
+       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;
+       g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 
+                               0, state, NULL);
+       g_slice_free (ModestMailOperationState, state);
+       
+       tny_folder_find_msg_async (folder, msg_uid, get_msg_async_cb, get_msg_status_cb, helper);
+
+       g_object_unref (G_OBJECT (folder));
+}
+
+void 
 modest_mail_operation_get_msg (ModestMailOperation *self,
                               TnyHeader *header,
                               gboolean progress_feedback,
@@ -2568,11 +2679,10 @@ get_msg_async_cb (TnyFolder *folder,
                priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
        } else if (err) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
-               if (err) {
-                       priv->error = g_error_copy ((const GError *) err);
+               priv->error = g_error_copy ((const GError *) err);
+               if (priv->error) {
                        priv->error->domain = MODEST_MAIL_OPERATION_ERROR;
-               }
-               if (!priv->error) {
+               } else {
                        g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
                                     MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
                                     err->message);
@@ -2582,6 +2692,8 @@ get_msg_async_cb (TnyFolder *folder,
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
        }
 
+       if (info->header == NULL && msg)
+               info->header = tny_msg_get_header (msg);
 
        /* Call the user callback */
        if (info->user_callback)
@@ -2765,7 +2877,7 @@ remove_msgs_async_cb (TnyFolder *folder,
                return;
        }
 
-       account = tny_folder_get_account (folder);
+       account = modest_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 (),
@@ -2796,6 +2908,7 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
        TnyHeader *header = NULL;
        TnyList *remove_headers = NULL;
        TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
+       ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
 
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_LIST (headers));
@@ -2807,52 +2920,67 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
                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));
+       g_object_unref (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 */
+       /* Use the merged folder if we're removing messages from outbox */
        if (modest_tny_folder_is_local_folder (folder)) {
+               ModestTnyLocalFoldersAccount *local_account;
+
+               local_account = (ModestTnyLocalFoldersAccount *)
+                       modest_tny_account_store_get_local_folders_account (accstore);
                folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
+               if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
+                       g_object_unref (folder);
+                       folder = modest_tny_local_folders_account_get_merged_outbox (local_account);
+               }
+               g_object_unref (local_account);
        }
+
        if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
-               TnyTransportAccount *traccount = NULL;
-               ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
-               traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
-               if (traccount) {
-                       ModestTnySendQueueStatus status;
-                       ModestTnySendQueue *send_queue = modest_runtime_get_send_queue(traccount, TRUE);
-
-                       if (TNY_IS_SEND_QUEUE (send_queue)) {
-                               TnyIterator *iter = tny_list_create_iterator(headers);
-                               g_object_unref(remove_headers);
-                               remove_headers = TNY_LIST(tny_simple_list_new());
-                               while (!tny_iterator_is_done(iter)) {
+               TnyIterator *headers_iter = tny_list_create_iterator (headers);
+
+               while (!tny_iterator_is_done (headers_iter)) {
+                       TnyTransportAccount *traccount = NULL;
+                       TnyHeader *hdr = NULL;
+
+                       hdr = TNY_HEADER (tny_iterator_get_current (headers_iter));
+                       traccount = modest_tny_account_store_get_transport_account_from_outbox_header (accstore,
+                                                                                                      header);
+                       if (traccount) {
+                               ModestTnySendQueueStatus status;
+                               ModestTnySendQueue *send_queue;
+
+                               send_queue = modest_runtime_get_send_queue(traccount, TRUE);
+                               if (TNY_IS_SEND_QUEUE (send_queue)) {
                                        char *msg_id;
-                                       TnyHeader *hdr = TNY_HEADER(tny_iterator_get_current(iter));
+
                                        msg_id = modest_tny_send_queue_get_msg_id (hdr);
                                        status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
                                        if (status != MODEST_TNY_SEND_QUEUE_SENDING) {
+                                               if (G_UNLIKELY (remove_headers == NULL))
+                                                       remove_headers = tny_simple_list_new ();
                                                tny_list_append(remove_headers, G_OBJECT(hdr));
                                        }
-                                       g_object_unref(hdr);
                                        g_free(msg_id);
-                                       tny_iterator_next(iter);
                                }
-                               g_object_unref(iter);
+                               g_object_unref(traccount);
                        }
-                       g_object_unref(traccount);
+                       g_object_unref(hdr);
+                       tny_iterator_next (headers_iter);
                }
+               g_object_unref(headers_iter);
        }
 
        /* Get account and set it into mail_operation */
@@ -2860,6 +2988,9 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self,
        priv->op_type = MODEST_MAIL_OPERATION_TYPE_DELETE;
        priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
 
+       if (!remove_headers)
+               remove_headers = g_object_ref (headers);
+
        /* remove message from folder */
        modest_mail_operation_notify_start (self);
        tny_folder_remove_msgs_async (folder, remove_headers, remove_msgs_async_cb, 
@@ -2870,8 +3001,6 @@ cleanup:
                g_object_unref (remove_headers);
        if (header)
                g_object_unref (header);
-       if (iter)
-               g_object_unref (iter);
        if (folder)
                g_object_unref (folder);
 }
@@ -3418,6 +3547,46 @@ modest_mail_operation_run_queue (ModestMailOperation *self,
 }
 
 static void
+queue_wakeup_callback (ModestTnySendQueue *queue,
+                      gboolean cancelled,
+                      GError *error,
+                      gpointer userdata)
+{
+       ModestMailOperation *mail_op;
+       ModestMailOperationPrivate *priv;
+
+       mail_op = (ModestMailOperation *) userdata;
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op);
+
+       priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+       tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (queue));
+
+       /* Notify end */
+       modest_mail_operation_notify_end (mail_op);
+       g_object_unref (mail_op);
+}
+
+void
+modest_mail_operation_queue_wakeup (ModestMailOperation *self,
+                                   ModestTnySendQueue *queue)
+{
+       ModestMailOperationPrivate *priv;
+
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (queue));
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+       priv->account = TNY_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (queue)));
+       priv->op_type = MODEST_MAIL_OPERATION_TYPE_QUEUE_WAKEUP;
+
+       g_object_ref (self);
+
+       modest_tny_send_queue_wakeup (queue, queue_wakeup_callback, self);
+       modest_mail_operation_notify_start (self);
+}
+
+static void
 shutdown_callback (ModestTnyAccountStore *account_store, gpointer userdata)
 {
        ModestMailOperation *self = (ModestMailOperation *) userdata;