1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <modest-tny-send-queue.h>
32 #include <tny-simple-list.h>
33 #include <tny-iterator.h>
34 #include <tny-folder.h>
35 #include <tny-error.h>
36 #include <tny-camel-msg.h>
37 #include <tny-folder-change.h>
38 #include <tny-folder-observer.h>
39 #include <modest-tny-account.h>
40 #include <modest-runtime.h>
41 #include <modest-platform.h>
42 #include <widgets/modest-window-mgr.h>
43 #include <modest-marshal.h>
44 #include <modest-debug.h>
45 #include <string.h> /* strcmp */
47 /* 'private'/'protected' functions */
48 static void modest_tny_send_queue_class_init (ModestTnySendQueueClass *klass);
49 static void modest_tny_send_queue_finalize (GObject *obj);
50 static void modest_tny_send_queue_instance_init (GTypeInstance *instance, gpointer g_class);
53 static void _on_msg_start_sending (TnySendQueue *self,
60 static void _on_msg_has_been_sent (TnySendQueue *self,
67 static void _on_msg_error_happened (TnySendQueue *self,
73 static void _on_queue_start (TnySendQueue *self,
76 static void modest_tny_send_queue_add_async (TnySendQueue *self,
78 TnySendQueueAddCallback callback,
79 TnyStatusCallback status_callback,
82 static TnyFolder* modest_tny_send_queue_get_outbox (TnySendQueue *self);
83 static TnyFolder* modest_tny_send_queue_get_sentbox (TnySendQueue *self);
87 STATUS_CHANGED_SIGNAL,
91 typedef struct _SendInfo SendInfo;
94 ModestTnySendQueueStatus status;
97 typedef struct _ModestTnySendQueuePrivate ModestTnySendQueuePrivate;
98 struct _ModestTnySendQueuePrivate {
102 /* The info that is currently being sent */
105 /* Special folders */
109 /* last was send receive operation?*/
110 gboolean requested_send_receive;
113 #define MODEST_TNY_SEND_QUEUE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
114 MODEST_TYPE_TNY_SEND_QUEUE, \
115 ModestTnySendQueuePrivate))
118 static TnyCamelSendQueueClass *parent_class = NULL;
120 /* uncomment the following if you have defined any signals */
121 static guint signals[LAST_SIGNAL] = {0};
124 * this thread actually tries to send all the mails in the outbox and keeps
125 * track of their state.
129 on_modest_tny_send_queue_compare_id (gconstpointer info, gconstpointer msg_id)
131 g_return_val_if_fail (info && ((SendInfo*)info)->msg_id && msg_id, -1);
133 return strcmp( ((SendInfo*)info)->msg_id, msg_id);
137 modest_tny_send_queue_info_free (SendInfo *info)
139 g_free(info->msg_id);
140 g_slice_free(SendInfo, info);
144 modest_tny_send_queue_lookup_info (ModestTnySendQueue *self, const gchar *msg_id)
146 ModestTnySendQueuePrivate *priv;
147 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
149 return g_queue_find_custom (priv->queue, msg_id, on_modest_tny_send_queue_compare_id);
154 queue_item_to_string (gpointer data, gchar **user_data)
156 SendInfo *info = (SendInfo*)data;
160 if (!(user_data && *user_data))
163 switch (info->status) {
164 case MODEST_TNY_SEND_QUEUE_UNKNOWN: status = "UNKNOWN"; break;
165 case MODEST_TNY_SEND_QUEUE_WAITING: status = "WAITING"; break;
166 case MODEST_TNY_SEND_QUEUE_SUSPENDED: status = "SUSPENDED"; break;
167 case MODEST_TNY_SEND_QUEUE_SENDING: status = "SENDING"; break;
168 case MODEST_TNY_SEND_QUEUE_FAILED: status = "FAILED"; break;
169 default: status= "UNEXPECTED"; break;
172 tmp = g_strdup_printf ("%s\"%s\" => [%s]\n",
173 *user_data, info->msg_id, status);
179 modest_tny_send_queue_to_string (ModestTnySendQueue *self)
182 ModestTnySendQueuePrivate *priv;
184 g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), NULL);
185 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
187 str = g_strdup_printf ("items in the send queue: %d\n",
188 g_queue_get_length (priv->queue));
190 g_queue_foreach (priv->queue, (GFunc)queue_item_to_string, &str);
196 TnySendQueueAddCallback callback;
201 _on_added_to_outbox (TnySendQueue *self,
207 ModestTnySendQueuePrivate *priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE(self);
208 TnyHeader *header = NULL;
209 SendInfo *info = NULL;
210 GList* existing = NULL;
211 gchar* msg_id = NULL;
212 AddAsyncHelper *helper;
214 g_return_if_fail (TNY_IS_SEND_QUEUE(self));
215 g_return_if_fail (TNY_IS_CAMEL_MSG(msg));
217 header = tny_msg_get_header (msg);
218 msg_id = modest_tny_send_queue_get_msg_id (header);
220 g_warning ("%s: No msg_id returned for header", __FUNCTION__);
224 /* Put newly added message in WAITING state */
225 existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_id);
226 if(existing != NULL) {
227 info = existing->data;
228 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
230 info = g_slice_new (SendInfo);
231 info->msg_id = msg_id;
232 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
233 g_queue_push_tail (priv->queue, info);
236 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
239 g_object_unref (G_OBJECT(header));
241 /* Call the user callback */
242 helper = (AddAsyncHelper *) user_data;
243 if (helper->callback)
244 helper->callback (self, cancelled, msg, err, helper->user_data);
245 g_slice_free (AddAsyncHelper, helper);
249 _add_message (ModestTnySendQueue *self, TnyHeader *header)
251 ModestWindowMgr *mgr = NULL;
252 ModestTnySendQueuePrivate *priv;
253 SendInfo *info = NULL;
254 GList* existing = NULL;
255 gchar* msg_uid = NULL;
256 ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_UNKNOWN;
257 gboolean editing = FALSE;
259 g_return_if_fail (TNY_IS_SEND_QUEUE(self));
260 g_return_if_fail (TNY_IS_HEADER(header));
261 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
263 /* Check whether the mail is already in the queue */
264 msg_uid = modest_tny_send_queue_get_msg_id (header);
265 status = modest_tny_send_queue_get_msg_status (self, msg_uid);
267 case MODEST_TNY_SEND_QUEUE_UNKNOWN:
268 case MODEST_TNY_SEND_QUEUE_SUSPENDED:
269 case MODEST_TNY_SEND_QUEUE_FAILED:
271 /* Check if it already exists on queue */
272 existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_uid);
276 /* Check if its being edited */
277 mgr = modest_runtime_get_window_mgr ();
278 editing = modest_window_mgr_find_registered_header (mgr, header, NULL);
282 /* Add new meesage info */
283 info = g_slice_new0 (SendInfo);
284 info->msg_id = strdup(msg_uid);
285 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
286 g_queue_push_tail (priv->queue, info);
297 modest_tny_send_queue_add_async (TnySendQueue *self,
299 TnySendQueueAddCallback callback,
300 TnyStatusCallback status_callback,
303 AddAsyncHelper *helper = g_slice_new0 (AddAsyncHelper);
304 helper->callback = callback;
305 helper->user_data = user_data;
307 /* Call the superclass passing our own callback */
308 TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg,
316 modest_tny_send_queue_get_sentbox (TnySendQueue *self)
318 ModestTnySendQueuePrivate *priv;
320 g_return_val_if_fail (self, NULL);
322 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
324 return g_object_ref (priv->sentbox);
329 modest_tny_send_queue_get_outbox (TnySendQueue *self)
331 ModestTnySendQueuePrivate *priv;
333 g_return_val_if_fail (self, NULL);
335 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
337 return g_object_ref (priv->outbox);
341 modest_tny_send_queue_get_type (void)
343 static GType my_type = 0;
346 static const GTypeInfo my_info = {
347 sizeof(ModestTnySendQueueClass),
348 NULL, /* base init */
349 NULL, /* base finalize */
350 (GClassInitFunc) modest_tny_send_queue_class_init,
351 NULL, /* class finalize */
352 NULL, /* class data */
353 sizeof(ModestTnySendQueue),
355 (GInstanceInitFunc) modest_tny_send_queue_instance_init,
359 my_type = g_type_register_static (TNY_TYPE_CAMEL_SEND_QUEUE,
360 "ModestTnySendQueue",
368 modest_tny_send_queue_class_init (ModestTnySendQueueClass *klass)
370 GObjectClass *gobject_class;
372 gobject_class = (GObjectClass*) klass;
374 parent_class = g_type_class_peek_parent (klass);
375 gobject_class->finalize = modest_tny_send_queue_finalize;
377 TNY_CAMEL_SEND_QUEUE_CLASS(klass)->add_async = modest_tny_send_queue_add_async;
378 TNY_CAMEL_SEND_QUEUE_CLASS(klass)->get_outbox = modest_tny_send_queue_get_outbox;
379 TNY_CAMEL_SEND_QUEUE_CLASS(klass)->get_sentbox = modest_tny_send_queue_get_sentbox;
380 klass->status_changed = NULL;
382 signals[STATUS_CHANGED_SIGNAL] =
383 g_signal_new ("status_changed",
384 G_TYPE_FROM_CLASS (gobject_class),
386 G_STRUCT_OFFSET (ModestTnySendQueueClass, status_changed),
388 modest_marshal_VOID__STRING_INT,
389 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
391 g_type_class_add_private (gobject_class, sizeof(ModestTnySendQueuePrivate));
395 modest_tny_send_queue_instance_init (GTypeInstance *instance, gpointer g_class)
397 ModestTnySendQueuePrivate *priv;
399 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (instance);
400 priv->queue = g_queue_new();
401 priv->current = NULL;
405 modest_tny_send_queue_finalize (GObject *obj)
407 ModestTnySendQueuePrivate *priv;
409 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (obj);
411 g_queue_foreach (priv->queue, (GFunc)modest_tny_send_queue_info_free, NULL);
412 g_queue_free (priv->queue);
414 g_object_unref (priv->outbox);
415 g_object_unref (priv->sentbox);
417 G_OBJECT_CLASS(parent_class)->finalize (obj);
421 TnyCamelTransportAccount *account;
422 ModestTnySendQueue *queue;
426 new_queue_get_headers_async_cb (TnyFolder *folder,
432 ModestTnySendQueue *self;
434 GetHeadersInfo *info;
436 info = (GetHeadersInfo *) user_data;
437 self = MODEST_TNY_SEND_QUEUE (info->queue);
439 /* In case of error set the transport account anyway */
440 if (cancelled || err)
443 /* Add messages to our internal queue */
444 iter = tny_list_create_iterator (headers);
445 while (!tny_iterator_is_done (iter)) {
446 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
447 _add_message (self, header);
448 g_object_unref (header);
449 tny_iterator_next (iter);
452 /* Reenable suspended items */
453 modest_tny_send_queue_wakeup (self);
456 g_object_unref (iter);
457 g_object_unref (headers);
460 /* Do this at the end, because it'll call tny_send_queue_flush
461 which will call tny_send_queue_get_outbox and
462 tny_send_queue_get_sentbox */
463 tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self),
467 g_object_unref (info->account);
468 g_object_unref (info->queue);
469 g_slice_free (GetHeadersInfo, info);
473 modest_tny_send_queue_new (TnyCamelTransportAccount *account)
475 ModestTnySendQueue *self = NULL;
476 ModestTnySendQueuePrivate *priv = NULL;
477 TnyList *headers = NULL;
478 GetHeadersInfo *info;
480 g_return_val_if_fail (TNY_IS_CAMEL_TRANSPORT_ACCOUNT(account), NULL);
482 self = MODEST_TNY_SEND_QUEUE(g_object_new(MODEST_TYPE_TNY_SEND_QUEUE, NULL));
484 /* Connect signals to control when a msg is being or has been sent */
485 g_signal_connect (G_OBJECT(self), "msg-sending",
486 G_CALLBACK(_on_msg_start_sending),
488 g_signal_connect (G_OBJECT(self), "msg-sent",
489 G_CALLBACK(_on_msg_has_been_sent),
491 g_signal_connect (G_OBJECT(self), "error-happened",
492 G_CALLBACK(_on_msg_error_happened),
494 g_signal_connect (G_OBJECT (self), "queue-start",
495 G_CALLBACK (_on_queue_start),
498 /* Set outbox and sentbox */
499 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
500 priv->outbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account),
501 TNY_FOLDER_TYPE_OUTBOX);
502 priv->sentbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account),
503 TNY_FOLDER_TYPE_SENT);
504 priv->requested_send_receive = FALSE;
506 headers = tny_simple_list_new ();
507 info = g_slice_new0 (GetHeadersInfo);
508 info->account = g_object_ref (account);
509 info->queue = g_object_ref (self);
510 tny_folder_get_headers_async (priv->outbox, headers, TRUE,
511 new_queue_get_headers_async_cb,
518 modest_tny_send_queue_msg_is_being_sent (ModestTnySendQueue* self,
521 ModestTnySendQueueStatus status;
523 g_return_val_if_fail (msg_id != NULL, FALSE);
525 status = modest_tny_send_queue_get_msg_status (self, msg_id);
526 return status == MODEST_TNY_SEND_QUEUE_SENDING;
530 modest_tny_send_queue_sending_in_progress (ModestTnySendQueue* self)
532 ModestTnySendQueuePrivate *priv;
534 g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), FALSE);
536 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
538 return priv->current != NULL;
541 ModestTnySendQueueStatus
542 modest_tny_send_queue_get_msg_status (ModestTnySendQueue *self, const gchar *msg_id)
546 g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), MODEST_TNY_SEND_QUEUE_UNKNOWN);
547 g_return_val_if_fail (msg_id, MODEST_TNY_SEND_QUEUE_UNKNOWN);
549 item = modest_tny_send_queue_lookup_info (self, msg_id);
551 return MODEST_TNY_SEND_QUEUE_UNKNOWN;
553 return ((SendInfo*)item->data)->status;
557 modest_tny_send_queue_get_msg_id (TnyHeader *header)
559 gchar* msg_uid = NULL;
561 time_t date_received;
563 g_return_val_if_fail (header && TNY_IS_HEADER(header), NULL);
565 /* Get message uid */
566 subject = tny_header_dup_subject (header);
567 date_received = tny_header_get_date_received (header);
569 msg_uid = g_strdup_printf ("%s %d", subject, (int) date_received);
577 _on_msg_start_sending (TnySendQueue *self, TnyHeader *header,
578 TnyMsg *msg, int done, int total, gpointer user_data)
580 ModestTnySendQueuePrivate *priv = NULL;
582 SendInfo *info = NULL;
583 gchar *msg_id = NULL;
585 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
587 /* Get message uid */
588 msg_id = modest_tny_send_queue_get_msg_id (header);
590 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
592 g_warning ("%s: could not get msg-id for header", __FUNCTION__);
595 /* Set current status item */
597 info->status = MODEST_TNY_SEND_QUEUE_SENDING;
598 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
599 priv->current = item;
601 g_warning ("%s: could not find item with id '%s'", __FUNCTION__, msg_id);
608 _on_msg_has_been_sent (TnySendQueue *self,
615 ModestTnySendQueuePrivate *priv;
616 gchar *msg_id = NULL;
619 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
621 /* Get message uid */
622 msg_id = modest_tny_send_queue_get_msg_id (header);
624 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
626 tny_folder_sync_async (priv->sentbox, FALSE, NULL, NULL, NULL);
628 /* Get status info */
629 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
632 /* TODO: note that item=NULL must not happen, but I found that
633 tinymail is issuing the message-sent signal twice, because
634 tny_camel_send_queue_update is called twice for each
635 message sent. This must be fixed in tinymail. Sergio */
637 /* Remove status info */
638 modest_tny_send_queue_info_free (item->data);
639 g_queue_delete_link (priv->queue, item);
640 priv->current = NULL;
642 modest_platform_information_banner (NULL, NULL, _("mcen_ib_message_sent"));
650 _on_msg_error_happened (TnySendQueue *self,
656 ModestTnySendQueuePrivate *priv = NULL;
658 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
660 /* Note that header could be NULL. Tinymail notifies about
661 generic send queue errors with this signal as well, and
662 those notifications are not bound to any particular header
664 if (header && TNY_IS_HEADER (header)) {
665 SendInfo *info = NULL;
667 gchar* msg_uid = NULL;
669 /* Get sending info (create new if it doesn not exist) */
670 msg_uid = modest_tny_send_queue_get_msg_id (header);
671 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self),
674 /* TODO: this should not happen (but it does), so the
675 problem should be located in the way we generate
678 g_warning ("%s: could not find item with id '%s'", __FUNCTION__, msg_uid);
685 /* Keep in queue so that we remember that the opertion has failed */
686 /* and was not just cancelled */
687 if (err->code == TNY_SYSTEM_ERROR_CANCEL) {
688 info->status = MODEST_TNY_SEND_QUEUE_SUSPENDED;
690 if (err->code == TNY_SERVICE_ERROR_CONNECT) {
691 TnyCamelTransportAccount* transport;
693 transport = tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
696 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"),
697 tny_account_get_hostname (TNY_ACCOUNT (transport)));
698 modest_platform_run_alert_dialog (message, FALSE);
700 g_object_unref (transport);
703 info->status = MODEST_TNY_SEND_QUEUE_FAILED;
705 priv->current = NULL;
707 /* Notify status has changed */
708 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
716 _on_queue_start (TnySendQueue *self,
719 ModestMailOperation *mail_op;
721 mail_op = modest_mail_operation_new (NULL);
722 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
724 modest_mail_operation_run_queue (mail_op, MODEST_TNY_SEND_QUEUE (self));
725 g_object_unref (mail_op);
729 fill_list_of_caches (gpointer key, gpointer value, gpointer userdata)
731 GSList **send_queues = (GSList **) userdata;
732 *send_queues = g_slist_prepend (*send_queues, value);
735 /* This function shouldn't be here. Move it to another place. Sergio */
736 ModestTnySendQueueStatus
737 modest_tny_all_send_queues_get_msg_status (TnyHeader *header)
739 ModestCacheMgr *cache_mgr = NULL;
740 GHashTable *send_queue_cache = NULL;
741 ModestTnyAccountStore *accounts_store = NULL;
742 TnyList *accounts = NULL;
743 TnyIterator *iter = NULL;
744 TnyTransportAccount *account = NULL;
745 GSList *send_queues = NULL, *node;
746 /* get_msg_status returns suspended by default, so we want to detect changes */
747 ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_UNKNOWN;
748 ModestTnySendQueueStatus queue_status = MODEST_TNY_SEND_QUEUE_UNKNOWN;
749 gchar *msg_uid = NULL;
750 ModestTnySendQueue *send_queue = NULL;
752 g_return_val_if_fail (TNY_IS_HEADER(header), MODEST_TNY_SEND_QUEUE_UNKNOWN);
754 msg_uid = modest_tny_send_queue_get_msg_id (header);
755 cache_mgr = modest_runtime_get_cache_mgr ();
756 send_queue_cache = modest_cache_mgr_get_cache (cache_mgr,
757 MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE);
759 g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues);
760 if (send_queues == NULL) {
761 accounts = tny_simple_list_new ();
762 accounts_store = modest_runtime_get_account_store ();
763 tny_account_store_get_accounts (TNY_ACCOUNT_STORE(accounts_store),
765 TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS);
767 iter = tny_list_create_iterator (accounts);
768 while (!tny_iterator_is_done (iter)) {
769 account = TNY_TRANSPORT_ACCOUNT(tny_iterator_get_current (iter));
770 send_queue = modest_runtime_get_send_queue(TNY_TRANSPORT_ACCOUNT(account), TRUE);
771 g_object_unref(account);
773 queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid);
774 if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) {
775 status = queue_status;
778 tny_iterator_next (iter);
780 g_object_unref (iter);
781 g_object_unref (accounts);
784 for (node = send_queues; node != NULL; node = g_slist_next (node)) {
785 send_queue = MODEST_TNY_SEND_QUEUE (node->data);
787 queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid);
788 if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) {
789 status = queue_status;
796 g_slist_free (send_queues);
801 wakeup_get_headers_async_cb (TnyFolder *folder,
807 ModestTnySendQueue *self;
808 ModestTnySendQueuePrivate *priv;
811 self = MODEST_TNY_SEND_QUEUE (user_data);
812 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
814 if (cancelled || err) {
815 g_debug ("Failed to wake up the headers of the send queue");
816 g_object_unref (self);
820 /* Wake up every single suspended header */
821 iter = tny_list_create_iterator (headers);
822 while (!tny_iterator_is_done (iter)) {
823 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
825 if (tny_header_get_flags (header) & TNY_HEADER_FLAG_SUSPENDED) {
830 /* Unset the suspended flag */
831 tny_header_unset_flag (header, TNY_HEADER_FLAG_SUSPENDED);
834 msg_id = modest_tny_send_queue_get_msg_id (header);
835 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
836 info = (SendInfo *) item->data;
837 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
838 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
845 g_object_unref (header);
846 tny_iterator_next (iter);
849 /* Make changes persistent on disk */
850 tny_folder_sync_async (priv->outbox, FALSE, NULL, NULL, NULL);
853 g_object_unref (iter);
854 g_object_unref (headers);
855 g_object_unref (self);
860 modest_tny_send_queue_wakeup (ModestTnySendQueue *self)
862 ModestTnySendQueuePrivate *priv;
865 g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
867 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
869 headers = tny_simple_list_new ();
870 tny_folder_get_headers_async (priv->outbox, headers, TRUE,
871 wakeup_get_headers_async_cb,
872 NULL, g_object_ref (self));
876 modest_tny_send_queue_get_requested_send_receive (ModestTnySendQueue *self)
878 ModestTnySendQueuePrivate *priv;
880 g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE (self), FALSE);
881 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
883 return priv->requested_send_receive;
887 modest_tny_send_queue_set_requested_send_receive (ModestTnySendQueue *self, gboolean requested_send_receive)
889 ModestTnySendQueuePrivate *priv;
891 g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
892 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
894 priv->requested_send_receive = requested_send_receive;