X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-tny-send-queue.c;h=522a83a732d449991b4d544e86994f1d8397eabf;hp=72c918aeae0ae398530389d3eae6282c2a4306b9;hb=40a8f5cbe03bd040fe3403dbfa6806df4fb6bc8a;hpb=0344beb7b1e6a60f4b6605c7c6d49fedfdd02676 diff --git a/src/modest-tny-send-queue.c b/src/modest-tny-send-queue.c index 72c918a..522a83a 100644 --- a/src/modest-tny-send-queue.c +++ b/src/modest-tny-send-queue.c @@ -34,6 +34,9 @@ #include #include #include +#include +#include +#include #include #include /* strcmp */ @@ -43,10 +46,12 @@ static void modest_tny_send_queue_finalize (GObject *obj); static void modest_tny_send_queue_instance_init (GTypeInstance *instance, gpointer g_class); /* Signal handlers */ -static void _on_msg_start_sending (TnySendQueue *self, TnyMsg *msg, gpointer user_data); -static void _on_msg_has_been_sent (TnySendQueue *self, TnyMsg *msg, gpointer user_data); +static void _on_msg_start_sending (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, int done, int total, gpointer user_data); +static void _on_msg_has_been_sent (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, int done, int total, gpointer user_data); static void _on_msg_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, gpointer user_data); +static TnyFolder*modest_tny_send_queue_get_outbox (TnySendQueue *self); +static TnyFolder*modest_tny_send_queue_get_sentbox (TnySendQueue *self); /* list my signals */ enum { @@ -113,6 +118,10 @@ 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) @@ -127,37 +136,67 @@ modest_tny_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err) 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)); + 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_unset_flags (header, TNY_HEADER_FLAG_PRIORITY); + tny_header_set_flags (header, TNY_HEADER_FLAG_SUSPENDED_PRIORITY); + 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 modest_tny_send_queue_add (TnySendQueue *self, TnyMsg *msg, GError **err) { ModestTnySendQueuePrivate *priv; - TnyHeader *header; - SendInfo *info; - GList* existing; - const gchar* msg_id; + TnyHeader *header = NULL; + SendInfo *info = NULL; + GList* existing = NULL; + const gchar* msg_id = NULL; g_return_if_fail (TNY_IS_SEND_QUEUE(self)); g_return_if_fail (TNY_IS_CAMEL_MSG(msg)); priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); header = tny_msg_get_header (msg); - - /* FIXME: do something smart here... */ - + /* Note that this call actually sets the message id to something * sensible. */ TNY_CAMEL_SEND_QUEUE_CLASS(parent_class)->add_func (self, msg, err); /* FIXME */ /* Check whether the mail is already in the queue */ - msg_id = tny_header_get_message_id (header); +/* msg_id = tny_header_get_message_id (header); */ + msg_id = tny_header_get_uid (header); + g_return_if_fail (msg_id != NULL); existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_id); if(existing != NULL) { - g_assert(info->status == MODEST_TNY_SEND_QUEUE_SUSPENDED || - info->status == MODEST_TNY_SEND_QUEUE_FAILED); + //g_assert(info->status == MODEST_TNY_SEND_QUEUE_SUSPENDED || + // info->status == MODEST_TNY_SEND_QUEUE_FAILED); info = existing->data; info->status = MODEST_TNY_SEND_QUEUE_WAITING; @@ -173,6 +212,58 @@ modest_tny_send_queue_add (TnySendQueue *self, TnyMsg *msg, GError **err) } g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); + + /* free */ + g_object_unref (header); +} + +static void +_add_message (ModestTnySendQueue *self, TnyHeader *header) +{ + ModestWindowMgr *mgr = NULL; + ModestTnySendQueuePrivate *priv; + SendInfo *info = NULL; + GList* existing = NULL; + gchar* msg_uid = NULL; + ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_WAITING; + gboolean editing = FALSE; + + g_return_if_fail (TNY_IS_SEND_QUEUE(self)); + g_return_if_fail (TNY_IS_HEADER(header)); + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); + + /* Check whether the mail is already in the queue */ + msg_uid = modest_tny_send_queue_get_msg_id (header); + status = modest_tny_send_queue_get_msg_status (self, msg_uid); + switch (status) { + case MODEST_TNY_SEND_QUEUE_UNKNONW: + case MODEST_TNY_SEND_QUEUE_SUSPENDED: + case MODEST_TNY_SEND_QUEUE_FAILED: + if (status != MODEST_TNY_SEND_QUEUE_SUSPENDED) + tny_header_unset_flags (header, TNY_HEADER_FLAG_PRIORITY); + + /* Check if it already exists on queue */ + existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_uid); + if(existing != NULL) return; + + /* Check if its being edited */ + mgr = modest_runtime_get_window_mgr (); + editing = modest_window_mgr_find_registered_header (mgr, header, NULL); + if (editing) return; + + /* Add new meesage info */ + info = g_slice_new (SendInfo); + info->msg_id = strdup(msg_uid); + info->status = MODEST_TNY_SEND_QUEUE_WAITING; + g_queue_push_tail (priv->queue, info); + break; + default: + goto frees; + } + + /* Free */ + frees: + g_free(msg_uid); } static TnyFolder* @@ -211,6 +302,12 @@ modest_tny_send_queue_get_outbox (TnySendQueue *self) } 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)); return folder; @@ -306,14 +403,9 @@ modest_tny_send_queue_new (TnyCamelTransportAccount *account) account); /* Connect signals to control when a msg is being or has been sent */ - /* TODO: this signal was implemented in tinymail camel send queue, but im - waiting for implement some unit tests nbefore commited changes */ - if (FALSE) { - g_signal_connect (G_OBJECT(self), "msg-sending", - G_CALLBACK(_on_msg_start_sending), - NULL); - } - + g_signal_connect (G_OBJECT(self), "msg-sending", + G_CALLBACK(_on_msg_start_sending), + NULL); g_signal_connect (G_OBJECT(self), "msg-sent", G_CALLBACK(_on_msg_has_been_sent), NULL); @@ -328,27 +420,54 @@ modest_tny_send_queue_new (TnyCamelTransportAccount *account) void modest_tny_send_queue_try_to_send (ModestTnySendQueue* self) { - /* TODO: Rename this to tny_camel_send_queue_try_to_send() in tinymail - and check that it works, without creating a second worker. */ -/* tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE(self)); */ + TnyIterator *iter = NULL; + TnyFolder *outbox = NULL; + TnyList *headers = tny_simple_list_new (); + TnyHeader *header = NULL; + GError *err = NULL; + + 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; + + 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); + } + + 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); } -#if 0 gboolean modest_tny_send_queue_msg_is_being_sent (ModestTnySendQueue* self, const gchar *msg_id) { - ModestTnySendQueuePrivate *priv; + ModestTnySendQueueStatus status; g_return_val_if_fail (msg_id != NULL, FALSE); - priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); - if (modest_tny_send_queue_sending_in_progress(self)) - return g_ascii_strcasecmp(priv->current_msg_id, msg_id); - else - return FALSE; + status = modest_tny_send_queue_get_msg_status (self, msg_id); + return status == MODEST_TNY_SEND_QUEUE_SENDING; } -#endif gboolean modest_tny_send_queue_sending_in_progress (ModestTnySendQueue* self) @@ -364,93 +483,130 @@ modest_tny_send_queue_get_msg_status (ModestTnySendQueue *self, const gchar *msg { GList *item; item = modest_tny_send_queue_lookup_info (self, msg_id); - if(item == NULL) return MODEST_TNY_SEND_QUEUE_SUSPENDED; + if(item == NULL) return MODEST_TNY_SEND_QUEUE_UNKNONW; return ((SendInfo*)item->data)->status; } -static void +gchar * +modest_tny_send_queue_get_msg_id (TnyHeader *header) +{ + const gchar *uid = NULL; + gchar* msg_uid = NULL; + gchar **tmp = NULL; + + /* Get message uid */ + uid = tny_header_get_uid (header); + tmp = g_strsplit (uid, "__", 2); + if (tmp[1] != NULL) + msg_uid = g_strconcat (tmp[0], "_", NULL); + else + msg_uid = g_strdup(tmp[0]); + + /* free */ + g_strfreev(tmp); + + return msg_uid; +} + + +static void _on_msg_start_sending (TnySendQueue *self, + TnyHeader *header, TnyMsg *msg, + int done, + int total, gpointer user_data) { - ModestTnySendQueuePrivate *priv; - TnyHeader *header; - GList *item; - SendInfo *info; + ModestTnySendQueuePrivate *priv = NULL; + GList *item = NULL; + SendInfo *info = NULL; + gchar *msg_id = NULL; priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); + + /* Get message uid */ + msg_id = modest_tny_send_queue_get_msg_id (header); - header = tny_msg_get_header(msg); - item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), tny_header_get_message_id (header)); - - if (item != NULL) - { - info = item->data; - info->status = MODEST_TNY_SEND_QUEUE_SENDING; - - g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); - } - + /* Get status info */ + item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id); + g_return_if_fail (item != NULL); + 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; + + /* free */ + g_free (msg_id); } static void _on_msg_has_been_sent (TnySendQueue *self, + TnyHeader *header, TnyMsg *msg, + int done, + int total, gpointer user_data) { ModestTnySendQueuePrivate *priv; - TnyHeader *header; GList *item; + gchar *msg_id = NULL; priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); - header = tny_msg_get_header (msg); - - /* TODO: Use this version as soon as the msg-sending - * notification works */ -#if 0 - item = priv->current; - g_assert(item != NULL); -#else - item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), tny_header_get_message_id(header)); - g_assert(item != NULL); -#endif + /* Get message uid */ + msg_id = modest_tny_send_queue_get_msg_id (header); + + /* Get status info */ + item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id); + g_return_if_fail(item != 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")); + + /* free */ + g_free(msg_id); } -static void _on_msg_error_happened (TnySendQueue *self, - TnyHeader *header, - TnyMsg *msg, - GError *err, - gpointer user_data) +static void +_on_msg_error_happened (TnySendQueue *self, + TnyHeader *header, + TnyMsg *msg, + GError *err, + gpointer user_data) { - ModestTnySendQueuePrivate *priv; - SendInfo *info; - GList *item; - + ModestTnySendQueuePrivate *priv = NULL; + SendInfo *info = NULL; + GList *item = NULL; + gchar* msg_uid = NULL; + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); + + /* Get sending info (create new if it doesn not exist) */ + 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 = strdup(msg_uid); + g_queue_push_tail (priv->queue, info); + } + else { + info = item->data; + } - /* TODO: Use this version as soon as the msg-sending - * notification works */ -#if 0 - item = priv->current; - g_assert(item != NULL); - info = priv->current->data; -#else - /* TODO: Why do we get the msg and its header separately? The docs - * don't really tell. */ - g_assert(header == tny_msg_get_header (msg)); // ???? - item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), tny_header_get_message_id (header)); - g_assert(item != NULL); - info = item->data; -#endif - - /* Keep in queue so that we remember that the opertion has failed - * and was not just cancelled */ + /* Keep in queue so that we remember that the opertion has failed */ + /* and was not just cancelled */ info->status = MODEST_TNY_SEND_QUEUE_FAILED; + + /* Notify status has changed */ g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); + + /* free */ + g_free(msg_uid); }