X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-tny-send-queue.c;h=aa5169fe21815a9e356ad9fe31d0f8a68aec41d8;hp=3fc3bdaae9b001e1fd7393cd3b46fdd29e147887;hb=81bb7fae864f7a1c81d2bccc082e11eaee1a7bd6;hpb=89cf071908dcf0cc57c747e3e2621ce3ae8a4670 diff --git a/src/modest-tny-send-queue.c b/src/modest-tny-send-queue.c index 3fc3bda..aa5169f 100644 --- a/src/modest-tny-send-queue.c +++ b/src/modest-tny-send-queue.c @@ -192,6 +192,11 @@ modest_tny_send_queue_to_string (ModestTnySendQueue *self) return str; } +typedef struct { + TnySendQueueAddCallback callback; + gpointer user_data; +} AddAsyncHelper; + static void _on_added_to_outbox (TnySendQueue *self, gboolean cancelled, @@ -204,6 +209,7 @@ _on_added_to_outbox (TnySendQueue *self, SendInfo *info = NULL; GList* existing = NULL; gchar* msg_id = NULL; + AddAsyncHelper *helper; g_return_if_fail (TNY_IS_SEND_QUEUE(self)); g_return_if_fail (TNY_IS_CAMEL_MSG(msg)); @@ -231,6 +237,12 @@ _on_added_to_outbox (TnySendQueue *self, end: g_object_unref (G_OBJECT(header)); + + /* Call the user callback */ + helper = (AddAsyncHelper *) user_data; + if (helper->callback) + helper->callback (self, cancelled, msg, err, helper->user_data); + g_slice_free (AddAsyncHelper, helper); } static void @@ -268,7 +280,7 @@ _add_message (ModestTnySendQueue *self, TnyHeader *header) break; /* Add new meesage info */ - info = g_slice_new (SendInfo); + info = g_slice_new0 (SendInfo); info->msg_id = strdup(msg_uid); info->status = MODEST_TNY_SEND_QUEUE_WAITING; g_queue_push_tail (priv->queue, info); @@ -288,8 +300,15 @@ modest_tny_send_queue_add_async (TnySendQueue *self, TnyStatusCallback status_callback, gpointer user_data) { + AddAsyncHelper *helper = g_slice_new0 (AddAsyncHelper); + helper->callback = callback; + helper->user_data = user_data; + /* Call the superclass passing our own callback */ - TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg, _on_added_to_outbox, NULL, NULL); + TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_async (self, msg, + _on_added_to_outbox, + status_callback, + helper); } @@ -380,6 +399,8 @@ modest_tny_send_queue_instance_init (GTypeInstance *instance, gpointer g_class) priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (instance); priv->queue = g_queue_new(); priv->current = NULL; + priv->outbox = NULL; + priv->sentbox = NULL; } static void @@ -392,10 +413,61 @@ 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_CLASS(parent_class)->finalize (obj); g_object_unref (priv->outbox); g_object_unref (priv->sentbox); +} - G_OBJECT_CLASS(parent_class)->finalize (obj); +typedef struct { + TnyCamelTransportAccount *account; + ModestTnySendQueue *queue; +} GetHeadersInfo; + +static void +new_queue_get_headers_async_cb (TnyFolder *folder, + gboolean cancelled, + TnyList *headers, + GError *err, + gpointer user_data) +{ + ModestTnySendQueue *self; + TnyIterator *iter; + GetHeadersInfo *info; + + info = (GetHeadersInfo *) user_data; + self = MODEST_TNY_SEND_QUEUE (info->queue); + + /* In case of error set the transport account anyway */ + if (cancelled || err) + goto set_transport; + + /* Add messages to our internal queue */ + iter = tny_list_create_iterator (headers); + while (!tny_iterator_is_done (iter)) { + TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); + _add_message (self, header); + g_object_unref (header); + tny_iterator_next (iter); + } + + /* Reenable suspended items */ + modest_tny_send_queue_wakeup (self); + + /* Frees */ + g_object_unref (iter); + g_object_unref (headers); + + set_transport: + /* 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), + info->account); + + /* Frees */ + g_object_unref (info->account); + g_object_unref (info->queue); + g_slice_free (GetHeadersInfo, info); } ModestTnySendQueue* @@ -403,13 +475,27 @@ modest_tny_send_queue_new (TnyCamelTransportAccount *account) { ModestTnySendQueue *self = NULL; ModestTnySendQueuePrivate *priv = NULL; - TnyIterator *iter = NULL; TnyList *headers = NULL; + GetHeadersInfo *info; 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)); - + + /* 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); + + /* NOTE that this could happen if there was not enough disk + space when the account was created */ + if (!priv->outbox || !priv->sentbox) { + g_object_unref (self); + return NULL; + } + /* 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), @@ -424,41 +510,16 @@ modest_tny_send_queue_new (TnyCamelTransportAccount *account) G_CALLBACK (_on_queue_start), NULL); - /* 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); priv->requested_send_receive = FALSE; - - 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)) { - TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); - _add_message (self, header); - g_object_unref (header); - - tny_iterator_next (iter); - } - - /* Reenable suspended items */ - modest_tny_send_queue_wakeup (self); - - /* Frees */ - g_object_unref (headers); - 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); + headers = tny_simple_list_new (); + info = g_slice_new0 (GetHeadersInfo); + info->account = g_object_ref (account); + info->queue = g_object_ref (self); + tny_folder_get_headers_async (priv->outbox, headers, TRUE, + new_queue_get_headers_async_cb, + NULL, info); return self; } @@ -633,10 +694,38 @@ _on_msg_error_happened (TnySendQueue *self, /* Keep in queue so that we remember that the opertion has failed */ /* and was not just cancelled */ - if (err->code == TNY_SYSTEM_ERROR_CANCEL) + if (err->code == TNY_SYSTEM_ERROR_CANCEL) { info->status = MODEST_TNY_SEND_QUEUE_SUSPENDED; - else + } else { + if (err->code == TNY_SERVICE_ERROR_CONNECT) { + TnyCamelTransportAccount* transport; + TnyTransportAccount *conn_specific; + + transport = tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)); + if (transport) { + gchar *message; + ModestTnyAccountStore *acc_store; + const gchar *acc_name; + + acc_store = modest_runtime_get_account_store(); + acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport)); + conn_specific = (TnyTransportAccount *) + modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name); + if (conn_specific) { + message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), + tny_account_get_hostname (TNY_ACCOUNT (conn_specific))); + g_object_unref (conn_specific); + } else { + message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), + tny_account_get_hostname (TNY_ACCOUNT (transport))); + } + modest_platform_run_alert_dialog (message, FALSE); + g_free (message); + g_object_unref (transport); + } + } info->status = MODEST_TNY_SEND_QUEUE_FAILED; + } priv->current = NULL; /* Notify status has changed */ @@ -704,11 +793,12 @@ modest_tny_all_send_queues_get_msg_status (TnyHeader *header) account = TNY_TRANSPORT_ACCOUNT(tny_iterator_get_current (iter)); send_queue = modest_runtime_get_send_queue(TNY_TRANSPORT_ACCOUNT(account), TRUE); g_object_unref(account); - - queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid); - if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) { - status = queue_status; - break; + if (TNY_IS_SEND_QUEUE (send_queue)) { + queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid); + if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) { + status = queue_status; + break; + } } tny_iterator_next (iter); } @@ -732,19 +822,25 @@ modest_tny_all_send_queues_get_msg_status (TnyHeader *header) return status; } -void -modest_tny_send_queue_wakeup (ModestTnySendQueue *self) +static void +wakeup_get_headers_async_cb (TnyFolder *folder, + gboolean cancelled, + TnyList *headers, + GError *err, + gpointer user_data) { + ModestTnySendQueue *self; ModestTnySendQueuePrivate *priv; - TnyList *headers; TnyIterator *iter; - g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (self)); - + self = MODEST_TNY_SEND_QUEUE (user_data); priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); - headers = tny_simple_list_new (); - tny_folder_get_headers (priv->outbox, headers, TRUE, NULL); + if (cancelled || err) { + g_debug ("Failed to wake up the headers of the send queue"); + g_object_unref (self); + return; + } /* Wake up every single suspended header */ iter = tny_list_create_iterator (headers); @@ -762,12 +858,16 @@ modest_tny_send_queue_wakeup (ModestTnySendQueue *self) /* 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; + if (!item) { + info = g_slice_new (SendInfo); + info->msg_id = msg_id; + g_queue_push_tail (priv->queue, info); + } else { + info = (SendInfo *) item->data; + g_free (msg_id); + } 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); + g_signal_emit (self, signals[STATUS_CHANGED_SIGNAL], 0, info->msg_id, info->status); } /* Frees */ @@ -780,7 +880,25 @@ modest_tny_send_queue_wakeup (ModestTnySendQueue *self) /* Frees */ g_object_unref (iter); - g_object_unref (G_OBJECT (headers)); + g_object_unref (headers); + g_object_unref (self); +} + + +void +modest_tny_send_queue_wakeup (ModestTnySendQueue *self) +{ + ModestTnySendQueuePrivate *priv; + TnyList *headers; + + 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_async (priv->outbox, headers, TRUE, + wakeup_get_headers_async_cb, + NULL, g_object_ref (self)); } gboolean