#include "modest-marshal.h"
#include "modest-error.h"
#include "modest-mail-operation.h"
+#include <modest-count-stream.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include "modest-utils.h"
#define KB 1024
typedef struct {
GetMsgAsyncUserCallback user_callback;
TnyHeader *header;
+ TnyList *header_list;
+ TnyIterator *iter;
gpointer user_data;
ModestMailOperation *mail_op;
GDestroyNotify destroy_notify;
gint total_bytes;
} GetMsgInfo;
-typedef struct {
- ModestMailOperation *mail_op;
- TnyMsg *msg;
- gulong msg_sent_handler;
- gulong error_happened_handler;
-} SendMsgInfo;
-
-static void send_mail_msg_sent_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
- guint nth, guint total, gpointer userdata);
-static void send_mail_error_happened_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
- GError *error, gpointer userdata);
-static void common_send_mail_operation_end (TnySendQueue *queue, TnyMsg *msg,
- SendMsgInfo *info);
-
typedef struct _RefreshAsyncHelper {
ModestMailOperation *mail_op;
RefreshAsyncUserCallback user_callback;
/* Set new status */
priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
- /* Cancel the mail operation. We need to wrap it between this
- start/stop operations to allow following calls to the
- account */
+ /* Cancel the mail operation */
g_return_val_if_fail (priv->account, FALSE);
+ tny_account_cancel (priv->account);
if (priv->op_type == MODEST_MAIL_OPERATION_TYPE_SEND) {
ModestTnySendQueue *queue;
queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (priv->account));
- /* Cancel sending without removing the item */
- tny_send_queue_cancel (TNY_SEND_QUEUE (queue), FALSE, NULL);
- } else {
- /* Cancel operation */
- tny_account_cancel (priv->account);
- }
+ /* Cancel the sending of the following next messages */
+ tny_send_queue_cancel (TNY_SEND_QUEUE (queue), TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, NULL);
+ }
+
return canceled;
}
{
TnySendQueue *send_queue = NULL;
ModestMailOperationPrivate *priv;
- SendMsgInfo *info;
g_return_if_fail (self && MODEST_IS_MAIL_OPERATION (self));
g_return_if_fail (transport_account && TNY_IS_TRANSPORT_ACCOUNT (transport_account));
/* Add the msg to the queue */
modest_mail_operation_notify_start (self);
- info = g_slice_new0 (SendMsgInfo);
-
- info->mail_op = g_object_ref (self);
- info->msg = g_object_ref (msg);
- info->msg_sent_handler = g_signal_connect (G_OBJECT (send_queue), "msg-sent",
- G_CALLBACK (send_mail_msg_sent_handler), info);
- info->error_happened_handler = g_signal_connect (G_OBJECT (send_queue), "error-happened",
- G_CALLBACK (send_mail_error_happened_handler), info);
+ tny_send_queue_add_async (send_queue, msg, NULL, NULL, NULL);
- modest_tny_send_queue_add (MODEST_TNY_SEND_QUEUE(send_queue),
- msg,
- &(priv->error));
-
- priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
- }
-
-}
-
-static void
-common_send_mail_operation_end (TnySendQueue *queue, TnyMsg *msg,
- SendMsgInfo *info)
-{
- g_signal_handler_disconnect (queue, info->msg_sent_handler);
- g_signal_handler_disconnect (queue, info->error_happened_handler);
-
- g_object_unref (info->msg);
- modest_mail_operation_notify_end (info->mail_op);
- g_object_unref (info->mail_op);
-
- g_slice_free (SendMsgInfo, info);
-}
-
-static void
-send_mail_msg_sent_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
- guint nth, guint total, gpointer userdata)
-{
- SendMsgInfo *info = (SendMsgInfo *) userdata;
- TnyHeader *hdr1, *hdr2;
- const char *msgid1, *msgid2;
- hdr1 = tny_msg_get_header(msg);
- hdr2 = tny_msg_get_header(info->msg);
- msgid1 = tny_header_get_message_id(hdr1);
- msgid2 = tny_header_get_message_id(hdr2);
- if (msgid1 == NULL) msgid1 = "(null)";
- if (msgid2 == NULL) msgid2 = "(null)";
-
- if (!strcmp (msgid1, msgid2)) {
- ModestMailOperationPrivate *priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
-
- common_send_mail_operation_end (queue, msg, info);
+ modest_mail_operation_notify_end (self);
}
- g_object_unref(G_OBJECT(hdr1));
- g_object_unref(G_OBJECT(hdr2));
-}
-
-static void
-send_mail_error_happened_handler (TnySendQueue *queue, TnyHeader *header, TnyMsg *msg,
- GError *error, gpointer userdata)
-{
- SendMsgInfo *info = (SendMsgInfo *) userdata;
- TnyHeader *hdr1, *hdr2;
- const char *msgid1, *msgid2;
- if (!TNY_IS_MSG(msg)) {
- g_warning ("%s: did not receive a valid msg", __FUNCTION__);
- return;
- }
-
- hdr1 = tny_msg_get_header(msg);
- hdr2 = tny_msg_get_header(info->msg);
- msgid1 = tny_header_get_message_id(hdr1);
- msgid2 = tny_header_get_message_id(hdr2);
- if (msgid1 == NULL) msgid1 = "(null)";
- if (msgid2 == NULL) msgid2 = "(null)";
-
- if (!strcmp (msgid1, msgid2)) {
- if (error != NULL)
- g_warning ("%s: %s\n", __FUNCTION__, error->message);
- ModestMailOperationPrivate *priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
- priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
- g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
- MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
- "modest: send mail failed\n");
-
- common_send_mail_operation_end (queue, msg, info);
- }
- g_object_unref(G_OBJECT(hdr1));
- g_object_unref(G_OBJECT(hdr2));
}
return NULL;
}
+
void
modest_mail_operation_create_msg (ModestMailOperation *self,
const gchar *from, const gchar *to,
ModestMailOperationCreateMsgCallback callback,
gpointer userdata)
{
+ ModestMailOperationPrivate *priv;
CreateMsgInfo *info = NULL;
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
info = g_slice_new0 (CreateMsgInfo);
info->mail_op = g_object_ref (self);
TnyMsg *msg,
gpointer userdata)
{
+ ModestMailOperationPrivate *priv = NULL;
SendNewMailInfo *info = (SendNewMailInfo *) userdata;
TnyFolder *draft_folder = NULL;
TnyFolder *outbox_folder = NULL;
goto end;
}
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ if (priv->error) {
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+ modest_mail_operation_notify_end (self);
+ goto end;
+ }
+
/* Call mail operation */
modest_mail_operation_send_mail (self, info->transport_account, msg);
static void
tny_folder_observer_init (TnyFolderObserverIface *iface)
{
- iface->update_func = internal_folder_observer_update;
+ iface->update = internal_folder_observer_update;
}
static void
internal_folder_observer_class_init (InternalFolderObserverClass *klass)
g_slice_free (GetMsgInfo, msg_info);
}
-
static void
inbox_refreshed_cb (TnyFolder *inbox,
gboolean canceled,
TnyList *new_headers = NULL;
gboolean headers_only, ignore_limit;
TnyTransportAccount *transport_account;
- ModestTnySendQueue *send_queue;
info = (UpdateAccountInfo *) user_data;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
g_ptr_array_free (new_headers_array, FALSE);
send_mail:
- /* Send mails */
- priv->done = 0;
- priv->total = 0;
-
/* Get the transport account */
transport_account = (TnyTransportAccount *)
modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
info->account_name);
-
- /* Try to send */
- send_queue = modest_runtime_get_send_queue (transport_account);
- modest_tny_send_queue_try_to_send (send_queue);
+
+ if (transport_account) {
+ ModestTnySendQueue *send_queue;
+ TnyFolder *outbox;
+ guint num_messages;
+
+ send_queue = modest_runtime_get_send_queue (transport_account);
+
+ /* Get outbox folder */
+ outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (send_queue));
+ num_messages = tny_folder_get_all_count (outbox);
+ g_object_unref (outbox);
+
+ if (num_messages != 0) {
+ /* Send mails */
+ g_object_unref (priv->account);
+
+ /* Reenable suspended items */
+ modest_tny_send_queue_wakeup (MODEST_TNY_SEND_QUEUE (send_queue));
+
+ /* Try to send */
+ tny_camel_send_queue_flush (TNY_CAMEL_SEND_QUEUE (send_queue));
+ }
+ }
/* Check if the operation was a success */
if (!priv->error)
ModestTnyAccountStore *account_store = NULL;
TnyStoreAccount *store_account = NULL;
TnyList *folders;
+ ModestMailOperationState *state;
/* Init mail operation */
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
priv->total = 0;
priv->done = 0;
priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
- priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE;
+ priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE;
/* Get the store account */
account_store = modest_runtime_get_account_store ();
modest_mail_operation_notify_start (self);
/* notify about the start of the operation */
- ModestMailOperationState *state;
state = modest_mail_operation_clone_state (self);
state->done = 0;
state->total = 0;
/* Start notifying progress */
- g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL],
- 0, state, NULL);
+ g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL);
g_slice_free (ModestMailOperationState, state);
- /* Get all folders and continue in the callback */
+ /* Get all folders and continue in the callback */
folders = tny_simple_list_new ();
tny_folder_store_get_folders_async (TNY_FOLDER_STORE (store_account),
folders, NULL,
priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
priv->done++;
- finished = (priv->done == priv->total) ? TRUE : FALSE;
+
+ if (info->iter) {
+ tny_iterator_next (info->iter);
+ finished = (tny_iterator_is_done (info->iter));
+ } else {
+ finished = (priv->done == priv->total) ? TRUE : FALSE;
+ }
/* Check errors */
if (canceled || err) {
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
err->message);
- } else {
+ } else if (finished && priv->status == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS) {
/* Set the success status before calling the user callback */
- if (finished && priv->status == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
- priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+ } else if (priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED) {
+ canceled = TRUE;
+ finished = TRUE;
}
/* Notify about operation end */
modest_mail_operation_notify_end (info->mail_op);
- }
- /* Clean */
- g_object_unref (info->header);
- g_object_unref (info->mail_op);
- g_slice_free (GetMsgInfo, info);
+ /* Clean */
+ if (info->iter)
+ g_object_unref (info->iter);
+ if (info->header_list)
+ g_object_unref (info->header_list);
+ g_object_unref (info->header);
+ g_object_unref (info->mail_op);
+ g_slice_free (GetMsgInfo, info);
+ } else if (info->iter) {
+ TnyHeader *header = TNY_HEADER (tny_iterator_get_current (info->iter));
+ TnyFolder *folder = tny_header_get_folder (header);
+
+ g_object_unref (info->header);
+ info->header = g_object_ref (header);
+
+ /* Retrieve the next message */
+ tny_folder_get_msg_async (folder, header, get_msg_async_cb, get_msg_status_cb, info);
+
+ g_object_unref (header);
+ g_object_unref (folder);
+ } else {
+ g_warning ("%s: finished != TRUE but no messages left", __FUNCTION__);
+ }
}
void
modest_mail_operation_notify_start (self);
iter = tny_list_create_iterator (header_list);
- while (!tny_iterator_is_done (iter)) {
+ if (!tny_iterator_is_done (iter)) {
/* notify about the start of the operation */
ModestMailOperationState *state;
state = modest_mail_operation_clone_state (self);
msg_info = g_slice_new0 (GetMsgInfo);
msg_info->mail_op = g_object_ref (self);
msg_info->header = g_object_ref (header);
+ msg_info->header_list = g_object_ref (header_list);
+ msg_info->iter = g_object_ref (iter);
msg_info->user_callback = user_callback;
msg_info->user_data = user_data;
msg_info->destroy_notify = notify;
/* Free and go on */
g_object_unref (header);
g_object_unref (folder);
- tny_iterator_next (iter);
+ g_slice_free (ModestMailOperationState, state);
}
g_object_unref (iter);
}
helper);
}
+static void
+run_queue_stop (ModestTnySendQueue *queue,
+ ModestMailOperation *self)
+{
+ 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_SUCCESS;
+
+ modest_mail_operation_notify_end (self);
+ g_signal_handlers_disconnect_by_func (queue, run_queue_stop, self);
+ g_object_unref (self);
+}
+void
+modest_mail_operation_run_queue (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_RUN_QUEUE;
+
+ modest_mail_operation_notify_start (self);
+ g_object_ref (self);
+ g_signal_connect ((gpointer) queue, "queue-stop", G_CALLBACK (run_queue_stop), (gpointer) self);
+}
+
+static void
+sync_folder_finish_callback (TnyFolder *self, gboolean cancelled, GError *err, ModestMailOperation *mail_op)
+{
+ ModestMailOperationPrivate *priv;
+
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op);
+ if (err != NULL) {
+ g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+ MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
+ err->message);
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+ } else {
+ priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
+ }
+ modest_mail_operation_notify_end (mail_op);
+ g_object_unref (mail_op);
+}
+
+void
+modest_mail_operation_sync_folder (ModestMailOperation *self,
+ TnyFolder *folder, gboolean expunge)
+{
+ ModestMailOperationPrivate *priv;
+
+ g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+ g_return_if_fail (TNY_IS_FOLDER (folder));
+ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+ priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+ priv->account = TNY_ACCOUNT (tny_folder_get_account (folder));
+ priv->op_type = MODEST_MAIL_OPERATION_TYPE_SYNC_FOLDER;
+
+ modest_mail_operation_notify_start (self);
+ g_object_ref (self);
+ tny_folder_sync_async (folder, expunge, (TnyFolderCallback) sync_folder_finish_callback, NULL, self);
+}
static void
modest_mail_operation_notify_start (ModestMailOperation *self)
case MODEST_MAIL_OPERATION_TYPE_OPEN: type= "OPEN"; break;
case MODEST_MAIL_OPERATION_TYPE_DELETE: type= "DELETE"; break;
case MODEST_MAIL_OPERATION_TYPE_INFO: type= "INFO"; break;
+ case MODEST_MAIL_OPERATION_TYPE_RUN_QUEUE: type= "RUN-QUEUE"; break;
+ case MODEST_MAIL_OPERATION_TYPE_SYNC_FOLDER: type= "SYNC-FOLDER"; break;
case MODEST_MAIL_OPERATION_TYPE_UNKNOWN: type= "UNKNOWN"; break;
default: type = "UNEXPECTED"; break;
}