#include <tny-simple-list.h>
#include <tny-send-queue.h>
#include <tny-status.h>
+#include <tny-error.h>
#include <tny-folder-observer.h>
#include <camel/camel-stream-mem.h>
#include <glib/gi18n.h>
+#include <modest-defs.h>
#include "modest-platform.h"
#include "modest-account-mgr-helpers.h"
#include <modest-tny-account.h>
static gboolean _check_memory_low (ModestMailOperation *mail_op);
+
+typedef struct {
+ ModestTnySendQueue *queue;
+ ModestMailOperation *self;
+ guint error_handler;
+ guint start_handler;
+ guint stop_handler;
+} RunQueueHelper;
+
+static void run_queue_notify_and_destroy (RunQueueHelper *helper,
+ ModestMailOperationStatus status);
+
/* Helpers for the update account operation (send & receive)*/
typedef struct
{
} SendNewMailHelper;
static void
-send_mail_common_cb (gboolean cancelled,
- GError *err,
- SendNewMailHelper *helper)
+send_mail_on_sync_async_cb (TnyFolder *folder,
+ gboolean cancelled,
+ GError *err,
+ gpointer user_data)
{
ModestMailOperationPrivate *priv;
ModestMailOperation *self;
+ SendNewMailHelper *helper;
+ helper = (SendNewMailHelper *) user_data;
self = helper->mail_op;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
}
static void
-send_mail_on_sync_async_cb (TnyFolder *self,
- gboolean cancelled,
- GError *err,
- gpointer user_data)
+run_queue_start (TnySendQueue *self,
+ gpointer user_data)
+{
+ RunQueueHelper *helper = (RunQueueHelper *) user_data;
+ ModestMailOperation *mail_op;
+
+ g_debug ("%s sending queue successfully started", __FUNCTION__);
+
+ /* Wait for the message to be sent */
+ mail_op = modest_mail_operation_new (NULL);
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+ mail_op);
+ modest_mail_operation_run_queue (mail_op, helper->queue);
+ g_object_unref (mail_op);
+
+ /* Free the helper and end operation */
+ run_queue_notify_and_destroy (helper, MODEST_MAIL_OPERATION_STATUS_SUCCESS);
+}
+
+static void
+run_queue_error_happened (TnySendQueue *queue,
+ TnyHeader *header,
+ TnyMsg *msg,
+ GError *error,
+ gpointer user_data)
{
- send_mail_common_cb (cancelled, err, (SendNewMailHelper *) user_data);
+ RunQueueHelper *helper = (RunQueueHelper *) user_data;
+ ModestMailOperationPrivate *priv;
+
+ /* If we are here this means that the send queue could not
+ start to send emails. Shouldn't happen as this means that
+ we could not create the thread */
+ g_debug ("%s sending queue failed to create the thread", __FUNCTION__);
+
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (helper->self);
+ priv->error = g_error_copy ((const GError *) error);
+
+ if (error->code != TNY_SYSTEM_ERROR_UNKNOWN) {
+ /* This code is here for safety reasons. It should
+ never be called, because that would mean that we
+ are not controlling some error case */
+ g_warning ("%s Error %s should not happen",
+ __FUNCTION__, error->message);
+ }
+
+ /* Free helper and end operation */
+ run_queue_notify_and_destroy (helper, MODEST_MAIL_OPERATION_STATUS_FAILED);
}
static void
GError *err,
gpointer user_data)
{
- send_mail_common_cb (cancelled, err, (SendNewMailHelper *) user_data);
+ ModestMailOperationPrivate *priv;
+ ModestMailOperation *self;
+ SendNewMailHelper *helper;
+
+ helper = (SendNewMailHelper *) user_data;
+ self = helper->mail_op;
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ if (cancelled || err)
+ goto end;
+
+ if (err) {
+ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_SEND_QUEUE_ADD_ERROR,
+ "Error adding a msg to the send queue\n");
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
+ } else {
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+ }
+
+ end:
+ if (helper->notify) {
+ TnyTransportAccount *trans_account;
+ ModestTnySendQueue *queue;
+
+ trans_account = (TnyTransportAccount *) modest_mail_operation_get_account (self);
+ queue = modest_runtime_get_send_queue (trans_account, TRUE);
+ if (queue) {
+ RunQueueHelper *helper;
+
+ /* Create the helper */
+ helper = g_slice_new0 (RunQueueHelper);
+ helper->queue = g_object_ref (queue);
+ helper->self = g_object_ref (self);
+
+ /* if sending is ongoing wait for the queue to
+ stop. Otherwise wait for the queue-start
+ signal. It could happen that the queue
+ could not start, then check also the error
+ happened signal */
+ if (modest_tny_send_queue_sending_in_progress (queue)) {
+ run_queue_start (TNY_SEND_QUEUE (queue), helper);
+ } else {
+ helper->start_handler = g_signal_connect (queue, "queue-start",
+ G_CALLBACK (run_queue_start),
+ helper);
+ helper->error_handler = g_signal_connect (queue, "error-happened",
+ G_CALLBACK (run_queue_error_happened),
+ helper);
+ }
+ } else {
+ /* Finalize this mail operation */
+ modest_mail_operation_notify_end (self);
+ }
+ g_object_unref (trans_account);
+ }
+
+ g_object_unref (helper->mail_op);
+ g_slice_free (SendNewMailHelper, helper);
}
static gboolean
TnyHeader *header = tny_msg_get_header (info->draft_msg);
TnyFolder *src_folder = tny_header_get_folder (header);
+ g_debug ("--- REMOVE AND SYNC");
/* Remove the old draft */
tny_folder_remove_msg (src_folder, header, NULL);
/* Synchronize to expunge and to update the msg counts */
tny_folder_sync_async (info->drafts, TRUE, NULL, NULL, NULL);
tny_folder_sync_async (src_folder, TRUE, NULL, NULL, NULL);
+ g_debug ("--- REMOVED - SYNCED");
g_object_unref (G_OBJECT(header));
g_object_unref (G_OBJECT(src_folder));
}
if (!priv->error || priv->error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
- SaveToDraftsAddMsgInfo *cb_info = g_slice_new(SaveToDraftsAddMsgInfo);
- cb_info->transport_account = g_object_ref(info->transport_account);
- cb_info->draft_msg = info->draft_msg ? g_object_ref(info->draft_msg) : NULL;
- cb_info->callback = info->callback;
- cb_info->user_data = info->user_data;
- cb_info->drafts = g_object_ref(drafts);
- cb_info->msg = g_object_ref(msg);
- cb_info->mailop = g_object_ref(self);
- tny_folder_add_msg_async(drafts, msg, modest_mail_operation_save_to_drafts_add_msg_cb,
- NULL, cb_info);
+ if (drafts) {
+ SaveToDraftsAddMsgInfo *cb_info = g_slice_new(SaveToDraftsAddMsgInfo);
+ cb_info->transport_account = g_object_ref(info->transport_account);
+ cb_info->draft_msg = info->draft_msg ? g_object_ref(info->draft_msg) : NULL;
+ cb_info->callback = info->callback;
+ cb_info->user_data = info->user_data;
+ cb_info->drafts = g_object_ref(drafts);
+ cb_info->msg = g_object_ref(msg);
+ cb_info->mailop = g_object_ref(self);
+ tny_folder_add_msg_async(drafts, msg, modest_mail_operation_save_to_drafts_add_msg_cb,
+ NULL, cb_info);
+ }
} else {
/* Call the user callback */
priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
info->callback = callback;
info->user_data = user_data;
+ g_debug ("--- CREATE MESSAGE");
modest_mail_operation_notify_start (self);
modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body,
attachments_list, images_list, priority_flags,
static void
foreach_add_item (gpointer header, gpointer user_data)
{
- tny_list_prepend (TNY_LIST (user_data),
- G_OBJECT (header));
+ tny_list_append (TNY_LIST (user_data), G_OBJECT (header));
}
/* This is the method that looks for new messages in a folder */
return;
/* Get the transport account */
- transport_account = (TnyTransportAccount *)
- modest_tny_account_store_get_transport_account_for_open_connection (account_store,
- info->account_name);
+ transport_account = (TnyTransportAccount *)
+ modest_tny_account_store_get_server_account (account_store, info->account_name,
+ TNY_ACCOUNT_TYPE_TRANSPORT);
if (transport_account) {
ModestTnySendQueue *send_queue;
g_warning ("%s: could not get outbox", __FUNCTION__);
num_messages = 0;
}
-
+
if (num_messages != 0) {
+ ModestMailOperation *mail_op;
/* Reenable suspended items */
- modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
-
+ mail_op = modest_mail_operation_new (NULL);
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
+ mail_op);
+ modest_mail_operation_queue_wakeup (mail_op, MODEST_TNY_SEND_QUEUE (send_queue));
+
/* Try to send */
- tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
modest_tny_send_queue_set_requested_send_receive (MODEST_TNY_SEND_QUEUE (send_queue),
info->interactive);
}
UpdateAccountInfo *info;
ModestMailOperationPrivate *priv;
TnyIterator *new_headers_iter;
- GPtrArray *new_headers_array = NULL;
+ GPtrArray *new_headers_array = NULL;
gint max_size, retrieve_limit, i;
ModestAccountMgr *mgr;
ModestAccountRetrieveType retrieve_type;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
mgr = modest_runtime_get_account_mgr ();
- /* Set the last updated as the current time, do it even if the inbox refresh failed */
- modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time (NULL));
-
if (canceled || err) {
priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
if (err)
MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
"canceled");
- tny_folder_remove_observer (inbox, info->inbox_observer);
+ if (inbox)
+ tny_folder_remove_observer (inbox, info->inbox_observer);
g_object_unref (info->inbox_observer);
info->inbox_observer = NULL;
goto send_mail;
}
+ /* Set the last updated as the current time */
+ modest_account_mgr_set_last_updated (mgr, tny_account_get_id (priv->account), time (NULL));
+
/* Get the message max size */
max_size = modest_conf_get_int (modest_runtime_get_conf (),
MODEST_CONF_MSG_SIZE_LIMIT, NULL);
/* Apply per-message size limits */
if (tny_header_get_message_size (header) < max_size)
g_ptr_array_add (new_headers_array, g_object_ref (header));
-
+
g_object_unref (header);
tny_iterator_next (new_headers_iter);
}
retrieve_limit = modest_account_mgr_get_retrieve_limit (mgr, info->account_name);
if (retrieve_limit == 0)
retrieve_limit = G_MAXINT;
-
+
/* Get per-account retrieval type */
retrieve_type = modest_account_mgr_get_retrieve_type (mgr, info->account_name);
headers_only = (retrieve_type == MODEST_ACCOUNT_RETRIEVE_HEADERS_ONLY);
/* Order by date */
g_ptr_array_sort (new_headers_array, (GCompareFunc) compare_headers_by_date);
-
+
/* Ask the users if they want to retrieve all the messages
even though the limit was exceeded */
ignore_limit = FALSE;
}
g_ptr_array_foreach (new_headers_array, (GFunc) g_object_unref, NULL);
g_ptr_array_free (new_headers_array, FALSE);
-
+
if (!headers_only && (tny_list_get_length (new_headers) > 0)) {
gint msg_num = 0;
TnyIterator *iter;
msg_info->more_msgs = g_object_ref (iter);
msg_info->user_data = info;
- while ((msg_num < priv->total ) && !tny_iterator_is_done (iter)) {
+ while ((msg_num < priv->total ) && !tny_iterator_is_done (iter)) {
TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
TnyFolder *folder = tny_header_get_folder (header);
/* Get message in an async way */
- tny_folder_get_msg_async (folder, header, update_account_get_msg_async_cb,
+ tny_folder_get_msg_async (folder, header, update_account_get_msg_async_cb,
NULL, msg_info);
g_object_unref (folder);
-
+
msg_num++;
tny_iterator_next (iter);
}
/* If we don't have to retrieve the new messages then
simply send mail */
update_account_send_mail (info);
-
+
/* Check if the operation was a success */
if (!priv->error)
priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-
+
/* Call the user callback and free */
update_account_notify_user_and_free (info, new_headers);
}
/* We want the most recent ones (greater time_t) at the
beginning */
if (sent1 < sent2)
- return 1;
- else
return -1;
+ else
+ return 1;
}
g_slice_free (ModestMailOperationState, state);
}
-
static void
transfer_folder_cb (TnyFolder *folder,
gboolean cancelled,
ModestMailOperationPrivate *priv = NULL;
helper = (XFerFolderAsyncHelper *) user_data;
- g_return_if_fail (helper != NULL);
+ g_return_if_fail (helper != NULL);
self = helper->mail_op;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
priv->done = 1;
priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
}
-
+
+ /* Update state of new folder */
+ if (new_folder) {
+ tny_folder_refresh_async (new_folder, NULL, NULL, NULL);
+ tny_folder_poke_status (new_folder);
+ }
+
/* Notify about operation end */
modest_mail_operation_notify_end (self);
account_name);
account_proto = modest_tny_account_get_protocol_type (account);
g_object_unref (account);
-
- if (( (modest_protocol_registry_protocol_type_has_leave_on_server (protocol_registry, account_proto) && !leave_on_server) ||
- modest_tny_folder_is_remote_folder (folder) == FALSE))
+
+ if ((modest_protocol_registry_protocol_type_has_leave_on_server (protocol_registry, account_proto) &&
+ !leave_on_server) ||
+ !modest_tny_folder_is_remote_folder (folder))
expunge = TRUE;
else
expunge = FALSE;
-
+
/* Sync folder */
tny_folder_sync_async(folder, expunge, sync_folder_finish_callback,
NULL, self);
/* We know that tinymail sends us information about
* transferred bytes with this particular message
- *
- * (FIXME: this is very ugly, and no I (djcb) didn't write this code,
- * I just added the 'if' so we don't get runtime warning)
*/
if (status->message)
is_num_bytes = (g_ascii_strcasecmp (status->message, "Retrieving message") == 0);
}
static void
-run_queue_stop (ModestTnySendQueue *queue,
- ModestMailOperation *self)
+run_queue_notify_and_destroy (RunQueueHelper *helper,
+ ModestMailOperationStatus status)
{
ModestMailOperationPrivate *priv;
- g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
- g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (queue));
- priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+ /* Disconnect */
+ if (helper->error_handler &&
+ g_signal_handler_is_connected (helper->queue, helper->error_handler))
+ g_signal_handler_disconnect (helper->queue, helper->error_handler);
+ if (helper->start_handler &&
+ g_signal_handler_is_connected (helper->queue, helper->start_handler))
+ g_signal_handler_disconnect (helper->queue, helper->start_handler);
+ if (helper->stop_handler &&
+ g_signal_handler_is_connected (helper->queue, helper->stop_handler))
+ g_signal_handler_disconnect (helper->queue, helper->stop_handler);
- priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+ /* Set status */
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (helper->self);
+ priv->status = status;
- modest_mail_operation_notify_end (self);
- g_signal_handlers_disconnect_by_func (queue, run_queue_stop, self);
- g_object_unref (self);
+ /* Notify end */
+ modest_mail_operation_notify_end (helper->self);
+
+ /* Free data */
+ g_object_unref (helper->queue);
+ g_object_unref (helper->self);
+ g_slice_free (RunQueueHelper, helper);
+}
+
+static void
+run_queue_stop (ModestTnySendQueue *queue,
+ gpointer user_data)
+{
+ RunQueueHelper *helper;
+
+ g_debug ("%s sending queue stopped", __FUNCTION__);
+
+ helper = (RunQueueHelper *) user_data;
+ run_queue_notify_and_destroy (helper, MODEST_MAIL_OPERATION_STATUS_SUCCESS);
}
void
ModestTnySendQueue *queue)
{
ModestMailOperationPrivate *priv;
+ RunQueueHelper *helper;
g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (queue));
priv->account = TNY_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (queue)));
priv->op_type = MODEST_MAIL_OPERATION_TYPE_RUN_QUEUE;
+ /* Create the helper */
+ helper = g_slice_new0 (RunQueueHelper);
+ helper->queue = g_object_ref (queue);
+ helper->self = g_object_ref (self);
+ helper->stop_handler = g_signal_connect (queue, "queue-stop",
+ G_CALLBACK (run_queue_stop),
+ helper);
+
+ /* Notify operation has started */
modest_mail_operation_notify_start (self);
+ g_debug ("%s, run queue started", __FUNCTION__);
+}
+
+static void
+queue_wakeup_callback (ModestTnySendQueue *queue,
+ gboolean cancelled,
+ GError *error,
+ gpointer userdata)
+{
+ ModestMailOperation *mail_op;
+ ModestMailOperationPrivate *priv;
+
+ mail_op = (ModestMailOperation *) userdata;
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op);
+
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+ tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (queue));
+
+ /* Notify end */
+ modest_mail_operation_notify_end (mail_op);
+ g_object_unref (mail_op);
+}
+
+void
+modest_mail_operation_queue_wakeup (ModestMailOperation *self,
+ ModestTnySendQueue *queue)
+{
+ ModestMailOperationPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (queue));
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+ priv->account = TNY_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (queue)));
+ priv->op_type = MODEST_MAIL_OPERATION_TYPE_QUEUE_WAKEUP;
+
g_object_ref (self);
- g_signal_connect ((gpointer) queue, "queue-stop", G_CALLBACK (run_queue_stop), (gpointer) self);
+
+ modest_tny_send_queue_wakeup (queue, queue_wakeup_callback, self);
+ modest_mail_operation_notify_start (self);
}
static void