X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-mail-operation.c;h=7766262aa3c714b5f8e22f66c0be84ff9fdcc00f;hp=79d73c3ed50410ee3a471156d7081fa0869ffffb;hb=b933308658628c437daa43d7152eacecf45f8957;hpb=6e4dc5c482a9d152b2d3cf6ccd8837875a966240 diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 79d73c3..7766262 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -45,6 +45,7 @@ #include #include #include "modest-platform.h" +#include "modest-account-mgr-helpers.h" #include #include #include @@ -80,25 +81,27 @@ static void get_msg_status_cb (GObject *obj, TnyStatus *status, gpointer user_data); +static void modest_mail_operation_notify_start (ModestMailOperation *self); static void modest_mail_operation_notify_end (ModestMailOperation *self); enum _ModestMailOperationSignals { PROGRESS_CHANGED_SIGNAL, - + OPERATION_STARTED_SIGNAL, + OPERATION_FINISHED_SIGNAL, NUM_SIGNALS }; typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate; struct _ModestMailOperationPrivate { - TnyAccount *account; - gchar *account_name; + TnyAccount *account; guint done; guint total; GObject *source; GError *error; ErrorCheckingUserCallback error_checking; gpointer error_checking_user_data; + ErrorCheckingUserDataDestroyer error_checking_user_data_destroyer; ModestMailOperationStatus status; ModestMailOperationTypeOperation op_type; }; @@ -129,9 +132,12 @@ typedef struct _XFerMsgAsyncHelper ModestMailOperation *mail_op; TnyList *headers; TnyFolder *dest_folder; - XferMsgsAsynUserCallback user_callback; + XferAsyncUserCallback user_callback; gboolean delete; gpointer user_data; + gint last_total_bytes; + gint sum_total_bytes; + gint total_bytes; } XFerMsgAsyncHelper; typedef void (*ModestMailOperationCreateMsgCallback) (ModestMailOperation *mail_op, @@ -143,6 +149,7 @@ static void modest_mail_operation_create_msg (ModestMailOperation *self const gchar *cc, const gchar *bcc, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags, ModestMailOperationCreateMsgCallback callback, gpointer userdata); @@ -159,6 +166,7 @@ typedef struct gchar *plain_body; gchar *html_body; GList *attachments_list; + GList *images_list; TnyHeaderFlags priority_flags; ModestMailOperationCreateMsgCallback callback; gpointer userdata; @@ -227,7 +235,41 @@ modest_mail_operation_class_init (ModestMailOperationClass *klass) NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - + /** + * operation-started + * + * This signal is issued whenever a mail operation starts, and + * starts mean when the tinymail operation is issued. This + * means that it could happen that something wrong happens and + * the tinymail function is never called. In this situation a + * operation-finished will be issued without any + * operation-started + */ + signals[OPERATION_STARTED_SIGNAL] = + g_signal_new ("operation-started", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestMailOperationClass, operation_started), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + /** + * operation-started + * + * This signal is issued whenever a mail operation + * finishes. Note that this signal could be issued without any + * previous "operation-started" signal, because this last one + * is only issued when the tinymail operation is successfully + * started + */ + signals[OPERATION_FINISHED_SIGNAL] = + g_signal_new ("operation-finished", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestMailOperationClass, operation_finished), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -275,8 +317,7 @@ modest_mail_operation_finalize (GObject *obj) } ModestMailOperation* -modest_mail_operation_new (ModestMailOperationTypeOperation op_type, - GObject *source) +modest_mail_operation_new (GObject *source) { ModestMailOperation *obj; ModestMailOperationPrivate *priv; @@ -284,7 +325,6 @@ modest_mail_operation_new (ModestMailOperationTypeOperation op_type, obj = MODEST_MAIL_OPERATION(g_object_new(MODEST_TYPE_MAIL_OPERATION, NULL)); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj); - priv->op_type = op_type; if (source != NULL) priv->source = g_object_ref(source); @@ -292,20 +332,21 @@ modest_mail_operation_new (ModestMailOperationTypeOperation op_type, } ModestMailOperation* -modest_mail_operation_new_with_error_handling (ModestMailOperationTypeOperation op_type, - GObject *source, +modest_mail_operation_new_with_error_handling (GObject *source, ErrorCheckingUserCallback error_handler, - gpointer user_data) + gpointer user_data, + ErrorCheckingUserDataDestroyer error_handler_destroyer) { ModestMailOperation *obj; ModestMailOperationPrivate *priv; - obj = modest_mail_operation_new (op_type, source); + obj = modest_mail_operation_new (source); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj); g_return_val_if_fail (error_handler != NULL, obj); priv->error_checking = error_handler; priv->error_checking_user_data = user_data; + priv->error_checking_user_data_destroyer = error_handler_destroyer; return obj; } @@ -318,6 +359,7 @@ modest_mail_operation_execute_error_handler (ModestMailOperation *self) priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); g_return_if_fail(priv->status != MODEST_MAIL_OPERATION_STATUS_SUCCESS); + /* Call the user callback */ if (priv->error_checking != NULL) priv->error_checking (self, priv->error_checking_user_data); } @@ -358,7 +400,7 @@ modest_mail_operation_get_source (ModestMailOperation *self) return NULL; } - return g_object_ref (priv->source); + return (priv->source) ? g_object_ref (priv->source) : NULL; } ModestMailOperationStatus @@ -471,29 +513,6 @@ modest_mail_operation_is_finished (ModestMailOperation *self) return retval; } -guint -modest_mail_operation_get_id (ModestMailOperation *self) -{ - ModestMailOperationPrivate *priv; - - g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0); - - priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); - return priv->done; -} - -guint -modest_mail_operation_set_id (ModestMailOperation *self, - guint id) -{ - ModestMailOperationPrivate *priv; - - g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0); - - priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); - return priv->done; -} - /* * Creates an image of the current state of a mail operation, the * caller must free it @@ -560,10 +579,8 @@ modest_mail_operation_send_mail (ModestMailOperation *self, priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; } else { - /* TODO: connect to the msg-sent in order to know when - the mail operation is finished */ - -/* tny_send_queue_add (send_queue, msg, &(priv->error)); */ + /* Add the msg to the queue */ + modest_mail_operation_notify_start (self); modest_tny_send_queue_add (MODEST_TNY_SEND_QUEUE(send_queue), msg, &(priv->error)); @@ -612,11 +629,12 @@ create_msg_thread (gpointer thread_data) if (info->html_body == NULL) { new_msg = modest_tny_msg_new (info->to, info->from, info->cc, info->bcc, info->subject, info->plain_body, - info->attachments_list); /* FIXME: attachments */ + info->attachments_list); } else { new_msg = modest_tny_msg_new_html_plain (info->to, info->from, info->cc, info->bcc, info->subject, info->html_body, - info->plain_body, info->attachments_list); + info->plain_body, info->attachments_list, + info->images_list); } if (new_msg) { @@ -632,7 +650,7 @@ create_msg_thread (gpointer thread_data) if (info->attachments_list != NULL) flags |= TNY_HEADER_FLAG_ATTACHMENTS; - tny_header_set_flags (header, flags); + tny_header_set_flag (header, flags); g_object_unref (G_OBJECT(header)); } else { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; @@ -651,15 +669,14 @@ create_msg_thread (gpointer thread_data) g_free (info->subject); g_list_foreach (info->attachments_list, (GFunc) g_object_unref, NULL); g_list_free (info->attachments_list); + g_list_foreach (info->images_list, (GFunc) g_object_unref, NULL); + g_list_free (info->images_list); if (info->callback) { CreateMsgIdleInfo *idle_info; idle_info = g_slice_new0 (CreateMsgIdleInfo); - idle_info->mail_op = info->mail_op; - g_object_ref (info->mail_op); - idle_info->msg = new_msg; - if (new_msg) - g_object_ref (new_msg); + idle_info->mail_op = g_object_ref (info->mail_op); + idle_info->msg = (new_msg) ? g_object_ref (new_msg) : NULL; idle_info->callback = info->callback; idle_info->userdata = info->userdata; g_idle_add (idle_create_msg_cb, idle_info); @@ -679,6 +696,7 @@ modest_mail_operation_create_msg (ModestMailOperation *self, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags, ModestMailOperationCreateMsgCallback callback, gpointer userdata) @@ -686,8 +704,7 @@ modest_mail_operation_create_msg (ModestMailOperation *self, CreateMsgInfo *info = NULL; info = g_slice_new0 (CreateMsgInfo); - info->mail_op = self; - g_object_ref (self); + info->mail_op = g_object_ref (self); info->from = g_strdup (from); info->to = g_strdup (to); @@ -698,6 +715,8 @@ modest_mail_operation_create_msg (ModestMailOperation *self, info->html_body = g_strdup (html_body); info->attachments_list = g_list_copy ((GList *) attachments_list); g_list_foreach (info->attachments_list, (GFunc) g_object_ref, NULL); + info->images_list = g_list_copy ((GList *) images_list); + g_list_foreach (info->images_list, (GFunc) g_object_ref, NULL); info->priority_flags = priority_flags; info->callback = callback; @@ -731,8 +750,10 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self, modest_mail_operation_send_mail (self, info->transport_account, msg); /* Remove old mail from its source folder */ - draft_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_DRAFTS); - outbox_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_OUTBOX); + draft_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), + TNY_FOLDER_TYPE_DRAFTS); + outbox_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), + TNY_FOLDER_TYPE_OUTBOX); if (info->draft_msg != NULL) { TnyFolder *folder = NULL; TnyFolder *src_folder = NULL; @@ -740,6 +761,10 @@ modest_mail_operation_send_new_mail_cb (ModestMailOperation *self, folder = tny_msg_get_folder (info->draft_msg); if (folder == NULL) goto end; folder_type = modest_tny_folder_guess_folder_type (folder); + + if (folder_type == TNY_FOLDER_TYPE_INVALID) + g_warning ("%s: BUG: folder of type TNY_FOLDER_TYPE_INVALID", __FUNCTION__); + if (folder_type == TNY_FOLDER_TYPE_OUTBOX) src_folder = outbox_folder; else @@ -781,6 +806,7 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags) { ModestMailOperationPrivate *priv = NULL; @@ -790,6 +816,8 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self, g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account)); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + priv->op_type = MODEST_MAIL_OPERATION_TYPE_SEND; + priv->account = TNY_ACCOUNT (g_object_ref (transport_account)); /* Check parametters */ if (to == NULL) { @@ -807,8 +835,11 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self, info->draft_msg = draft_msg; if (draft_msg) g_object_ref (draft_msg); + + + modest_mail_operation_notify_start (self); modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body, - attachments_list, priority_flags, + attachments_list, images_list, priority_flags, modest_mail_operation_send_new_mail_cb, info); } @@ -817,7 +848,8 @@ typedef struct { TnyTransportAccount *transport_account; TnyMsg *draft_msg; - ModestMsgEditWindow *edit_window; + SaveToDraftstCallback callback; + gpointer user_data; } SaveToDraftsInfo; static void @@ -826,12 +858,13 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self, gpointer userdata) { TnyFolder *src_folder = NULL; - TnyFolder *folder = NULL; + TnyFolder *drafts = NULL; TnyHeader *header = NULL; ModestMailOperationPrivate *priv = NULL; SaveToDraftsInfo *info = (SaveToDraftsInfo *) userdata; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + if (!msg) { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, @@ -840,8 +873,9 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self, goto end; } - folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_DRAFTS); - if (!folder) { + drafts = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), + TNY_FOLDER_TYPE_DRAFTS); + if (!drafts) { priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, @@ -850,19 +884,18 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self, } if (!priv->error) - tny_folder_add_msg (folder, msg, &(priv->error)); + tny_folder_add_msg (drafts, msg, &(priv->error)); if ((!priv->error) && (info->draft_msg != NULL)) { header = tny_msg_get_header (info->draft_msg); src_folder = tny_header_get_folder (header); - /* Remove the old draft expunging it */ + /* Remove the old draft */ tny_folder_remove_msg (src_folder, header, NULL); -/* tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED); */ -/* tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); */ - tny_folder_sync (folder, TRUE, &(priv->error)); /* FALSE --> don't expunge */ - tny_folder_sync_async (src_folder, TRUE, NULL, NULL, NULL); /* expunge */ + /* Synchronize to expunge and to update the msg counts */ + tny_folder_sync_async (drafts, TRUE, NULL, NULL, NULL); + tny_folder_sync_async (src_folder, TRUE, NULL, NULL, NULL); g_object_unref (header); } @@ -872,17 +905,15 @@ modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self, else priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - if (info->edit_window) - modest_msg_edit_window_set_draft (info->edit_window, msg); - - end: - if (folder) - g_object_unref (G_OBJECT(folder)); + /* Call the user callback */ + if (info->callback) + info->callback (self, msg, info->user_data); + + if (drafts) + g_object_unref (G_OBJECT(drafts)); if (src_folder) g_object_unref (G_OBJECT(src_folder)); - if (info->edit_window) - g_object_unref (G_OBJECT(info->edit_window)); if (info->draft_msg) g_object_unref (G_OBJECT (info->draft_msg)); if (info->transport_account) @@ -896,13 +927,15 @@ void modest_mail_operation_save_to_drafts (ModestMailOperation *self, TnyTransportAccount *transport_account, TnyMsg *draft_msg, - ModestMsgEditWindow *edit_window, const gchar *from, const gchar *to, const gchar *cc, const gchar *bcc, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, - TnyHeaderFlags priority_flags) + const GList *images_list, + TnyHeaderFlags priority_flags, + SaveToDraftstCallback callback, + gpointer user_data) { ModestMailOperationPrivate *priv = NULL; SaveToDraftsInfo *info = NULL; @@ -914,20 +947,18 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self, /* Get account and set it into mail_operation */ priv->account = g_object_ref (transport_account); + priv->op_type = MODEST_MAIL_OPERATION_TYPE_INFO; info = g_slice_new0 (SaveToDraftsInfo); info->transport_account = g_object_ref (transport_account); - info->draft_msg = draft_msg; - if (draft_msg) - g_object_ref (draft_msg); - info->edit_window = edit_window; - if (edit_window) - g_object_ref (edit_window); + info->draft_msg = (draft_msg) ? g_object_ref (draft_msg) : NULL; + info->callback = callback; + info->user_data = user_data; + modest_mail_operation_notify_start (self); modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body, - attachments_list, priority_flags, + attachments_list, images_list, priority_flags, modest_mail_operation_save_to_drafts_cb, info); - } typedef struct @@ -1153,7 +1184,7 @@ set_last_updated_idle (gpointer data) { /* This is a GDK lock because we are an idle callback and - * modest_account_mgr_set_int can contain Gtk+ code */ + * modest_account_mgr_set_last_updated can issue Gtk+ code */ gdk_threads_enter (); /* CHECKED - please recheck */ @@ -1161,11 +1192,9 @@ set_last_updated_idle (gpointer data) the time when this idle was called, it's just an approximation and it won't be very different */ - modest_account_mgr_set_int (modest_runtime_get_account_mgr (), - (gchar *) data, - MODEST_ACCOUNT_LAST_UPDATED, - time(NULL), - TRUE); + modest_account_mgr_set_last_updated (modest_runtime_get_account_mgr (), + (gchar *) data, + time (NULL)); gdk_threads_leave (); /* CHECKED - please recheck */ @@ -1387,17 +1416,20 @@ update_account_thread (gpointer thr_user_data) priv->total = 0; if (priv->account != NULL) g_object_unref (priv->account); - priv->account = g_object_ref (info->transport_account); + + if (info->transport_account) { + priv->account = g_object_ref (info->transport_account); - send_queue = modest_runtime_get_send_queue (info->transport_account); - if (send_queue) { - modest_tny_send_queue_try_to_send (send_queue); - } else { - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, - "cannot create a send queue for %s\n", - tny_account_get_name (TNY_ACCOUNT (info->transport_account))); - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + send_queue = modest_runtime_get_send_queue (info->transport_account); + if (send_queue) { + modest_tny_send_queue_try_to_send (send_queue); + } else { + g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, + MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED, + "cannot create a send queue for %s\n", + tny_account_get_name (TNY_ACCOUNT (info->transport_account))); + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + } } /* Check if the operation was a success */ @@ -1412,7 +1444,10 @@ update_account_thread (gpointer thr_user_data) } out: - + /* Set the account back to not busy */ + modest_account_mgr_set_account_busy (modest_runtime_get_account_mgr(), + info->account_name, FALSE); + if (info->callback) { UpdateAccountInfo *idle_info; @@ -1436,7 +1471,9 @@ update_account_thread (gpointer thr_user_data) if (all_folders) g_object_unref (all_folders); g_object_unref (info->account); - g_object_unref (info->transport_account); + if (info->transport_account) + g_object_unref (info->transport_account); + g_free (info->account_name); g_free (info->retrieve_type); g_slice_free (UpdateAccountInfo, info); @@ -1468,6 +1505,7 @@ modest_mail_operation_update_account (ModestMailOperation *self, priv->total = 0; priv->done = 0; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; /* Get the store account */ store_account = (TnyStoreAccount *) @@ -1482,6 +1520,7 @@ modest_mail_operation_update_account (ModestMailOperation *self, goto error; } + priv->account = g_object_ref (store_account); /* Get the transport account, we can not do it in the thread due to some problems with dbus */ @@ -1501,6 +1540,7 @@ modest_mail_operation_update_account (ModestMailOperation *self, info->account = store_account; info->transport_account = transport_account; info->callback = callback; + info->account_name = g_strdup (account_name); info->user_data = user_data; /* Get the message size limit */ @@ -1513,12 +1553,10 @@ modest_mail_operation_update_account (ModestMailOperation *self, /* Get per-account retrieval type */ mgr = modest_runtime_get_account_mgr (); - info->retrieve_type = modest_account_mgr_get_string (mgr, account_name, - MODEST_ACCOUNT_RETRIEVE, FALSE); + info->retrieve_type = modest_account_mgr_get_retrieve_type (mgr, account_name); /* Get per-account message amount retrieval limit */ - info->retrieve_limit = modest_account_mgr_get_int (mgr, account_name, - MODEST_ACCOUNT_LIMIT_RETRIEVE, FALSE); + info->retrieve_limit = modest_account_mgr_get_retrieve_limit (mgr, account_name); if (info->retrieve_limit == 0) info->retrieve_limit = G_MAXINT; @@ -1526,13 +1564,17 @@ modest_mail_operation_update_account (ModestMailOperation *self, /* Set account busy */ modest_account_mgr_set_account_busy(mgr, account_name, TRUE); - priv->account_name = g_strdup(account_name); + modest_mail_operation_notify_start (self); thread = g_thread_create (update_account_thread, info, FALSE, NULL); return TRUE; error: + if (store_account) + g_object_unref (store_account); + if (transport_account) + g_object_unref (transport_account); priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; if (callback) { callback (self, NULL, user_data); @@ -1558,6 +1600,10 @@ modest_mail_operation_create_folder (ModestMailOperation *self, g_return_val_if_fail (name, NULL); priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); + priv->op_type = MODEST_MAIL_OPERATION_TYPE_INFO; + priv->account = (TNY_IS_ACCOUNT (parent)) ? + g_object_ref (parent) : + modest_tny_folder_get_account (TNY_FOLDER (parent)); /* Check for already existing folder */ if (modest_tny_folder_has_subfolder_with_name (parent, name)) { @@ -1589,6 +1635,7 @@ modest_mail_operation_create_folder (ModestMailOperation *self, if (!priv->error) { /* Create the folder */ + modest_mail_operation_notify_start (self); new_folder = tny_folder_store_create_folder (parent, name, &(priv->error)); CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED); if (!priv->error) @@ -1629,6 +1676,7 @@ modest_mail_operation_remove_folder (ModestMailOperation *self, /* Get the account */ account = modest_tny_folder_get_account (folder); priv->account = g_object_ref(account); + priv->op_type = MODEST_MAIL_OPERATION_TYPE_DELETE; /* Delete folder or move to trash */ if (remove_to_trash) { @@ -1637,6 +1685,7 @@ modest_mail_operation_remove_folder (ModestMailOperation *self, TNY_FOLDER_TYPE_TRASH); /* TODO: error_handling */ if (trash_folder) { + modest_mail_operation_notify_start (self); modest_mail_operation_xfer_folder (self, folder, TNY_FOLDER_STORE (trash_folder), TRUE, NULL, NULL); @@ -1645,6 +1694,7 @@ modest_mail_operation_remove_folder (ModestMailOperation *self, } else { TnyFolderStore *parent = tny_folder_get_folder_store (folder); + modest_mail_operation_notify_start (self); tny_folder_store_remove_folder (parent, folder, &(priv->error)); CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED); @@ -1741,7 +1791,7 @@ transfer_folder_cb (TnyFolder *folder, * which is already GDK locked by Tinymail */ /* no gdk_threads_enter (), CHECKED */ - helper->user_callback (priv->source, helper->user_data); + helper->user_callback (self, helper->user_data); /* no gdk_threads_leave () , CHECKED */ } @@ -1785,43 +1835,18 @@ new_name_valid_if_local_account (ModestMailOperationPrivate *priv, priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS, - _("ckdg_ib_folder_already_exists")); + _CS("ckdg_ib_folder_already_exists")); return FALSE; } else return TRUE; } -/** - * This function checks if @ancestor is an acestor of @folder and - * returns TRUE in that case - */ -static gboolean -folder_is_ancestor (TnyFolder *folder, - TnyFolderStore *ancestor) -{ - TnyFolder *tmp = NULL; - gboolean found = FALSE; - - tmp = folder; - while (!found && tmp && !TNY_IS_ACCOUNT (tmp)) { - TnyFolderStore *folder_store; - - folder_store = tny_folder_get_folder_store (tmp); - if (ancestor == folder_store) - found = TRUE; - else - tmp = g_object_ref (folder_store); - g_object_unref (folder_store); - } - return found; -} - void modest_mail_operation_xfer_folder (ModestMailOperation *self, TnyFolder *folder, TnyFolderStore *parent, gboolean delete_original, - XferMsgsAsynUserCallback user_callback, + XferAsyncUserCallback user_callback, gpointer user_data) { ModestMailOperationPrivate *priv = NULL; @@ -1841,6 +1866,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, error_msg = _("mail_in_ui_folder_move_target_error"); /* Get account and set it into mail_operation */ + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; @@ -1849,89 +1875,66 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, if (TNY_IS_FOLDER (parent)) parent_rules = modest_tny_folder_get_rules (TNY_FOLDER (parent)); - /* The moveable restriction is applied also to copy operation */ + /* Apply operation constraints */ if ((gpointer) parent == (gpointer) folder || (!TNY_IS_FOLDER_STORE (parent)) || (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE)) { - - /* Set status failed and set an error */ - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, - error_msg); - - /* Notify the queue */ - modest_mail_operation_notify_end (self); - + /* Folder rules */ + goto error; } else if (TNY_IS_FOLDER (parent) && (parent_rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)) { - - /* Set status failed and set an error */ - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, - error_msg); - - /* Notify the queue */ - modest_mail_operation_notify_end (self); + /* Folder rules */ + goto error; } else if (TNY_IS_FOLDER (parent) && TNY_IS_FOLDER_STORE (folder) && - folder_is_ancestor (TNY_FOLDER (parent), TNY_FOLDER_STORE (folder))) { - /* Set status failed and set an error */ - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, - error_msg); - - /* Notify the queue */ - modest_mail_operation_notify_end (self); - + modest_tny_folder_is_ancestor (TNY_FOLDER (parent), + TNY_FOLDER_STORE (folder))) { + /* Do not move a parent into a child */ + goto error; } else if (TNY_IS_FOLDER_STORE (parent) && modest_tny_folder_has_subfolder_with_name (parent, folder_name)) { /* Check that the new folder name is not used by any - parent subfolder */ - - /* Set status failed and set an error */ - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, - error_msg); - - /* Notify the queue */ - modest_mail_operation_notify_end (self); - + parent subfolder */ + goto error; } else if (!(new_name_valid_if_local_account (priv, parent, folder_name))) { /* Check that the new folder name is not used by any special local folder */ - - /* Set status failed and set an error */ - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, - error_msg); - - /* Notify the queue */ - modest_mail_operation_notify_end (self); + goto error; } else { /* Create the helper */ helper = g_slice_new0 (XFerMsgAsyncHelper); - helper->mail_op = g_object_ref(self); + helper->mail_op = g_object_ref (self); helper->dest_folder = NULL; helper->headers = NULL; helper->user_callback = user_callback; helper->user_data = user_data; - /* Move/Copy folder */ + /* Move/Copy folder */ + modest_mail_operation_notify_start (self); tny_folder_copy_async (folder, parent, tny_folder_get_name (folder), delete_original, transfer_folder_cb, transfer_folder_status_cb, - helper); - } - + helper); + return; + } + + error: + /* Set status failed and set an error */ + priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; + g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, + MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES, + error_msg); + + /* Call the user callback if exists */ + if (user_callback) + user_callback (self, user_data); + + /* Notify the queue */ + modest_mail_operation_notify_end (self); } void @@ -1951,6 +1954,7 @@ modest_mail_operation_rename_folder (ModestMailOperation *self, /* Get account and set it into mail_operation */ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); + priv->op_type = MODEST_MAIL_OPERATION_TYPE_INFO; /* Check folder rules */ rules = modest_tny_folder_get_rules (TNY_FOLDER (folder)); @@ -1987,6 +1991,7 @@ modest_mail_operation_rename_folder (ModestMailOperation *self, helper->user_data = NULL; /* Rename. Camel handles folder subscription/unsubscription */ + modest_mail_operation_notify_start (self); tny_folder_copy_async (folder, into, name, TRUE, transfer_folder_cb, transfer_folder_status_cb, @@ -2002,10 +2007,11 @@ modest_mail_operation_rename_folder (ModestMailOperation *self, /* ************************** MSG ACTIONS ************************* */ /* ******************************************************************* */ -void modest_mail_operation_get_msg (ModestMailOperation *self, - TnyHeader *header, - GetMsgAsyncUserCallback user_callback, - gpointer user_data) +void +modest_mail_operation_get_msg (ModestMailOperation *self, + TnyHeader *header, + GetMsgAsyncUserCallback user_callback, + gpointer user_data) { GetMsgAsyncHelper *helper = NULL; TnyFolder *folder; @@ -2018,42 +2024,33 @@ void modest_mail_operation_get_msg (ModestMailOperation *self, folder = tny_header_get_folder (header); priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; - /* Get message from folder */ - if (folder) { - /* Get account and set it into mail_operation */ - priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); + /* Get account and set it into mail_operation */ + priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); + + /* Check for cached messages */ + if (tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED) + priv->op_type = MODEST_MAIL_OPERATION_TYPE_OPEN; + else + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; + + helper = g_slice_new0 (GetMsgAsyncHelper); + helper->mail_op = self; + helper->user_callback = user_callback; + helper->user_data = user_data; + helper->header = g_object_ref (header); - /* Check for cached messages */ - if (tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED) - priv->op_type = MODEST_MAIL_OPERATION_TYPE_OPEN; - else - priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; - - helper = g_slice_new0 (GetMsgAsyncHelper); - helper->mail_op = self; - helper->user_callback = user_callback; - helper->user_data = user_data; - helper->header = g_object_ref (header); - - // The callback's reference so that the mail op is not - // finalized until the async operation is completed even if - // the user canceled the request meanwhile. - g_object_ref (G_OBJECT (helper->mail_op)); + /* The callback's reference so that the mail op is not + * finalized until the async operation is completed even if + * the user canceled the request meanwhile. + */ + g_object_ref (G_OBJECT (helper->mail_op)); - tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper); + modest_mail_operation_notify_start (self); + tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper); - g_object_unref (G_OBJECT (folder)); - } else { - /* Set status failed and set an error */ - priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, - MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, - _("Error trying to get a message. No folder found for header")); - - /* Notify the queue */ - modest_mail_operation_notify_end (self); - } + g_object_unref (G_OBJECT (folder)); } static void @@ -2318,6 +2315,7 @@ modest_mail_operation_get_msgs_full (ModestMailOperation *self, /* Init mail operation */ priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self); priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; priv->done = 0; priv->total = tny_list_get_length(header_list); @@ -2329,10 +2327,8 @@ modest_mail_operation_get_msgs_full (ModestMailOperation *self, folder = tny_header_get_folder (header); if (folder) { priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); - g_object_unref (folder); } - g_object_unref (header); } @@ -2378,6 +2374,7 @@ modest_mail_operation_get_msgs_full (ModestMailOperation *self, info->headers = g_object_ref (header_list); info->notify = notify; + modest_mail_operation_notify_start (self); thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL); } else { /* Set status failed and set an error */ @@ -2413,14 +2410,16 @@ modest_mail_operation_remove_msg (ModestMailOperation *self, /* Get account and set it into mail_operation */ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); - + priv->op_type = MODEST_MAIL_OPERATION_TYPE_DELETE; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; /* remove message from folder */ tny_folder_remove_msg (folder, header, &(priv->error)); if (!priv->error) { - tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED); - tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); + tny_header_set_flag (header, TNY_HEADER_FLAG_DELETED); + tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN); + + modest_mail_operation_notify_start (self); if (TNY_IS_CAMEL_IMAP_FOLDER (folder)) /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */ @@ -2473,10 +2472,12 @@ modest_mail_operation_remove_msgs (ModestMailOperation *self, /* Get account and set it into mail_operation */ priv->account = modest_tny_folder_get_account (TNY_FOLDER(folder)); - + priv->op_type = MODEST_MAIL_OPERATION_TYPE_DELETE; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; /* remove message from folder */ + modest_mail_operation_notify_start (self); + tny_folder_remove_msgs (folder, headers, &(priv->error)); if (!priv->error) { if (TNY_IS_CAMEL_IMAP_FOLDER (folder) || @@ -2513,7 +2514,7 @@ transfer_msgs_status_cb (GObject *obj, ModestMailOperation *self; ModestMailOperationPrivate *priv; ModestMailOperationState *state; - + gboolean is_num_bytes; g_return_if_fail (status != NULL); g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS); @@ -2524,19 +2525,30 @@ transfer_msgs_status_cb (GObject *obj, self = helper->mail_op; priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - priv->done = status->position; - priv->total = status->of_total; + /* We know that tinymail sends us information about + transferred bytes with this particular message */ + is_num_bytes = (g_ascii_strcasecmp (status->message, "Retrieving message") == 0); state = modest_mail_operation_clone_state (self); + if (is_num_bytes && !((status->position == 1) && (status->of_total == 100))) { + /* We know that we're in a different message when the + total number of bytes to transfer is different. Of + course it could fail if we're transferring messages + of the same size, but this is a workarround */ + if (status->of_total != helper->last_total_bytes) { + priv->done++; + helper->sum_total_bytes += helper->last_total_bytes; + helper->last_total_bytes = status->of_total; + } + state->bytes_done += status->position + helper->sum_total_bytes; + state->bytes_total = helper->total_bytes; - /* This is not a GDK lock because we are a Tinymail callback and - * Tinymail already acquires the Gdk lock */ - - /* no gdk_threads_enter (), CHECKED */ - - g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL); - /* no gdk_threads_leave (), CHECKED */ + /* Notify the status change. Only notify about changes + referred to bytes */ + g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], + 0, state, NULL); + } g_slice_free (ModestMailOperationState, state); } @@ -2582,8 +2594,8 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u iter = tny_list_create_iterator (helper->headers); while (!tny_iterator_is_done (iter)) { header = TNY_HEADER (tny_iterator_get_current (iter)); - tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED); - tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); + tny_header_set_flag (header, TNY_HEADER_FLAG_DELETED); + tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN); g_object_unref (header); tny_iterator_next (iter); @@ -2601,7 +2613,7 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u * Tinymail already acquires the Gdk lock */ /* no gdk_threads_enter (), CHECKED */ - helper->user_callback (priv->source, helper->user_data); + helper->user_callback (self, helper->user_data); /* no gdk_threads_leave (), CHECKED */ } @@ -2616,8 +2628,25 @@ transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError *err, gpointer u g_object_unref (folder); if (iter) g_object_unref (iter); - g_slice_free (XFerMsgAsyncHelper, helper); + g_slice_free (XFerMsgAsyncHelper, helper); +} +static guint +compute_message_list_size (TnyList *headers) +{ + TnyIterator *iter; + guint size = 0; + + iter = tny_list_create_iterator (headers); + while (!tny_iterator_is_done (iter)) { + TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter)); + size += tny_header_get_message_size (header); + g_object_unref (header); + tny_iterator_next (iter); + } + g_object_unref (iter); + + return size; } void @@ -2625,7 +2654,7 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, TnyList *headers, TnyFolder *folder, gboolean delete_original, - XferMsgsAsynUserCallback user_callback, + XferAsyncUserCallback user_callback, gpointer user_data) { ModestMailOperationPrivate *priv = NULL; @@ -2634,18 +2663,16 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, XFerMsgAsyncHelper *helper = NULL; TnyHeader *header = NULL; ModestTnyFolderRules rules = 0; - const gchar *id1 = NULL; - const gchar *id2 = NULL; - gboolean same_folder = FALSE; - g_return_if_fail (MODEST_IS_MAIL_OPERATION (self)); - g_return_if_fail (TNY_IS_LIST (headers)); - g_return_if_fail (TNY_IS_FOLDER (folder)); + g_return_if_fail (self && MODEST_IS_MAIL_OPERATION (self)); + g_return_if_fail (headers && TNY_IS_LIST (headers)); + g_return_if_fail (folder && TNY_IS_FOLDER (folder)); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - priv->total = 1; + priv->total = tny_list_get_length (headers); priv->done = 0; priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS; + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; /* Apply folder rules */ rules = modest_tny_folder_get_rules (TNY_FOLDER (folder)); @@ -2667,14 +2694,16 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, src_folder = tny_header_get_folder (header); g_object_unref (header); } - g_object_unref (iter); + if (src_folder == NULL) { + g_warning ("%s: cannot find folder from header", __FUNCTION__); + return; + } + + /* Check folder source and destination */ - id1 = tny_folder_get_id (src_folder); - id2 = tny_folder_get_id (TNY_FOLDER(folder)); - same_folder = !g_ascii_strcasecmp (id1, id2); - if (same_folder) { + if (src_folder == folder) { /* Set status failed and set an error */ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR, @@ -2697,11 +2726,15 @@ modest_mail_operation_xfer_msgs (ModestMailOperation *self, helper->user_callback = user_callback; helper->user_data = user_data; helper->delete = delete_original; + helper->last_total_bytes = 0; + helper->sum_total_bytes = 0; + helper->total_bytes = compute_message_list_size (headers); /* Get account and set it into mail_operation */ priv->account = modest_tny_folder_get_account (src_folder); /* Transfer messages */ + modest_mail_operation_notify_start (self); tny_folder_transfer_msgs_async (src_folder, headers, folder, @@ -2731,8 +2764,6 @@ on_refresh_folder (TnyFolder *folder, if (error) { priv->error = g_error_copy (error); priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED; - printf("DEBUG: %s: Operation error:\n %s", __FUNCTION__, - error->message); goto out; } @@ -2742,11 +2773,11 @@ on_refresh_folder (TnyFolder *folder, MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND, _("Error trying to refresh the contents of %s"), tny_folder_get_name (folder)); - printf("DEBUG: %s: Operation cancelled.\n", __FUNCTION__); goto out; } priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS; + out: /* Call user defined callback, if it exists */ if (helper->user_callback) { @@ -2756,7 +2787,6 @@ on_refresh_folder (TnyFolder *folder, helper->user_callback (self, folder, helper->user_data); } - out: /* Free */ g_slice_free (RefreshAsyncHelper, helper); @@ -2812,6 +2842,7 @@ modest_mail_operation_refresh_folder (ModestMailOperation *self, /* Get account and set it into mail_operation */ priv->account = modest_tny_folder_get_account (folder); + priv->op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; /* Create the helper */ helper = g_slice_new0 (RefreshAsyncHelper); @@ -2822,12 +2853,33 @@ modest_mail_operation_refresh_folder (ModestMailOperation *self, /* Refresh the folder. TODO: tinymail could issue a status updates before the callback call then this could happen. We must review the design */ + modest_mail_operation_notify_start (self); tny_folder_refresh_async (folder, on_refresh_folder, on_refresh_folder_status_update, helper); } + +static void +modest_mail_operation_notify_start (ModestMailOperation *self) +{ + ModestMailOperationPrivate *priv = NULL; + + g_return_if_fail (self); + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + + /* Ensure that all the fields are filled correctly */ + g_return_if_fail (priv->account != NULL); + g_return_if_fail (priv->op_type != MODEST_MAIL_OPERATION_TYPE_UNKNOWN); + + /* Notify the observers about the mail operation. We do not + wrapp this emission because we assume that this function is + always called from within the main lock */ + g_signal_emit (G_OBJECT (self), signals[OPERATION_STARTED_SIGNAL], 0, NULL); +} + /** * * It's used by the mail operation queue to notify the observers @@ -2839,25 +2891,30 @@ modest_mail_operation_refresh_folder (ModestMailOperation *self, static void modest_mail_operation_notify_end (ModestMailOperation *self) { - ModestMailOperationState *state; ModestMailOperationPrivate *priv = NULL; g_return_if_fail (self); priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); - /* Set the account back to not busy */ - if (priv->account_name) { - modest_account_mgr_set_account_busy (modest_runtime_get_account_mgr(), - priv->account_name, FALSE); - g_free(priv->account_name); - priv->account_name = NULL; - } - - /* Notify the observers about the mail operation end */ - /* We do not wrapp this emission because we assume that this + /* Notify the observers about the mail operation end. We do + not wrapp this emission because we assume that this function is always called from within the main lock */ - state = modest_mail_operation_clone_state (self); - g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, state, NULL); - g_slice_free (ModestMailOperationState, state); + g_signal_emit (G_OBJECT (self), signals[OPERATION_FINISHED_SIGNAL], 0, NULL); + + /* Remove the error user data */ + if (priv->error_checking_user_data && priv->error_checking_user_data_destroyer) + priv->error_checking_user_data_destroyer (priv->error_checking_user_data); +} + +TnyAccount * +modest_mail_operation_get_account (ModestMailOperation *self) +{ + ModestMailOperationPrivate *priv = NULL; + + g_return_val_if_fail (self, NULL); + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + + return (priv->account) ? g_object_ref (priv->account) : NULL; }