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 _on_added_to_outbox (TnySendQueue *self,
202 ModestTnySendQueuePrivate *priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE(self);
203 TnyHeader *header = NULL;
204 SendInfo *info = NULL;
205 GList* existing = NULL;
206 gchar* msg_id = NULL;
208 g_return_if_fail (TNY_IS_SEND_QUEUE(self));
209 g_return_if_fail (TNY_IS_CAMEL_MSG(msg));
211 header = tny_msg_get_header (msg);
212 msg_id = modest_tny_send_queue_get_msg_id (header);
214 g_warning ("%s: No msg_id returned for header", __FUNCTION__);
218 /* Put newly added message in WAITING state */
219 existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_id);
220 if(existing != NULL) {
221 info = existing->data;
222 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
224 info = g_slice_new (SendInfo);
225 info->msg_id = msg_id;
226 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
227 g_queue_push_tail (priv->queue, info);
230 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
233 g_object_unref (G_OBJECT(header));
237 _add_message (ModestTnySendQueue *self, TnyHeader *header)
239 ModestWindowMgr *mgr = NULL;
240 ModestTnySendQueuePrivate *priv;
241 SendInfo *info = NULL;
242 GList* existing = NULL;
243 gchar* msg_uid = NULL;
244 ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_UNKNOWN;
245 gboolean editing = FALSE;
247 g_return_if_fail (TNY_IS_SEND_QUEUE(self));
248 g_return_if_fail (TNY_IS_HEADER(header));
249 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
251 /* Check whether the mail is already in the queue */
252 msg_uid = modest_tny_send_queue_get_msg_id (header);
253 status = modest_tny_send_queue_get_msg_status (self, msg_uid);
255 case MODEST_TNY_SEND_QUEUE_UNKNOWN:
256 case MODEST_TNY_SEND_QUEUE_SUSPENDED:
257 case MODEST_TNY_SEND_QUEUE_FAILED:
259 /* Check if it already exists on queue */
260 existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_uid);
264 /* Check if its being edited */
265 mgr = modest_runtime_get_window_mgr ();
266 editing = modest_window_mgr_find_registered_header (mgr, header, NULL);
270 /* Add new meesage info */
271 info = g_slice_new0 (SendInfo);
272 info->msg_id = strdup(msg_uid);
273 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
274 g_queue_push_tail (priv->queue, info);
285 modest_tny_send_queue_add_async (TnySendQueue *self,
287 TnySendQueueAddCallback callback,
288 TnyStatusCallback status_callback,
291 /* Call the superclass passing our own callback */
292 TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg, _on_added_to_outbox, NULL, NULL);
297 modest_tny_send_queue_get_sentbox (TnySendQueue *self)
299 ModestTnySendQueuePrivate *priv;
301 g_return_val_if_fail (self, NULL);
303 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
305 return g_object_ref (priv->sentbox);
310 modest_tny_send_queue_get_outbox (TnySendQueue *self)
312 ModestTnySendQueuePrivate *priv;
314 g_return_val_if_fail (self, NULL);
316 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
318 return g_object_ref (priv->outbox);
322 modest_tny_send_queue_get_type (void)
324 static GType my_type = 0;
327 static const GTypeInfo my_info = {
328 sizeof(ModestTnySendQueueClass),
329 NULL, /* base init */
330 NULL, /* base finalize */
331 (GClassInitFunc) modest_tny_send_queue_class_init,
332 NULL, /* class finalize */
333 NULL, /* class data */
334 sizeof(ModestTnySendQueue),
336 (GInstanceInitFunc) modest_tny_send_queue_instance_init,
340 my_type = g_type_register_static (TNY_TYPE_CAMEL_SEND_QUEUE,
341 "ModestTnySendQueue",
349 modest_tny_send_queue_class_init (ModestTnySendQueueClass *klass)
351 GObjectClass *gobject_class;
353 gobject_class = (GObjectClass*) klass;
355 parent_class = g_type_class_peek_parent (klass);
356 gobject_class->finalize = modest_tny_send_queue_finalize;
358 TNY_CAMEL_SEND_QUEUE_CLASS(klass)->add_async = modest_tny_send_queue_add_async;
359 TNY_CAMEL_SEND_QUEUE_CLASS(klass)->get_outbox = modest_tny_send_queue_get_outbox;
360 TNY_CAMEL_SEND_QUEUE_CLASS(klass)->get_sentbox = modest_tny_send_queue_get_sentbox;
361 klass->status_changed = NULL;
363 signals[STATUS_CHANGED_SIGNAL] =
364 g_signal_new ("status_changed",
365 G_TYPE_FROM_CLASS (gobject_class),
367 G_STRUCT_OFFSET (ModestTnySendQueueClass, status_changed),
369 modest_marshal_VOID__STRING_INT,
370 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
372 g_type_class_add_private (gobject_class, sizeof(ModestTnySendQueuePrivate));
376 modest_tny_send_queue_instance_init (GTypeInstance *instance, gpointer g_class)
378 ModestTnySendQueuePrivate *priv;
380 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (instance);
381 priv->queue = g_queue_new();
382 priv->current = NULL;
386 modest_tny_send_queue_finalize (GObject *obj)
388 ModestTnySendQueuePrivate *priv;
390 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (obj);
392 g_queue_foreach (priv->queue, (GFunc)modest_tny_send_queue_info_free, NULL);
393 g_queue_free (priv->queue);
395 g_object_unref (priv->outbox);
396 g_object_unref (priv->sentbox);
398 G_OBJECT_CLASS(parent_class)->finalize (obj);
402 TnyCamelTransportAccount *account;
403 ModestTnySendQueue *queue;
407 new_queue_get_headers_async_cb (TnyFolder *folder,
413 ModestTnySendQueue *self;
415 GetHeadersInfo *info;
417 info = (GetHeadersInfo *) user_data;
418 self = MODEST_TNY_SEND_QUEUE (info->queue);
420 /* In case of error set the transport account anyway */
421 if (cancelled || err)
424 /* Add messages to our internal queue */
425 iter = tny_list_create_iterator (headers);
426 while (!tny_iterator_is_done (iter)) {
427 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
428 _add_message (self, header);
429 g_object_unref (header);
430 tny_iterator_next (iter);
433 /* Reenable suspended items */
434 modest_tny_send_queue_wakeup (self);
437 g_object_unref (iter);
438 g_object_unref (headers);
441 /* Do this at the end, because it'll call tny_send_queue_flush
442 which will call tny_send_queue_get_outbox and
443 tny_send_queue_get_sentbox */
444 tny_camel_send_queue_set_transport_account (TNY_CAMEL_SEND_QUEUE(self),
448 g_object_unref (info->account);
449 g_object_unref (info->queue);
450 g_slice_free (GetHeadersInfo, info);
454 modest_tny_send_queue_new (TnyCamelTransportAccount *account)
456 ModestTnySendQueue *self = NULL;
457 ModestTnySendQueuePrivate *priv = NULL;
458 TnyList *headers = NULL;
459 GetHeadersInfo *info;
461 g_return_val_if_fail (TNY_IS_CAMEL_TRANSPORT_ACCOUNT(account), NULL);
463 self = MODEST_TNY_SEND_QUEUE(g_object_new(MODEST_TYPE_TNY_SEND_QUEUE, NULL));
465 /* Connect signals to control when a msg is being or has been sent */
466 g_signal_connect (G_OBJECT(self), "msg-sending",
467 G_CALLBACK(_on_msg_start_sending),
469 g_signal_connect (G_OBJECT(self), "msg-sent",
470 G_CALLBACK(_on_msg_has_been_sent),
472 g_signal_connect (G_OBJECT(self), "error-happened",
473 G_CALLBACK(_on_msg_error_happened),
475 g_signal_connect (G_OBJECT (self), "queue-start",
476 G_CALLBACK (_on_queue_start),
479 /* Set outbox and sentbox */
480 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
481 priv->outbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account),
482 TNY_FOLDER_TYPE_OUTBOX);
483 priv->sentbox = modest_tny_account_get_special_folder (TNY_ACCOUNT(account),
484 TNY_FOLDER_TYPE_SENT);
485 priv->requested_send_receive = FALSE;
487 headers = tny_simple_list_new ();
488 info = g_slice_new0 (GetHeadersInfo);
489 info->account = g_object_ref (account);
490 info->queue = g_object_ref (self);
491 tny_folder_get_headers_async (priv->outbox, headers, TRUE,
492 new_queue_get_headers_async_cb,
499 modest_tny_send_queue_msg_is_being_sent (ModestTnySendQueue* self,
502 ModestTnySendQueueStatus status;
504 g_return_val_if_fail (msg_id != NULL, FALSE);
506 status = modest_tny_send_queue_get_msg_status (self, msg_id);
507 return status == MODEST_TNY_SEND_QUEUE_SENDING;
511 modest_tny_send_queue_sending_in_progress (ModestTnySendQueue* self)
513 ModestTnySendQueuePrivate *priv;
515 g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), FALSE);
517 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
519 return priv->current != NULL;
522 ModestTnySendQueueStatus
523 modest_tny_send_queue_get_msg_status (ModestTnySendQueue *self, const gchar *msg_id)
527 g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), MODEST_TNY_SEND_QUEUE_UNKNOWN);
528 g_return_val_if_fail (msg_id, MODEST_TNY_SEND_QUEUE_UNKNOWN);
530 item = modest_tny_send_queue_lookup_info (self, msg_id);
532 return MODEST_TNY_SEND_QUEUE_UNKNOWN;
534 return ((SendInfo*)item->data)->status;
538 modest_tny_send_queue_get_msg_id (TnyHeader *header)
540 gchar* msg_uid = NULL;
542 time_t date_received;
544 g_return_val_if_fail (header && TNY_IS_HEADER(header), NULL);
546 /* Get message uid */
547 subject = tny_header_dup_subject (header);
548 date_received = tny_header_get_date_received (header);
550 msg_uid = g_strdup_printf ("%s %d", subject, (int) date_received);
558 _on_msg_start_sending (TnySendQueue *self, TnyHeader *header,
559 TnyMsg *msg, int done, int total, gpointer user_data)
561 ModestTnySendQueuePrivate *priv = NULL;
563 SendInfo *info = NULL;
564 gchar *msg_id = NULL;
566 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
568 /* Get message uid */
569 msg_id = modest_tny_send_queue_get_msg_id (header);
571 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
573 g_warning ("%s: could not get msg-id for header", __FUNCTION__);
576 /* Set current status item */
578 info->status = MODEST_TNY_SEND_QUEUE_SENDING;
579 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
580 priv->current = item;
582 g_warning ("%s: could not find item with id '%s'", __FUNCTION__, msg_id);
589 _on_msg_has_been_sent (TnySendQueue *self,
596 ModestTnySendQueuePrivate *priv;
597 gchar *msg_id = NULL;
600 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
602 /* Get message uid */
603 msg_id = modest_tny_send_queue_get_msg_id (header);
605 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
607 tny_folder_sync_async (priv->sentbox, FALSE, NULL, NULL, NULL);
609 /* Get status info */
610 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
613 /* TODO: note that item=NULL must not happen, but I found that
614 tinymail is issuing the message-sent signal twice, because
615 tny_camel_send_queue_update is called twice for each
616 message sent. This must be fixed in tinymail. Sergio */
618 /* Remove status info */
619 modest_tny_send_queue_info_free (item->data);
620 g_queue_delete_link (priv->queue, item);
621 priv->current = NULL;
623 modest_platform_information_banner (NULL, NULL, _("mcen_ib_message_sent"));
631 _on_msg_error_happened (TnySendQueue *self,
637 ModestTnySendQueuePrivate *priv = NULL;
639 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
641 /* Note that header could be NULL. Tinymail notifies about
642 generic send queue errors with this signal as well, and
643 those notifications are not bound to any particular header
645 if (header && TNY_IS_HEADER (header)) {
646 SendInfo *info = NULL;
648 gchar* msg_uid = NULL;
650 /* Get sending info (create new if it doesn not exist) */
651 msg_uid = modest_tny_send_queue_get_msg_id (header);
652 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self),
655 /* TODO: this should not happen (but it does), so the
656 problem should be located in the way we generate
659 g_warning ("%s: could not find item with id '%s'", __FUNCTION__, msg_uid);
666 /* Keep in queue so that we remember that the opertion has failed */
667 /* and was not just cancelled */
668 if (err->code == TNY_SYSTEM_ERROR_CANCEL)
669 info->status = MODEST_TNY_SEND_QUEUE_SUSPENDED;
671 info->status = MODEST_TNY_SEND_QUEUE_FAILED;
672 priv->current = NULL;
674 /* Notify status has changed */
675 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
683 _on_queue_start (TnySendQueue *self,
686 ModestMailOperation *mail_op;
688 mail_op = modest_mail_operation_new (NULL);
689 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
691 modest_mail_operation_run_queue (mail_op, MODEST_TNY_SEND_QUEUE (self));
692 g_object_unref (mail_op);
696 fill_list_of_caches (gpointer key, gpointer value, gpointer userdata)
698 GSList **send_queues = (GSList **) userdata;
699 *send_queues = g_slist_prepend (*send_queues, value);
702 /* This function shouldn't be here. Move it to another place. Sergio */
703 ModestTnySendQueueStatus
704 modest_tny_all_send_queues_get_msg_status (TnyHeader *header)
706 ModestCacheMgr *cache_mgr = NULL;
707 GHashTable *send_queue_cache = NULL;
708 ModestTnyAccountStore *accounts_store = NULL;
709 TnyList *accounts = NULL;
710 TnyIterator *iter = NULL;
711 TnyTransportAccount *account = NULL;
712 GSList *send_queues = NULL, *node;
713 /* get_msg_status returns suspended by default, so we want to detect changes */
714 ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_UNKNOWN;
715 ModestTnySendQueueStatus queue_status = MODEST_TNY_SEND_QUEUE_UNKNOWN;
716 gchar *msg_uid = NULL;
717 ModestTnySendQueue *send_queue = NULL;
719 g_return_val_if_fail (TNY_IS_HEADER(header), MODEST_TNY_SEND_QUEUE_UNKNOWN);
721 msg_uid = modest_tny_send_queue_get_msg_id (header);
722 cache_mgr = modest_runtime_get_cache_mgr ();
723 send_queue_cache = modest_cache_mgr_get_cache (cache_mgr,
724 MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE);
726 g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues);
727 if (send_queues == NULL) {
728 accounts = tny_simple_list_new ();
729 accounts_store = modest_runtime_get_account_store ();
730 tny_account_store_get_accounts (TNY_ACCOUNT_STORE(accounts_store),
732 TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS);
734 iter = tny_list_create_iterator (accounts);
735 while (!tny_iterator_is_done (iter)) {
736 account = TNY_TRANSPORT_ACCOUNT(tny_iterator_get_current (iter));
737 send_queue = modest_runtime_get_send_queue(TNY_TRANSPORT_ACCOUNT(account), TRUE);
738 g_object_unref(account);
740 queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid);
741 if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) {
742 status = queue_status;
745 tny_iterator_next (iter);
747 g_object_unref (iter);
748 g_object_unref (accounts);
751 for (node = send_queues; node != NULL; node = g_slist_next (node)) {
752 send_queue = MODEST_TNY_SEND_QUEUE (node->data);
754 queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid);
755 if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) {
756 status = queue_status;
763 g_slist_free (send_queues);
768 wakeup_get_headers_async_cb (TnyFolder *folder,
774 ModestTnySendQueue *self;
775 ModestTnySendQueuePrivate *priv;
778 self = MODEST_TNY_SEND_QUEUE (user_data);
779 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
781 if (cancelled || err) {
782 g_debug ("Failed to wake up the headers of the send queue");
783 g_object_unref (self);
787 /* Wake up every single suspended header */
788 iter = tny_list_create_iterator (headers);
789 while (!tny_iterator_is_done (iter)) {
790 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
792 if (tny_header_get_flags (header) & TNY_HEADER_FLAG_SUSPENDED) {
797 /* Unset the suspended flag */
798 tny_header_unset_flag (header, TNY_HEADER_FLAG_SUSPENDED);
801 msg_id = modest_tny_send_queue_get_msg_id (header);
802 item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id);
803 info = (SendInfo *) item->data;
804 info->status = MODEST_TNY_SEND_QUEUE_WAITING;
805 g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status);
812 g_object_unref (header);
813 tny_iterator_next (iter);
816 /* Make changes persistent on disk */
817 tny_folder_sync_async (priv->outbox, FALSE, NULL, NULL, NULL);
820 g_object_unref (iter);
821 g_object_unref (headers);
822 g_object_unref (self);
827 modest_tny_send_queue_wakeup (ModestTnySendQueue *self)
829 ModestTnySendQueuePrivate *priv;
832 g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
834 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
836 headers = tny_simple_list_new ();
837 tny_folder_get_headers_async (priv->outbox, headers, TRUE,
838 wakeup_get_headers_async_cb,
839 NULL, g_object_ref (self));
843 modest_tny_send_queue_get_requested_send_receive (ModestTnySendQueue *self)
845 ModestTnySendQueuePrivate *priv;
847 g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE (self), FALSE);
848 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
850 return priv->requested_send_receive;
854 modest_tny_send_queue_set_requested_send_receive (ModestTnySendQueue *self, gboolean requested_send_receive)
856 ModestTnySendQueuePrivate *priv;
858 g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self));
859 priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self);
861 priv->requested_send_receive = requested_send_receive;