1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "modest-mail-operation.h"
31 /* include other impl specific header files */
34 #include <tny-mime-part.h>
35 #include <tny-store-account.h>
36 #include <tny-folder-store.h>
37 #include <tny-folder-store-query.h>
38 #include <tny-camel-stream.h>
39 #include <tny-simple-list.h>
40 #include <tny-send-queue.h>
41 #include <tny-status.h>
42 #include <camel/camel-stream-mem.h>
43 #include <glib/gi18n.h>
44 #include "modest-platform.h"
45 #include <modest-tny-account.h>
46 #include <modest-tny-send-queue.h>
47 #include <modest-runtime.h>
48 #include "modest-text-utils.h"
49 #include "modest-tny-msg.h"
50 #include "modest-tny-folder.h"
51 #include "modest-tny-platform-factory.h"
52 #include "modest-marshal.h"
53 #include "modest-error.h"
55 /* 'private'/'protected' functions */
56 static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
57 static void modest_mail_operation_init (ModestMailOperation *obj);
58 static void modest_mail_operation_finalize (GObject *obj);
60 static void get_msg_cb (TnyFolder *folder,
66 static void get_msg_status_cb (GObject *obj,
70 static void modest_mail_operation_notify_end (ModestMailOperation *self);
72 enum _ModestMailOperationSignals
74 PROGRESS_CHANGED_SIGNAL,
79 typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate;
80 struct _ModestMailOperationPrivate {
83 ModestMailOperationStatus status;
84 ModestMailOperationId id;
86 ErrorCheckingUserCallback error_checking;
90 #define MODEST_MAIL_OPERATION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
91 MODEST_TYPE_MAIL_OPERATION, \
92 ModestMailOperationPrivate))
94 #define CHECK_EXCEPTION(priv, new_status) if (priv->error) {\
95 priv->status = new_status;\
98 typedef struct _GetMsgAsyncHelper {
99 ModestMailOperation *mail_op;
100 GetMsgAsyncUserCallback user_callback;
105 typedef struct _XFerMsgAsyncHelper
107 ModestMailOperation *mail_op;
109 TnyFolder *dest_folder;
110 XferMsgsAsynUserCallback user_callback;
112 } XFerMsgAsyncHelper;
114 typedef struct _XFerFolderAsyncHelper
116 ModestMailOperation *mail_op;
118 } XFerFolderAsyncHelper;
121 static GObjectClass *parent_class = NULL;
123 static guint signals[NUM_SIGNALS] = {0};
126 modest_mail_operation_get_type (void)
128 static GType my_type = 0;
130 static const GTypeInfo my_info = {
131 sizeof(ModestMailOperationClass),
132 NULL, /* base init */
133 NULL, /* base finalize */
134 (GClassInitFunc) modest_mail_operation_class_init,
135 NULL, /* class finalize */
136 NULL, /* class data */
137 sizeof(ModestMailOperation),
139 (GInstanceInitFunc) modest_mail_operation_init,
142 my_type = g_type_register_static (G_TYPE_OBJECT,
143 "ModestMailOperation",
150 modest_mail_operation_class_init (ModestMailOperationClass *klass)
152 GObjectClass *gobject_class;
153 gobject_class = (GObjectClass*) klass;
155 parent_class = g_type_class_peek_parent (klass);
156 gobject_class->finalize = modest_mail_operation_finalize;
158 g_type_class_add_private (gobject_class, sizeof(ModestMailOperationPrivate));
161 * ModestMailOperation::progress-changed
162 * @self: the #MailOperation that emits the signal
163 * @user_data: user data set when the signal handler was connected
165 * Emitted when the progress of a mail operation changes
167 signals[PROGRESS_CHANGED_SIGNAL] =
168 g_signal_new ("progress-changed",
169 G_TYPE_FROM_CLASS (gobject_class),
171 G_STRUCT_OFFSET (ModestMailOperationClass, progress_changed),
173 g_cclosure_marshal_VOID__VOID,
178 modest_mail_operation_init (ModestMailOperation *obj)
180 ModestMailOperationPrivate *priv;
182 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
184 priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID;
185 priv->id = MODEST_MAIL_OPERATION_ID_UNKNOWN;
193 modest_mail_operation_finalize (GObject *obj)
195 ModestMailOperationPrivate *priv;
197 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
200 g_error_free (priv->error);
204 g_object_unref (priv->source);
208 G_OBJECT_CLASS(parent_class)->finalize (obj);
212 modest_mail_operation_new (ModestMailOperationId id,
215 ModestMailOperation *obj;
216 ModestMailOperationPrivate *priv;
218 obj = MODEST_MAIL_OPERATION(g_object_new(MODEST_TYPE_MAIL_OPERATION, NULL));
219 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
223 priv->source = g_object_ref(source);
229 modest_mail_operation_new_with_error_handling (ModestMailOperationId id,
231 ErrorCheckingUserCallback error_handler)
233 ModestMailOperation *obj;
234 ModestMailOperationPrivate *priv;
236 obj = modest_mail_operation_new (id, source);
237 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
239 g_return_val_if_fail (error_handler != NULL, obj);
240 priv->error_checking = error_handler;
246 modest_mail_operation_execute_error_handler (ModestMailOperation *self)
248 ModestMailOperationPrivate *priv;
250 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
251 g_return_if_fail(priv->status != MODEST_MAIL_OPERATION_STATUS_SUCCESS);
253 if (priv->error_checking == NULL) return;
254 priv->error_checking (priv->source, self);
258 ModestMailOperationId
259 modest_mail_operation_get_id (ModestMailOperation *self)
261 ModestMailOperationPrivate *priv;
263 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
269 modest_mail_operation_is_mine (ModestMailOperation *self,
272 ModestMailOperationPrivate *priv;
274 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
275 if (priv->source == NULL) return FALSE;
277 return priv->source == me;
281 modest_mail_operation_get_source (ModestMailOperation *self)
283 ModestMailOperationPrivate *priv;
285 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
287 return g_object_ref (priv->source);
291 modest_mail_operation_send_mail (ModestMailOperation *self,
292 TnyTransportAccount *transport_account,
295 TnySendQueue *send_queue;
297 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
298 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
299 g_return_if_fail (TNY_IS_MSG (msg));
301 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
302 if (!TNY_IS_SEND_QUEUE(send_queue))
303 g_printerr ("modest: could not find send queue for account\n");
306 tny_send_queue_add (send_queue, msg, &err);
308 g_printerr ("modest: error adding msg to send queue: %s\n",
312 /* g_message ("modest: message added to send queue"); */
316 /* Notify about operation end */
317 modest_mail_operation_notify_end (self);
321 modest_mail_operation_send_new_mail (ModestMailOperation *self,
322 TnyTransportAccount *transport_account,
323 const gchar *from, const gchar *to,
324 const gchar *cc, const gchar *bcc,
325 const gchar *subject, const gchar *plain_body,
326 const gchar *html_body,
327 const GList *attachments_list,
328 TnyHeaderFlags priority_flags)
331 ModestMailOperationPrivate *priv = NULL;
332 /* GList *node = NULL; */
334 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
335 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
337 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
339 /* Check parametters */
341 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
342 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
343 _("Error trying to send a mail. You need to set at least one recipient"));
347 if (html_body == NULL) {
348 new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
350 new_msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
353 g_printerr ("modest: failed to create a new msg\n");
357 /* TODO: add priority handling. It's received in the priority_flags operator, and
358 it should have effect in the sending operation */
360 /* Call mail operation */
361 modest_mail_operation_send_mail (self, transport_account, new_msg);
364 g_object_unref (G_OBJECT (new_msg));
368 modest_mail_operation_save_to_drafts (ModestMailOperation *self,
369 TnyTransportAccount *transport_account,
370 const gchar *from, const gchar *to,
371 const gchar *cc, const gchar *bcc,
372 const gchar *subject, const gchar *plain_body,
373 const gchar *html_body,
374 const GList *attachments_list,
375 TnyHeaderFlags priority_flags)
378 TnyFolder *folder = NULL;
379 ModestMailOperationPrivate *priv = NULL;
382 /* GList *node = NULL; */
384 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
385 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
387 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
389 if (html_body == NULL) {
390 msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
392 msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
395 g_printerr ("modest: failed to create a new msg\n");
399 folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
401 g_printerr ("modest: failed to find Drafts folder\n");
405 tny_folder_add_msg (folder, msg, &err);
407 g_printerr ("modest: error adding msg to Drafts folder: %s",
413 modest_mail_operation_notify_end (self);
418 g_object_unref (G_OBJECT(msg));
420 g_object_unref (G_OBJECT(folder));
425 ModestMailOperation *mail_op;
426 TnyStoreAccount *account;
427 TnyTransportAccount *transport_account;
431 recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
434 TnyList *folders = tny_simple_list_new ();
436 tny_folder_store_get_folders (store, folders, query, NULL);
437 iter = tny_list_create_iterator (folders);
439 while (!tny_iterator_is_done (iter)) {
441 TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
443 tny_list_prepend (all_folders, G_OBJECT (folder));
444 recurse_folders (folder, query, all_folders);
445 g_object_unref (G_OBJECT (folder));
447 tny_iterator_next (iter);
449 g_object_unref (G_OBJECT (iter));
450 g_object_unref (G_OBJECT (folders));
454 * Used by update_account_thread to emit the "progress-changed" signal
455 * from the main loop. We call it inside an idle call to achieve that
458 notify_update_account_observers (gpointer data)
460 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
462 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
468 * Used by update_account_thread to notify the queue from the main
469 * loop. We call it inside an idle call to achieve that
472 notify_update_account_queue (gpointer data)
474 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
476 modest_mail_operation_notify_end (mail_op);
477 g_object_unref (mail_op);
483 update_account_thread (gpointer thr_user_data)
485 UpdateAccountInfo *info;
486 TnyList *all_folders = NULL;
487 TnyIterator *iter = NULL;
488 TnyFolderStoreQuery *query = NULL;
489 ModestMailOperationPrivate *priv;
490 ModestTnySendQueue *send_queue;
493 info = (UpdateAccountInfo *) thr_user_data;
494 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
496 /* Get all the folders We can do it synchronously because
497 we're already running in a different thread than the UI */
498 all_folders = tny_simple_list_new ();
499 query = tny_folder_store_query_new ();
500 tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
501 tny_folder_store_get_folders (TNY_FOLDER_STORE (info->account),
506 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
510 iter = tny_list_create_iterator (all_folders);
511 while (!tny_iterator_is_done (iter)) {
512 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
514 recurse_folders (folder, query, all_folders);
515 tny_iterator_next (iter);
517 g_object_unref (G_OBJECT (iter));
519 /* Update status and notify. We need to call the notification
520 with a source functopm in order to call it from the main
521 loop. We need that in order not to get into trouble with
522 Gtk+. We use a timeout in order to provide more status
523 information, because the sync tinymail call does not
524 provide it for the moment */
525 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
527 /* Refresh folders */
528 iter = tny_list_create_iterator (all_folders);
529 while (!tny_iterator_is_done (iter) && !priv->error) {
531 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
533 /* Refresh the folder */
534 tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
536 /* TODO: Apply retrieval types */
538 /* TODO: apply per-message size limits */
540 /* TODO: apply message count limit */
543 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
546 g_object_unref (G_OBJECT (folder));
547 tny_iterator_next (iter);
549 g_object_unref (G_OBJECT (iter));
550 g_source_remove (timeout);
553 priv->id = MODEST_MAIL_OPERATION_ID_SEND;
555 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(info->transport_account));
557 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
558 modest_tny_send_queue_flush (send_queue);
559 g_source_remove (timeout);
561 g_object_unref (G_OBJECT(send_queue));
563 /* Check if the operation was a success */
565 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
567 /* Update the last updated key */
568 modest_account_mgr_set_int (modest_runtime_get_account_mgr (),
569 tny_account_get_id (TNY_ACCOUNT (info->account)),
570 MODEST_ACCOUNT_LAST_UPDATED,
576 /* Notify about operation end. Note that the info could be
577 freed before this idle happens, but the mail operation will
579 g_idle_add (notify_update_account_queue, info->mail_op);
582 g_object_unref (query);
583 g_object_unref (all_folders);
584 g_object_unref (info->account);
585 g_object_unref (info->transport_account);
586 g_slice_free (UpdateAccountInfo, info);
592 modest_mail_operation_update_account (ModestMailOperation *self,
593 const gchar *account_name)
596 UpdateAccountInfo *info;
597 ModestMailOperationPrivate *priv;
598 TnyStoreAccount *modest_account;
599 TnyTransportAccount *transport_account;
601 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
602 g_return_val_if_fail (account_name, FALSE);
604 /* Init mail operation. Set total and done to 0, and do not
605 update them, this way the progress objects will know that
606 we have no clue about the number of the objects */
607 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
610 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
612 /* Get the Modest account */
613 modest_account = (TnyStoreAccount *)
614 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store (),
616 TNY_ACCOUNT_TYPE_STORE);
618 if (!modest_account) {
619 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
620 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
621 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
622 "cannot get tny store account for %s\n", account_name);
623 modest_mail_operation_notify_end (self);
627 /* Get the transport account, we can not do it in the thread
628 due to some problems with dbus */
629 transport_account = (TnyTransportAccount *)
630 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
632 if (!transport_account) {
633 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
634 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
635 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
636 "cannot get tny transport account for %s\n", account_name);
637 modest_mail_operation_notify_end (self);
641 /* Create the helper object */
642 info = g_slice_new (UpdateAccountInfo);
643 info->mail_op = self;
644 info->account = modest_account;
645 info->transport_account = transport_account;
647 thread = g_thread_create (update_account_thread, info, FALSE, NULL);
652 ModestMailOperationStatus
653 modest_mail_operation_get_status (ModestMailOperation *self)
655 ModestMailOperationPrivate *priv;
657 g_return_val_if_fail (self, MODEST_MAIL_OPERATION_STATUS_INVALID);
658 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self),
659 MODEST_MAIL_OPERATION_STATUS_INVALID);
661 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
666 modest_mail_operation_get_error (ModestMailOperation *self)
668 ModestMailOperationPrivate *priv;
670 g_return_val_if_fail (self, NULL);
671 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
673 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
678 modest_mail_operation_cancel (ModestMailOperation *self)
680 ModestMailOperationPrivate *priv;
682 if (!MODEST_IS_MAIL_OPERATION (self)) {
683 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
687 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
689 /* TODO: Tinymail does not support cancel operation */
690 /* tny_account_cancel (); */
693 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
695 /* Notify about operation end */
696 modest_mail_operation_notify_end (self);
702 modest_mail_operation_get_task_done (ModestMailOperation *self)
704 ModestMailOperationPrivate *priv;
706 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
708 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
713 modest_mail_operation_get_task_total (ModestMailOperation *self)
715 ModestMailOperationPrivate *priv;
717 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
719 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
724 modest_mail_operation_is_finished (ModestMailOperation *self)
726 ModestMailOperationPrivate *priv;
727 gboolean retval = FALSE;
729 if (!MODEST_IS_MAIL_OPERATION (self)) {
730 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
734 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
736 if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS ||
737 priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED ||
738 priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED ||
739 priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) {
748 /* ******************************************************************* */
749 /* ************************** STORE ACTIONS ************************* */
750 /* ******************************************************************* */
754 modest_mail_operation_create_folder (ModestMailOperation *self,
755 TnyFolderStore *parent,
758 ModestTnyFolderRules rules;
759 ModestMailOperationPrivate *priv;
760 TnyFolder *new_folder = NULL;
761 gboolean can_create = FALSE;
763 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
764 g_return_val_if_fail (name, NULL);
766 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
769 if (!TNY_IS_FOLDER (parent)) {
770 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
771 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
772 _("mail_in_ui_folder_create_error"));
774 /* Check folder rules */
775 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
776 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)
777 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
778 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
779 _("mail_in_ui_folder_create_error"));
785 /* Create the folder */
786 new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
787 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
790 /* Notify about operation end */
791 modest_mail_operation_notify_end (self);
797 modest_mail_operation_remove_folder (ModestMailOperation *self,
799 gboolean remove_to_trash)
802 ModestMailOperationPrivate *priv;
803 ModestTnyFolderRules rules;
805 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
806 g_return_if_fail (TNY_IS_FOLDER (folder));
808 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
810 /* Check folder rules */
811 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
812 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE) {
813 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
814 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
815 _("mail_in_ui_folder_delete_error"));
819 /* Get the account */
820 account = tny_folder_get_account (folder);
822 /* Delete folder or move to trash */
823 if (remove_to_trash) {
824 TnyFolder *trash_folder = NULL;
825 trash_folder = modest_tny_account_get_special_folder (account,
826 TNY_FOLDER_TYPE_TRASH);
827 /* TODO: error_handling */
828 modest_mail_operation_xfer_folder (self, folder,
829 TNY_FOLDER_STORE (trash_folder), TRUE);
831 TnyFolderStore *parent = tny_folder_get_folder_store (folder);
833 tny_folder_store_remove_folder (parent, folder, &(priv->error));
834 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
837 g_object_unref (G_OBJECT (parent));
839 g_object_unref (G_OBJECT (account));
842 /* Notify about operation end */
843 modest_mail_operation_notify_end (self);
847 modest_mail_operation_rename_folder (ModestMailOperation *self,
851 ModestMailOperationPrivate *priv;
852 ModestTnyFolderRules rules;
854 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
855 g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
856 g_return_if_fail (name);
858 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
860 /* Check folder rules */
861 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
862 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
863 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
864 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
865 _("FIXME: unable to rename"));
867 /* Rename. Camel handles folder subscription/unsubscription */
868 TnyFolderStore *into;
871 into = tny_folder_get_folder_store (folder);
872 nfol = tny_folder_copy (folder, into, name, TRUE, &(priv->error));
874 g_object_unref (into);
876 g_object_unref (nfol);
878 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
882 /* Notify about operation end */
883 modest_mail_operation_notify_end (self);
887 transfer_folder_status_cb (GObject *obj,
891 XFerMsgAsyncHelper *helper = NULL;
892 ModestMailOperation *self;
893 ModestMailOperationPrivate *priv;
895 g_return_if_fail (status != NULL);
896 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER);
898 helper = (XFerMsgAsyncHelper *) user_data;
899 g_return_if_fail (helper != NULL);
901 self = helper->mail_op;
902 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
904 if ((status->position == 1) && (status->of_total == 100))
907 priv->done = status->position;
908 priv->total = status->of_total;
910 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
915 transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, GError **err, gpointer user_data)
917 XFerFolderAsyncHelper *helper = NULL;
918 ModestMailOperation *self = NULL;
919 ModestMailOperationPrivate *priv = NULL;
921 helper = (XFerFolderAsyncHelper *) user_data;
922 self = helper->mail_op;
924 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
927 priv->error = g_error_copy (*err);
929 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
930 } else if (cancelled) {
931 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
932 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
933 MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
934 _("Transference of %s was cancelled."),
935 tny_folder_get_name (folder));
938 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
942 g_slice_free (XFerFolderAsyncHelper, helper);
943 g_object_unref (folder);
944 g_object_unref (into);
945 if (new_folder != NULL)
946 g_object_unref (new_folder);
948 /* Notify about operation end */
949 modest_mail_operation_notify_end (self);
953 modest_mail_operation_xfer_folder (ModestMailOperation *self,
955 TnyFolderStore *parent,
956 gboolean delete_original)
958 XFerFolderAsyncHelper *helper = NULL;
959 ModestMailOperationPrivate *priv = NULL;
960 ModestTnyFolderRules parent_rules, rules;
962 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
963 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
964 g_return_if_fail (TNY_IS_FOLDER (folder));
966 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
968 /* Pick references for async calls */
969 g_object_ref (folder);
970 g_object_ref (parent);
972 /* Get folder rules */
973 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
974 parent_rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
976 /* The moveable restriction is applied also to copy operation */
977 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
978 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
979 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
980 _("mail_in_ui_folder_move_target_error"));
982 /* Notify the queue */
983 modest_mail_operation_notify_end (self);
984 } else if (parent_rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
985 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
986 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
987 _("FIXME: parent folder does not accept new folders"));
989 /* Notify the queue */
990 modest_mail_operation_notify_end (self);
992 helper = g_slice_new0 (XFerFolderAsyncHelper);
993 helper->mail_op = self;
995 /* Move/Copy folder */
996 tny_folder_copy_async (folder,
998 tny_folder_get_name (folder),
1001 transfer_folder_status_cb,
1007 /* ******************************************************************* */
1008 /* ************************** MSG ACTIONS ************************* */
1009 /* ******************************************************************* */
1011 void modest_mail_operation_get_msg (ModestMailOperation *self,
1013 GetMsgAsyncUserCallback user_callback,
1016 GetMsgAsyncHelper *helper = NULL;
1018 ModestMailOperationPrivate *priv;
1020 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1021 g_return_if_fail (TNY_IS_HEADER (header));
1023 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1024 folder = tny_header_get_folder (header);
1026 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1028 /* Get message from folder */
1030 helper = g_slice_new0 (GetMsgAsyncHelper);
1031 helper->mail_op = self;
1032 helper->user_callback = user_callback;
1033 helper->pending_ops = 1;
1034 helper->user_data = user_data;
1036 tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper);
1038 g_object_unref (G_OBJECT (folder));
1040 /* Set status failed and set an error */
1041 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1042 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1043 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1044 _("Error trying to get a message. No folder found for header"));
1049 get_msg_cb (TnyFolder *folder,
1055 GetMsgAsyncHelper *helper = NULL;
1056 ModestMailOperation *self = NULL;
1057 ModestMailOperationPrivate *priv = NULL;
1059 helper = (GetMsgAsyncHelper *) user_data;
1060 g_return_if_fail (helper != NULL);
1061 self = helper->mail_op;
1062 g_return_if_fail (MODEST_IS_MAIL_OPERATION(self));
1063 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1065 helper->pending_ops--;
1067 /* Check errors and cancel */
1069 priv->error = g_error_copy (*error);
1070 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1074 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1075 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1076 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1077 _("Error trying to refresh the contents of %s"),
1078 tny_folder_get_name (folder));
1082 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1084 /* If user defined callback function was defined, call it */
1085 if (helper->user_callback) {
1086 helper->user_callback (self, NULL, msg, helper->user_data);
1091 if (helper->pending_ops == 0) {
1092 g_slice_free (GetMsgAsyncHelper, helper);
1094 /* Notify about operation end */
1095 modest_mail_operation_notify_end (self);
1100 get_msg_status_cb (GObject *obj,
1104 GetMsgAsyncHelper *helper = NULL;
1105 ModestMailOperation *self;
1106 ModestMailOperationPrivate *priv;
1108 g_return_if_fail (status != NULL);
1109 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG);
1111 helper = (GetMsgAsyncHelper *) user_data;
1112 g_return_if_fail (helper != NULL);
1114 /* Temporary FIX: useful when tinymail send us status
1115 information *after* calling the function callback */
1116 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1119 self = helper->mail_op;
1120 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1122 if ((status->position == 1) && (status->of_total == 100))
1128 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1131 /****************************************************/
1133 ModestMailOperation *mail_op;
1135 GetMsgAsyncUserCallback user_callback;
1137 GDestroyNotify notify;
1141 * Used by get_msgs_full_thread to emit the "progress-changed" signal
1142 * from the main loop. We call it inside an idle call to achieve that
1145 notify_get_msgs_full_observers (gpointer data)
1147 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
1149 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1155 GetMsgAsyncUserCallback user_callback;
1159 ModestMailOperation *mail_op;
1160 } NotifyGetMsgsInfo;
1164 * Used by get_msgs_full_thread to call the user_callback for each
1165 * message that has been read
1168 notify_get_msgs_full (gpointer data)
1170 NotifyGetMsgsInfo *info;
1172 info = (NotifyGetMsgsInfo *) data;
1174 /* Call the user callback */
1175 info->user_callback (info->mail_op, info->header, info->msg, info->user_data);
1177 g_slice_free (NotifyGetMsgsInfo, info);
1183 * Used by get_msgs_full_thread to free al the thread resources and to
1184 * call the destroy function for the passed user_data
1187 get_msgs_full_destroyer (gpointer data)
1189 GetFullMsgsInfo *info;
1191 info = (GetFullMsgsInfo *) data;
1194 info->notify (info->user_data);
1197 g_object_unref (info->headers);
1198 g_slice_free (GetFullMsgsInfo, info);
1204 get_msgs_full_thread (gpointer thr_user_data)
1206 GetFullMsgsInfo *info;
1207 ModestMailOperationPrivate *priv = NULL;
1208 TnyIterator *iter = NULL;
1210 info = (GetFullMsgsInfo *) thr_user_data;
1211 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
1213 iter = tny_list_create_iterator (info->headers);
1214 while (!tny_iterator_is_done (iter)) {
1218 header = TNY_HEADER (tny_iterator_get_current (iter));
1219 folder = tny_header_get_folder (header);
1221 /* Get message from folder */
1224 /* The callback will call it per each header */
1225 msg = tny_folder_get_msg (folder, header, &(priv->error));
1230 /* notify progress */
1231 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1232 notify_get_msgs_full_observers,
1233 info->mail_op, NULL);
1235 /* The callback is the responsible for
1236 freeing the message */
1237 if (info->user_callback) {
1238 NotifyGetMsgsInfo *info_notify;
1239 info_notify = g_slice_new0 (NotifyGetMsgsInfo);
1240 info_notify->user_callback = info->user_callback;
1241 info_notify->mail_op = info->mail_op;
1242 info_notify->header = g_object_ref (header);
1243 info_notify->msg = g_object_ref (msg);
1244 info_notify->user_data = info->user_data;
1245 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1246 notify_get_msgs_full,
1249 g_object_unref (msg);
1252 /* Set status failed and set an error */
1253 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1254 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1255 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1256 "Error trying to get a message. No folder found for header");
1258 g_object_unref (header);
1259 tny_iterator_next (iter);
1262 /* Notify about operation end */
1263 g_idle_add (notify_update_account_queue, info->mail_op);
1265 /* Free thread resources. Will be called after all previous idles */
1266 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
1272 modest_mail_operation_get_msgs_full (ModestMailOperation *self,
1273 TnyList *header_list,
1274 GetMsgAsyncUserCallback user_callback,
1276 GDestroyNotify notify)
1279 ModestMailOperationPrivate *priv = NULL;
1280 GetFullMsgsInfo *info = NULL;
1281 gboolean size_ok = TRUE;
1283 GError *error = NULL;
1284 const gint KB = 1024;
1286 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1288 /* Init mail operation */
1289 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1290 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1292 priv->total = tny_list_get_length(header_list);
1294 /* Get msg size limit */
1295 max_size = modest_conf_get_int (modest_runtime_get_conf (),
1296 MODEST_CONF_MSG_SIZE_LIMIT,
1299 g_clear_error (&error);
1300 max_size = G_MAXINT;
1302 max_size = max_size * KB;
1305 /* Check message size limits. If there is only one message
1306 always retrieve it */
1307 if (tny_list_get_length (header_list) > 1) {
1310 iter = tny_list_create_iterator (header_list);
1311 while (!tny_iterator_is_done (iter) && size_ok) {
1312 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1313 if (tny_header_get_message_size (header) >= max_size)
1315 g_object_unref (header);
1316 tny_iterator_next (iter);
1318 g_object_unref (iter);
1322 /* Create the info */
1323 info = g_slice_new0 (GetFullMsgsInfo);
1324 info->mail_op = self;
1325 info->user_callback = user_callback;
1326 info->user_data = user_data;
1327 info->headers = g_object_ref (header_list);
1328 info->notify = notify;
1330 thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL);
1332 /* FIXME: the error msg is different for pop */
1333 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1334 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
1335 _("emev_ni_ui_imap_msg_sizelimit_error"));
1336 /* Remove from queue and free resources */
1337 modest_mail_operation_notify_end (self);
1345 modest_mail_operation_remove_msg (ModestMailOperation *self,
1347 gboolean remove_to_trash)
1350 ModestMailOperationPrivate *priv;
1352 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1353 g_return_if_fail (TNY_IS_HEADER (header));
1355 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1356 folder = tny_header_get_folder (header);
1358 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1360 /* Delete or move to trash */
1361 if (remove_to_trash) {
1362 TnyFolder *trash_folder;
1363 TnyStoreAccount *store_account;
1365 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
1366 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
1367 TNY_FOLDER_TYPE_TRASH);
1372 headers = tny_simple_list_new ();
1373 tny_list_append (headers, G_OBJECT (header));
1374 g_object_unref (header);
1377 modest_mail_operation_xfer_msgs (self, headers, trash_folder, TRUE, NULL, NULL);
1378 g_object_unref (headers);
1379 /* g_object_unref (trash_folder); */
1381 ModestMailOperationPrivate *priv;
1383 /* Set status failed and set an error */
1384 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1385 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1386 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1387 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1388 _("Error trying to delete a message. Trash folder not found"));
1391 g_object_unref (G_OBJECT (store_account));
1393 tny_folder_remove_msg (folder, header, &(priv->error));
1395 tny_folder_sync(folder, TRUE, &(priv->error));
1400 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1402 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1405 g_object_unref (G_OBJECT (folder));
1407 /* Notify about operation end */
1408 modest_mail_operation_notify_end (self);
1412 transfer_msgs_status_cb (GObject *obj,
1416 XFerMsgAsyncHelper *helper = NULL;
1417 ModestMailOperation *self;
1418 ModestMailOperationPrivate *priv;
1420 g_return_if_fail (status != NULL);
1421 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS);
1423 helper = (XFerMsgAsyncHelper *) user_data;
1424 g_return_if_fail (helper != NULL);
1426 self = helper->mail_op;
1427 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1429 if ((status->position == 1) && (status->of_total == 100))
1432 priv->done = status->position;
1433 priv->total = status->of_total;
1435 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1440 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data)
1442 XFerMsgAsyncHelper *helper;
1443 ModestMailOperation *self;
1444 ModestMailOperationPrivate *priv;
1446 helper = (XFerMsgAsyncHelper *) user_data;
1447 self = helper->mail_op;
1449 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1452 priv->error = g_error_copy (*err);
1454 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1455 } else if (cancelled) {
1456 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1457 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1458 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1459 _("Error trying to refresh the contents of %s"),
1460 tny_folder_get_name (folder));
1463 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1466 /* If user defined callback function was defined, call it */
1467 if (helper->user_callback) {
1468 helper->user_callback (priv->source, helper->user_data);
1472 g_object_unref (helper->headers);
1473 g_object_unref (helper->dest_folder);
1474 g_object_unref (helper->mail_op);
1475 g_slice_free (XFerMsgAsyncHelper, helper);
1476 g_object_unref (folder);
1478 /* Notify about operation end */
1479 modest_mail_operation_notify_end (self);
1483 modest_mail_operation_xfer_msgs (ModestMailOperation *self,
1486 gboolean delete_original,
1487 XferMsgsAsynUserCallback user_callback,
1490 ModestMailOperationPrivate *priv;
1492 TnyFolder *src_folder;
1493 XFerMsgAsyncHelper *helper;
1495 ModestTnyFolderRules rules;
1497 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1498 g_return_if_fail (TNY_IS_LIST (headers));
1499 g_return_if_fail (TNY_IS_FOLDER (folder));
1501 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1504 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1506 /* Apply folder rules */
1507 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
1509 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
1510 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1511 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
1512 _("FIXME: folder does not accept msgs"));
1513 /* Notify the queue */
1514 modest_mail_operation_notify_end (self);
1518 /* Create the helper */
1519 helper = g_slice_new0 (XFerMsgAsyncHelper);
1520 helper->mail_op = g_object_ref(self);
1521 helper->dest_folder = g_object_ref(folder);
1522 helper->headers = g_object_ref(headers);
1523 helper->user_callback = user_callback;
1524 helper->user_data = user_data;
1526 /* Get source folder */
1527 iter = tny_list_create_iterator (headers);
1528 header = TNY_HEADER (tny_iterator_get_current (iter));
1529 src_folder = tny_header_get_folder (header);
1530 g_object_unref (header);
1531 g_object_unref (iter);
1533 /* Transfer messages */
1534 tny_folder_transfer_msgs_async (src_folder,
1539 transfer_msgs_status_cb,
1545 on_refresh_folder (TnyFolder *folder,
1550 ModestMailOperation *self;
1551 ModestMailOperationPrivate *priv;
1553 self = MODEST_MAIL_OPERATION (user_data);
1554 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1557 priv->error = g_error_copy (*error);
1558 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1563 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1564 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1565 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1566 _("Error trying to refresh the contents of %s"),
1567 tny_folder_get_name (folder));
1571 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1575 g_object_unref (folder);
1577 /* Notify about operation end */
1578 modest_mail_operation_notify_end (self);
1582 on_refresh_folder_status_update (GObject *obj,
1586 ModestMailOperation *self;
1587 ModestMailOperationPrivate *priv;
1589 g_return_if_fail (status != NULL);
1590 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH);
1592 /* Temporary FIX: useful when tinymail send us status
1593 information *after* calling the function callback */
1594 if (!MODEST_IS_MAIL_OPERATION (user_data))
1597 self = MODEST_MAIL_OPERATION (user_data);
1598 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1600 priv->done = status->position;
1601 priv->total = status->of_total;
1603 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1607 modest_mail_operation_refresh_folder (ModestMailOperation *self,
1610 ModestMailOperationPrivate *priv;
1612 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1614 /* Pick a reference */
1615 g_object_ref (folder);
1617 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1619 /* Refresh the folder. TODO: tinymail could issue a status
1620 updates before the callback call then this could happen. We
1621 must review the design */
1622 tny_folder_refresh_async (folder,
1624 on_refresh_folder_status_update,
1630 * It's used by the mail operation queue to notify the observers
1631 * attached to that signal that the operation finished. We need to use
1632 * that because tinymail does not give us the progress of a given
1633 * operation when it finishes (it directly calls the operation
1637 modest_mail_operation_notify_end (ModestMailOperation *self)
1639 /* Notify the observers about the mail opertation end */
1640 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1642 /* Notify the queue */
1643 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);