From: Sergio Villar Senin Date: Tue, 22 Jan 2008 17:51:30 +0000 (+0000) Subject: * Migrated Modest to the new send queue API X-Git-Tag: git_migration_finished~1773 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=a9c347489d676ecf1cb0a4ba30059432aeccee80 * Migrated Modest to the new send queue API * Cancelling messages now sets the status of the messages to Suspended instead of Failed * Fixes NB#75801, Modest properly cancels sends * Fixes NB#79456, Modest no longer crashes when doing S&R in the background * Modest restarts now the suspended messages in the Outbox when clicking s&r * Modest restarts now the suspended messages when starting the program * The dimming rules are properly updated when the status of a message in the Outbox changes * The modest send queue now stores references to the sent and outbox folders * Modest waits until all the messages have been sent (or fail) when doing s&r pmo-trunk-r4076 --- diff --git a/src/maemo/modest-main-window.c b/src/maemo/modest-main-window.c index 3d1b31b..83039d9 100644 --- a/src/maemo/modest-main-window.c +++ b/src/maemo/modest-main-window.c @@ -2233,6 +2233,7 @@ get_toolbar_mode_from_mail_operation (ModestMainWindow *self, /* Get toolbar mode from operation id*/ switch (modest_mail_operation_get_type_operation (mail_op)) { + case MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE: case MODEST_MAIL_OPERATION_TYPE_RECEIVE: case MODEST_MAIL_OPERATION_TYPE_OPEN: mode = TOOLBAR_MODE_TRANSFER; diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 61573eb..15a6307 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -506,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; } @@ -720,8 +717,6 @@ send_mail_error_happened_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg if (msgid2 == NULL) msgid2 = "(null)"; if (!strcmp (msgid1, msgid2)) { - if (error != NULL) - g_warning ("%s: %s\n", __FUNCTION__, error->message); ModestMailOperationPrivate *priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op); priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, @@ -1299,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, @@ -1316,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); @@ -1427,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) @@ -1452,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) @@ -1564,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 (); @@ -1596,17 +1684,15 @@ 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, NULL, diff --git a/src/modest-mail-operation.h b/src/modest-mail-operation.h index 46990ad..a3fac9c 100644 --- a/src/modest-mail-operation.h +++ b/src/modest-mail-operation.h @@ -69,6 +69,8 @@ typedef enum _ModestMailOperationStatus { typedef enum { MODEST_MAIL_OPERATION_TYPE_SEND, MODEST_MAIL_OPERATION_TYPE_RECEIVE, + MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE, + MODEST_MAIL_OPERATION_TYPE_SEND, MODEST_MAIL_OPERATION_TYPE_OPEN, MODEST_MAIL_OPERATION_TYPE_DELETE, MODEST_MAIL_OPERATION_TYPE_INFO, diff --git a/src/modest-tny-account.c b/src/modest-tny-account.c index 90c4433..f0b53b9 100644 --- a/src/modest-tny-account.c +++ b/src/modest-tny-account.c @@ -78,7 +78,8 @@ modest_tny_account_get_special_folder (TnyAccount *account, */ /* Per-account outbox folders are each in their own on-disk directory: */ - if (special_type == TNY_FOLDER_TYPE_OUTBOX) { + if ((special_type == TNY_FOLDER_TYPE_OUTBOX) && + (!modest_tny_account_is_virtual_local_folders (account))) { gchar *account_id; const gchar *modest_account_name; diff --git a/src/modest-tny-send-queue.c b/src/modest-tny-send-queue.c index 42823a4..1139eba 100644 --- a/src/modest-tny-send-queue.c +++ b/src/modest-tny-send-queue.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -74,9 +75,7 @@ static TnyFolder* modest_tny_send_queue_get_sentbox (TnySendQueue *self); /* list my signals */ enum { - STATUS_CHANGED, - /* MY_SIGNAL_1, */ - /* MY_SIGNAL_2, */ + STATUS_CHANGED_SIGNAL, LAST_SIGNAL }; @@ -93,6 +92,10 @@ struct _ModestTnySendQueuePrivate { /* The info that is currently being sent */ GList* current; + + /* Special folders */ + TnyFolder *outbox; + TnyFolder *sentbox; }; #define MODEST_TNY_SEND_QUEUE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ @@ -178,65 +181,6 @@ modest_tny_send_queue_to_string (ModestTnySendQueue *self) } static void -modest_tny_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err) -{ - ModestTnySendQueuePrivate *priv; - SendInfo *info; - TnyIterator *iter = NULL; - TnyFolder *outbox = NULL; - TnyList *headers = tny_simple_list_new (); - TnyHeader *header = NULL; - - priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); - if(priv->current != NULL) - { - info = priv->current->data; - priv->current = NULL; - - /* Keep in list until retry, so that we know that this was suspended - * by the user and not by an error. */ - info->status = MODEST_TNY_SEND_QUEUE_SUSPENDED; - - g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); - } - - /* Set flags to supend sending operaiton (if removed, this is not necessary) */ - if (!remove) { - outbox = modest_tny_send_queue_get_outbox (TNY_SEND_QUEUE(self)); - if (!outbox) { - g_warning ("%s: modest_tny_send_queue_get_outbox(..) returned NULL\n", __FUNCTION__); - goto frees; - } - tny_folder_get_headers (outbox, headers, TRUE, err); - if (err != NULL) goto frees; - iter = tny_list_create_iterator (headers); - while (!tny_iterator_is_done (iter)) { - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - tny_header_set_flag (header, TNY_HEADER_FLAG_SUSPENDED); - tny_iterator_next (iter); - g_object_unref (header); - } - } - - g_queue_foreach (priv->queue, (GFunc)modest_tny_send_queue_info_free, NULL); - g_queue_free (priv->queue); - priv->queue = g_queue_new(); - } - - /* Dont call super class implementaiton, becasue camel removes messages from outbox */ - TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->cancel_func (self, remove, err); /* FIXME */ - - frees: - if (headers != NULL) - g_object_unref (G_OBJECT (headers)); - if (outbox != NULL) - g_object_unref (G_OBJECT (outbox)); - if (iter != NULL) - g_object_unref (iter); -} - -static void _on_added_to_outbox (TnySendQueue *self, gboolean cancelled, TnyMsg *msg, GError *err, gpointer user_data) { @@ -266,7 +210,7 @@ _on_added_to_outbox (TnySendQueue *self, gboolean cancelled, TnyMsg *msg, GError g_queue_push_tail (priv->queue, info); } - g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); + g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status); g_object_unref(G_OBJECT(header)); } @@ -336,48 +280,26 @@ _add_message (ModestTnySendQueue *self, TnyHeader *header) static TnyFolder* modest_tny_send_queue_get_sentbox (TnySendQueue *self) { - TnyFolder *folder; - TnyCamelTransportAccount *account; + ModestTnySendQueuePrivate *priv; g_return_val_if_fail (self, NULL); - account = tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE(self)); - if (!account) { - g_printerr ("modest: no account for send queue\n"); - return NULL; - } - folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(account), - TNY_FOLDER_TYPE_SENT); - g_object_unref (G_OBJECT(account)); + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); - return folder; + return g_object_ref (priv->sentbox); } static TnyFolder* modest_tny_send_queue_get_outbox (TnySendQueue *self) { - TnyFolder *folder; - TnyCamelTransportAccount *account; + ModestTnySendQueuePrivate *priv; g_return_val_if_fail (self, NULL); - account = tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE(self)); - if (!account) { - g_printerr ("modest: no account for send queue\n"); - return NULL; - } - folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(account), - TNY_FOLDER_TYPE_OUTBOX); - - /* This vfunc's tinymail contract does not allow it to return NULL. */ - if (!folder) { - g_warning("%s: Returning NULL.\n", __FUNCTION__); - } - - g_object_unref (G_OBJECT(account)); + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); - return folder; + return g_object_ref (priv->outbox); } GType @@ -419,10 +341,9 @@ modest_tny_send_queue_class_init (ModestTnySendQueueClass *klass) TNY_CAMEL_SEND_QUEUE_CLASS(klass)->get_outbox_func = modest_tny_send_queue_get_outbox; TNY_CAMEL_SEND_QUEUE_CLASS(klass)->get_sentbox_func = modest_tny_send_queue_get_sentbox; - TNY_CAMEL_SEND_QUEUE_CLASS(klass)->cancel_func = modest_tny_send_queue_cancel; klass->status_changed = NULL; - signals[STATUS_CHANGED] = + signals[STATUS_CHANGED_SIGNAL] = g_signal_new ("status_changed", G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_FIRST, @@ -454,21 +375,24 @@ modest_tny_send_queue_finalize (GObject *obj) g_queue_foreach (priv->queue, (GFunc)modest_tny_send_queue_info_free, NULL); g_queue_free (priv->queue); + g_object_unref (priv->outbox); + g_object_unref (priv->sentbox); + G_OBJECT_CLASS(parent_class)->finalize (obj); } ModestTnySendQueue* modest_tny_send_queue_new (TnyCamelTransportAccount *account) { - ModestTnySendQueue *self; + ModestTnySendQueue *self = NULL; + ModestTnySendQueuePrivate *priv = NULL; + TnyIterator *iter = NULL; + TnyList *headers = NULL; g_return_val_if_fail (TNY_IS_CAMEL_TRANSPORT_ACCOUNT(account), NULL); self = MODEST_TNY_SEND_QUEUE(g_object_new(MODEST_TYPE_TNY_SEND_QUEUE, NULL)); - tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self), - account); - /* Connect signals to control when a msg is being or has been sent */ g_signal_connect (G_OBJECT(self), "msg-sending", G_CALLBACK(_on_msg_start_sending), @@ -479,51 +403,43 @@ modest_tny_send_queue_new (TnyCamelTransportAccount *account) g_signal_connect (G_OBJECT(self), "error-happened", G_CALLBACK(_on_msg_error_happened), NULL); - return self; -} + /* Set outbox and sentbox */ + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); + priv->outbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account), + TNY_FOLDER_TYPE_OUTBOX); + priv->sentbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account), + TNY_FOLDER_TYPE_SENT); -void -modest_tny_send_queue_try_to_send (ModestTnySendQueue* self) -{ - TnyIterator *iter = NULL; - TnyFolder *outbox = NULL; - TnyList *headers = tny_simple_list_new (); - TnyHeader *header = NULL; - GError *err = NULL; - - g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE(self)); - - outbox = modest_tny_send_queue_get_outbox (TNY_SEND_QUEUE(self)); - if (!outbox) - return; - - tny_folder_get_headers (outbox, headers, TRUE, &err); - if (err != NULL) - goto frees; + headers = tny_simple_list_new (); + tny_folder_get_headers (priv->outbox, headers, TRUE, NULL); + /* Add messages to our internal queue */ iter = tny_list_create_iterator (headers); while (!tny_iterator_is_done (iter)) { - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - _add_message (self, header); - g_object_unref (header); - } + TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); + _add_message (self, header); + g_object_unref (header); tny_iterator_next (iter); } - - /* Flush send queue */ - tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE(self)); - - frees: - if (headers != NULL) - g_object_unref (G_OBJECT (headers)); - if (outbox != NULL) - g_object_unref (G_OBJECT (outbox)); - if (iter != NULL) - g_object_unref (iter); + + /* Reenable suspended items */ + modest_tny_send_queue_wakeup (self); + + /* Frees */ + g_object_unref (G_OBJECT (headers)); + g_object_unref (G_OBJECT (priv->outbox)); + g_object_unref (iter); + + /* Do this at the end, because it'll call tny_send_queue_flush + which will call tny_send_queue_get_outbox and + tny_send_queue_get_sentbox */ + tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self), + account); + + return self; } gboolean @@ -604,17 +520,12 @@ _on_msg_start_sending (TnySendQueue *self, /* Get status info */ item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id); - if (!item) - g_warning ("%s: item (%s) should not be NULL", - __FUNCTION__, msg_id ? msg_id : ""); - else { - info = item->data; - info->status = MODEST_TNY_SEND_QUEUE_SENDING; - - /* Set current status item */ - g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); - priv->current = item; - } + + /* Set current status item */ + info = item->data; + info->status = MODEST_TNY_SEND_QUEUE_SENDING; + g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status); + priv->current = item; /* free */ g_free (msg_id); @@ -632,6 +543,9 @@ _on_msg_has_been_sent (TnySendQueue *self, gchar *msg_id = NULL; GList *item; + /* TODO: Sometimes tinymail does not return a header, need to check */ + g_return_if_fail (TNY_IS_HEADER (header)); + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); /* Get message uid */ @@ -641,15 +555,13 @@ _on_msg_has_been_sent (TnySendQueue *self, /* Get status info */ item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id); - if (item) { - /* Remove status info */ - modest_tny_send_queue_info_free (item->data); - g_queue_delete_link (priv->queue, item); - priv->current = NULL; + /* Remove status info */ + modest_tny_send_queue_info_free (item->data); + g_queue_delete_link (priv->queue, item); + priv->current = NULL; - modest_platform_information_banner (NULL, NULL, _("mcen_ib_message_sent")); - } + modest_platform_information_banner (NULL, NULL, _("mcen_ib_message_sent")); /* free */ g_free(msg_id); @@ -673,20 +585,18 @@ _on_msg_error_happened (TnySendQueue *self, msg_uid = modest_tny_send_queue_get_msg_id (header); item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_uid); - if (item == NULL) { - info = g_slice_new (SendInfo); - info->msg_id = (msg_uid != NULL)? strdup(msg_uid) : NULL; - g_queue_push_tail (priv->queue, info); - } else - info = item->data; + info = item->data; /* Keep in queue so that we remember that the opertion has failed */ /* and was not just cancelled */ - info->status = MODEST_TNY_SEND_QUEUE_FAILED; + if (err->code == TNY_SYSTEM_ERROR_CANCEL) + info->status = MODEST_TNY_SEND_QUEUE_SUSPENDED; + else + info->status = MODEST_TNY_SEND_QUEUE_FAILED; priv->current = NULL; /* Notify status has changed */ - g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); + g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status); /* free */ g_free(msg_uid); @@ -699,6 +609,7 @@ fill_list_of_caches (gpointer key, gpointer value, gpointer userdata) *send_queues = g_slist_prepend (*send_queues, value); } +/* This function shouldn't be here. Move it to another place. Sergio */ ModestTnySendQueueStatus modest_tny_all_send_queues_get_msg_status (TnyHeader *header) { @@ -762,3 +673,51 @@ modest_tny_all_send_queues_get_msg_status (TnyHeader *header) g_slist_free (send_queues); return status; } + +void +modest_tny_send_queue_wakeup (ModestTnySendQueue *self) +{ + ModestTnySendQueuePrivate *priv; + TnyList *headers; + TnyIterator *iter; + + g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self)); + + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); + + headers = tny_simple_list_new (); + tny_folder_get_headers (priv->outbox, headers, TRUE, NULL); + + /* Wake up every single suspended header */ + iter = tny_list_create_iterator (headers); + while (!tny_iterator_is_done (iter)) { + TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); + + if (tny_header_get_flags (header) & TNY_HEADER_FLAG_SUSPENDED) { + gchar *msg_id; + GList *item; + SendInfo *info; + + /* Unset the suspended flag */ + tny_header_unset_flag (header, TNY_HEADER_FLAG_SUSPENDED); + + /* Notify view */ + msg_id = modest_tny_send_queue_get_msg_id (header); + item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id); + info = (SendInfo *) item->data; + info->status = MODEST_TNY_SEND_QUEUE_WAITING; + g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status); + + /* Frees */ + g_free (msg_id); + } + + /* Frees */ + g_object_unref (header); + tny_iterator_next (iter); + } + + /* Frees */ + g_object_unref (iter); + g_object_unref (G_OBJECT (headers)); +} diff --git a/src/modest-tny-send-queue.h b/src/modest-tny-send-queue.h index 87eeb39..6c23f06 100644 --- a/src/modest-tny-send-queue.h +++ b/src/modest-tny-send-queue.h @@ -65,6 +65,7 @@ struct _ModestTnySendQueue { struct _ModestTnySendQueueClass { TnyCamelSendQueueClass parent_class; + /* Signals */ void (*status_changed)(ModestTnySendQueue *self, const gchar *msg_id, ModestTnySendQueueStatus status); }; @@ -102,17 +103,6 @@ ModestTnySendQueue* modest_tny_send_queue_new (TnyCamelTransportAccoun void modest_tny_send_queue_add (ModestTnySendQueue *self, TnyMsg *msg, GError **err); /** - * modest_tny_send_queue_try_to_send: - * @self: a valid #ModestTnySendQueue instance - * - * Try to send the messages that are in the queue's outbox folder. - * This is not always necessary because the queue tries to send - * messages as soon as a message is added, and as soon as the queue - * is instantiated. - */ -void modest_tny_send_queue_try_to_send (ModestTnySendQueue* self); - -/** * modest_tny_send_queue_sending_in_progress: * @self: a valid #ModestTnySendQueue instance * @@ -166,6 +156,16 @@ modest_tny_all_send_queues_get_msg_status (TnyHeader *header); */ gchar* modest_tny_send_queue_to_string (ModestTnySendQueue *self); +/** + * modest_tny_send_queue_wakeup: + * @self: a valid #ModestTnySendQueue instance + * + * Wakes up all suspended messages in the send queue. This means that + * the send queue will try to send them again. Note that you'd + * probably need a tny_send_queue_flush to force it + */ +void modest_tny_send_queue_wakeup (ModestTnySendQueue *self); + G_END_DECLS diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 4a9c06f..110a26f 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -1830,9 +1830,12 @@ modest_ui_actions_do_cancel_send (const gchar *account_name, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, "modest: could not find send queue for account\n"); } else { - /* Keeep messages in outbox folder */ - tny_send_queue_cancel (send_queue, FALSE, &error); - } + /* Cancel the current send */ + tny_account_cancel (TNY_ACCOUNT (transport_account)); + + /* Suspend all pending messages */ + tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error); + } frees: if (transport_account != NULL) @@ -5343,6 +5346,10 @@ modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue, #else gtk_widget_queue_draw (header_view); #endif + + /* Rerun dimming rules, because the message could become deletable for example */ + modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window), + MODEST_DIMMING_RULES_TOOLBAR); /* Free */ frees: