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 update_process_msg_status_cb (GObject *obj, */
61 /* TnyStatus *status, */
62 /* gpointer user_data); */
63 static void get_msg_cb (TnyFolder *folder,
69 static void get_msg_status_cb (GObject *obj,
73 static void modest_mail_operation_notify_end (ModestMailOperation *self);
75 enum _ModestMailOperationSignals
77 PROGRESS_CHANGED_SIGNAL,
82 typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate;
83 struct _ModestMailOperationPrivate {
86 ModestMailOperationStatus status;
87 ModestMailOperationId id;
89 ErrorCheckingUserCallback error_checking;
93 #define MODEST_MAIL_OPERATION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
94 MODEST_TYPE_MAIL_OPERATION, \
95 ModestMailOperationPrivate))
97 #define CHECK_EXCEPTION(priv, new_status) if (priv->error) {\
98 priv->status = new_status;\
101 typedef struct _GetMsgAsyncHelper {
102 ModestMailOperation *mail_op;
103 GetMsgAsynUserCallback user_callback;
108 typedef struct _XFerMsgAsyncHelper
110 ModestMailOperation *mail_op;
112 TnyFolder *dest_folder;
113 XferMsgsAsynUserCallback user_callback;
115 } XFerMsgAsyncHelper;
117 typedef struct _XFerFolderAsyncHelper
119 ModestMailOperation *mail_op;
121 } XFerFolderAsyncHelper;
124 static GObjectClass *parent_class = NULL;
126 static guint signals[NUM_SIGNALS] = {0};
129 modest_mail_operation_get_type (void)
131 static GType my_type = 0;
133 static const GTypeInfo my_info = {
134 sizeof(ModestMailOperationClass),
135 NULL, /* base init */
136 NULL, /* base finalize */
137 (GClassInitFunc) modest_mail_operation_class_init,
138 NULL, /* class finalize */
139 NULL, /* class data */
140 sizeof(ModestMailOperation),
142 (GInstanceInitFunc) modest_mail_operation_init,
145 my_type = g_type_register_static (G_TYPE_OBJECT,
146 "ModestMailOperation",
153 modest_mail_operation_class_init (ModestMailOperationClass *klass)
155 GObjectClass *gobject_class;
156 gobject_class = (GObjectClass*) klass;
158 parent_class = g_type_class_peek_parent (klass);
159 gobject_class->finalize = modest_mail_operation_finalize;
161 g_type_class_add_private (gobject_class, sizeof(ModestMailOperationPrivate));
164 * ModestMailOperation::progress-changed
165 * @self: the #MailOperation that emits the signal
166 * @user_data: user data set when the signal handler was connected
168 * Emitted when the progress of a mail operation changes
170 signals[PROGRESS_CHANGED_SIGNAL] =
171 g_signal_new ("progress-changed",
172 G_TYPE_FROM_CLASS (gobject_class),
174 G_STRUCT_OFFSET (ModestMailOperationClass, progress_changed),
176 g_cclosure_marshal_VOID__VOID,
181 modest_mail_operation_init (ModestMailOperation *obj)
183 ModestMailOperationPrivate *priv;
185 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
187 priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID;
188 priv->id = MODEST_MAIL_OPERATION_ID_UNKNOWN;
196 modest_mail_operation_finalize (GObject *obj)
198 ModestMailOperationPrivate *priv;
200 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
203 g_error_free (priv->error);
207 g_object_unref (priv->source);
211 G_OBJECT_CLASS(parent_class)->finalize (obj);
215 modest_mail_operation_new (ModestMailOperationId id,
218 ModestMailOperation *obj;
219 ModestMailOperationPrivate *priv;
221 obj = MODEST_MAIL_OPERATION(g_object_new(MODEST_TYPE_MAIL_OPERATION, NULL));
222 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
226 priv->source = g_object_ref(source);
232 modest_mail_operation_new_with_error_handling (ModestMailOperationId id,
234 ErrorCheckingUserCallback error_handler)
236 ModestMailOperation *obj;
237 ModestMailOperationPrivate *priv;
239 obj = modest_mail_operation_new (id, source);
240 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
242 g_return_val_if_fail (error_handler != NULL, obj);
243 priv->error_checking = error_handler;
249 modest_mail_operation_execute_error_handler (ModestMailOperation *self)
251 ModestMailOperationPrivate *priv;
253 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
254 g_return_if_fail(priv->status != MODEST_MAIL_OPERATION_STATUS_SUCCESS);
256 if (priv->error_checking == NULL) return;
257 priv->error_checking (priv->source, self);
261 ModestMailOperationId
262 modest_mail_operation_get_id (ModestMailOperation *self)
264 ModestMailOperationPrivate *priv;
266 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
272 modest_mail_operation_is_mine (ModestMailOperation *self,
275 ModestMailOperationPrivate *priv;
277 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
278 if (priv->source == NULL) return FALSE;
280 return priv->source == me;
285 modest_mail_operation_send_mail (ModestMailOperation *self,
286 TnyTransportAccount *transport_account,
289 TnySendQueue *send_queue;
291 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
292 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
293 g_return_if_fail (TNY_IS_MSG (msg));
295 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
296 if (!TNY_IS_SEND_QUEUE(send_queue))
297 g_printerr ("modest: could not find send queue for account\n");
300 tny_send_queue_add (send_queue, msg, &err);
302 g_printerr ("modest: error adding msg to send queue: %s\n",
306 /* g_message ("modest: message added to send queue"); */
310 /* Notify about operation end */
311 modest_mail_operation_notify_end (self);
315 modest_mail_operation_send_new_mail (ModestMailOperation *self,
316 TnyTransportAccount *transport_account,
317 const gchar *from, const gchar *to,
318 const gchar *cc, const gchar *bcc,
319 const gchar *subject, const gchar *plain_body,
320 const gchar *html_body,
321 const GList *attachments_list,
322 TnyHeaderFlags priority_flags)
325 ModestMailOperationPrivate *priv = NULL;
326 /* GList *node = NULL; */
328 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
329 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
331 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
333 /* Check parametters */
335 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
336 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
337 _("Error trying to send a mail. You need to set at least one recipient"));
341 if (html_body == NULL) {
342 new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
344 new_msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
347 g_printerr ("modest: failed to create a new msg\n");
351 /* TODO: add priority handling. It's received in the priority_flags operator, and
352 it should have effect in the sending operation */
354 /* Call mail operation */
355 modest_mail_operation_send_mail (self, transport_account, new_msg);
358 g_object_unref (G_OBJECT (new_msg));
362 modest_mail_operation_save_to_drafts (ModestMailOperation *self,
363 TnyTransportAccount *transport_account,
364 const gchar *from, const gchar *to,
365 const gchar *cc, const gchar *bcc,
366 const gchar *subject, const gchar *plain_body,
367 const gchar *html_body,
368 const GList *attachments_list,
369 TnyHeaderFlags priority_flags)
372 TnyFolder *folder = NULL;
373 ModestMailOperationPrivate *priv = NULL;
376 /* GList *node = NULL; */
378 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
379 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
381 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
383 if (html_body == NULL) {
384 msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
386 msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
389 g_printerr ("modest: failed to create a new msg\n");
393 folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
395 g_printerr ("modest: failed to find Drafts folder\n");
399 tny_folder_add_msg (folder, msg, &err);
401 g_printerr ("modest: error adding msg to Drafts folder: %s",
407 modest_mail_operation_notify_end (self);
412 g_object_unref (G_OBJECT(msg));
414 g_object_unref (G_OBJECT(folder));
419 ModestMailOperation *mail_op;
420 TnyStoreAccount *account;
421 TnyTransportAccount *transport_account;
425 recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
428 TnyList *folders = tny_simple_list_new ();
430 tny_folder_store_get_folders (store, folders, query, NULL);
431 iter = tny_list_create_iterator (folders);
433 while (!tny_iterator_is_done (iter)) {
435 TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
437 tny_list_prepend (all_folders, G_OBJECT (folder));
438 recurse_folders (folder, query, all_folders);
439 g_object_unref (G_OBJECT (folder));
441 tny_iterator_next (iter);
443 g_object_unref (G_OBJECT (iter));
444 g_object_unref (G_OBJECT (folders));
448 * Used by update_account_thread to emit the "progress-changed" signal
449 * from the main loop. We call it inside an idle call to achieve that
452 notify_update_account_observers (gpointer data)
454 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
456 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
462 * Used by update_account_thread to notify the queue from the main
463 * loop. We call it inside an idle call to achieve that
466 notify_update_account_queue (gpointer data)
468 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
470 modest_mail_operation_notify_end (mail_op);
471 g_object_unref (mail_op);
477 update_account_thread (gpointer thr_user_data)
479 UpdateAccountInfo *info;
480 TnyList *all_folders = NULL;
481 TnyIterator *iter = NULL;
482 TnyFolderStoreQuery *query = NULL;
483 ModestMailOperationPrivate *priv;
484 ModestTnySendQueue *send_queue;
487 info = (UpdateAccountInfo *) thr_user_data;
488 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
490 /* Get all the folders We can do it synchronously because
491 we're already running in a different thread than the UI */
492 all_folders = tny_simple_list_new ();
493 query = tny_folder_store_query_new ();
494 tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
495 tny_folder_store_get_folders (TNY_FOLDER_STORE (info->account),
500 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
504 iter = tny_list_create_iterator (all_folders);
505 while (!tny_iterator_is_done (iter)) {
506 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
508 recurse_folders (folder, query, all_folders);
509 tny_iterator_next (iter);
511 g_object_unref (G_OBJECT (iter));
513 /* Update status and notify. We need to call the notification
514 with a source functopm in order to call it from the main
515 loop. We need that in order not to get into trouble with
516 Gtk+. We use a timeout in order to provide more status
517 information, because the sync tinymail call does not
518 provide it for the moment */
519 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
521 /* Refresh folders */
522 iter = tny_list_create_iterator (all_folders);
523 while (!tny_iterator_is_done (iter) && !priv->error) {
525 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
527 /* Refresh the folder */
528 tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
530 /* TODO: Apply retrieval types */
532 /* TODO: apply per-message size limits */
534 /* TODO: apply message count limit */
537 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
540 g_object_unref (G_OBJECT (folder));
541 tny_iterator_next (iter);
543 g_object_unref (G_OBJECT (iter));
544 g_source_remove (timeout);
547 priv->id = MODEST_MAIL_OPERATION_ID_SEND;
549 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(info->transport_account));
551 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
552 modest_tny_send_queue_flush (send_queue);
553 g_source_remove (timeout);
555 g_object_unref (G_OBJECT(send_queue));
557 /* Check if the operation was a success */
559 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
561 /* Update the last updated key */
562 modest_account_mgr_set_int (modest_runtime_get_account_mgr (),
563 tny_account_get_id (TNY_ACCOUNT (info->account)),
564 MODEST_ACCOUNT_LAST_UPDATED,
570 /* Notify about operation end. Note that the info could be
571 freed before this idle happens, but the mail operation will
573 g_idle_add (notify_update_account_queue, info->mail_op);
576 g_object_unref (query);
577 g_object_unref (all_folders);
578 g_object_unref (info->account);
579 g_object_unref (info->transport_account);
580 g_slice_free (UpdateAccountInfo, info);
586 modest_mail_operation_update_account (ModestMailOperation *self,
587 const gchar *account_name)
590 UpdateAccountInfo *info;
591 ModestMailOperationPrivate *priv;
592 TnyStoreAccount *modest_account;
593 TnyTransportAccount *transport_account;
595 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
596 g_return_val_if_fail (account_name, FALSE);
598 /* Init mail operation. Set total and done to 0, and do not
599 update them, this way the progress objects will know that
600 we have no clue about the number of the objects */
601 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
604 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
606 /* Get the Modest account */
607 modest_account = (TnyStoreAccount *)
608 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store (),
610 TNY_ACCOUNT_TYPE_STORE);
612 if (!modest_account) {
613 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
614 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
615 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
616 "cannot get tny store account for %s\n", account_name);
617 modest_mail_operation_notify_end (self);
621 /* Get the transport account, we can not do it in the thread
622 due to some problems with dbus */
623 transport_account = (TnyTransportAccount *)
624 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
626 if (!transport_account) {
627 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
628 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
629 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
630 "cannot get tny transport account for %s\n", account_name);
631 modest_mail_operation_notify_end (self);
635 /* Create the helper object */
636 info = g_slice_new (UpdateAccountInfo);
637 info->mail_op = self;
638 info->account = modest_account;
639 info->transport_account = transport_account;
641 thread = g_thread_create (update_account_thread, info, FALSE, NULL);
646 ModestMailOperationStatus
647 modest_mail_operation_get_status (ModestMailOperation *self)
649 ModestMailOperationPrivate *priv;
651 g_return_val_if_fail (self, MODEST_MAIL_OPERATION_STATUS_INVALID);
652 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self),
653 MODEST_MAIL_OPERATION_STATUS_INVALID);
655 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
660 modest_mail_operation_get_error (ModestMailOperation *self)
662 ModestMailOperationPrivate *priv;
664 g_return_val_if_fail (self, NULL);
665 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
667 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
672 modest_mail_operation_cancel (ModestMailOperation *self)
674 ModestMailOperationPrivate *priv;
676 if (!MODEST_IS_MAIL_OPERATION (self)) {
677 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
681 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
683 /* TODO: Tinymail does not support cancel operation */
684 /* tny_account_cancel (); */
687 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
689 /* Notify about operation end */
690 modest_mail_operation_notify_end (self);
696 modest_mail_operation_get_task_done (ModestMailOperation *self)
698 ModestMailOperationPrivate *priv;
700 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
702 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
707 modest_mail_operation_get_task_total (ModestMailOperation *self)
709 ModestMailOperationPrivate *priv;
711 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
713 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
718 modest_mail_operation_is_finished (ModestMailOperation *self)
720 ModestMailOperationPrivate *priv;
721 gboolean retval = FALSE;
723 if (!MODEST_IS_MAIL_OPERATION (self)) {
724 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
728 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
730 if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS ||
731 priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED ||
732 priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED ||
733 priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) {
742 /* ******************************************************************* */
743 /* ************************** STORE ACTIONS ************************* */
744 /* ******************************************************************* */
748 modest_mail_operation_create_folder (ModestMailOperation *self,
749 TnyFolderStore *parent,
752 ModestTnyFolderRules rules;
753 ModestMailOperationPrivate *priv;
754 TnyFolder *new_folder = NULL;
755 gboolean can_create = FALSE;
757 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
758 g_return_val_if_fail (name, NULL);
760 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
763 if (!TNY_IS_FOLDER (parent)) {
764 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
765 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
766 _("mail_in_ui_folder_create_error"));
768 /* Check folder rules */
769 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
770 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)
771 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
772 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
773 _("mail_in_ui_folder_create_error"));
779 /* Create the folder */
780 new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
781 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
784 /* Notify about operation end */
785 modest_mail_operation_notify_end (self);
791 modest_mail_operation_remove_folder (ModestMailOperation *self,
793 gboolean remove_to_trash)
796 ModestMailOperationPrivate *priv;
797 ModestTnyFolderRules rules;
799 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
800 g_return_if_fail (TNY_IS_FOLDER (folder));
802 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
804 /* Check folder rules */
805 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
806 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE) {
807 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
808 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
809 _("mail_in_ui_folder_delete_error"));
813 /* Get the account */
814 account = tny_folder_get_account (folder);
816 /* Delete folder or move to trash */
817 if (remove_to_trash) {
818 TnyFolder *trash_folder = NULL;
819 /* TnyFolder *trash_folder, *new_folder; */
820 trash_folder = modest_tny_account_get_special_folder (account,
821 TNY_FOLDER_TYPE_TRASH);
822 /* TODO: error_handling */
823 modest_mail_operation_xfer_folder (self, folder,
824 TNY_FOLDER_STORE (trash_folder), TRUE);
825 /* new_folder = modest_mail_operation_xfer_folder (self, folder, */
826 /* TNY_FOLDER_STORE (trash_folder), TRUE); */
827 /* g_object_unref (G_OBJECT (new_folder)); */
829 TnyFolderStore *parent = tny_folder_get_folder_store (folder);
831 tny_folder_store_remove_folder (parent, folder, &(priv->error));
832 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
835 g_object_unref (G_OBJECT (parent));
837 g_object_unref (G_OBJECT (account));
840 /* Notify about operation end */
841 modest_mail_operation_notify_end (self);
845 modest_mail_operation_rename_folder (ModestMailOperation *self,
849 ModestMailOperationPrivate *priv;
850 ModestTnyFolderRules rules;
852 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
853 g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
854 g_return_if_fail (name);
856 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
858 /* Check folder rules */
859 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
860 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
861 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
862 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
863 _("FIXME: unable to rename"));
865 /* Rename. Camel handles folder subscription/unsubscription */
866 TnyFolderStore *into;
869 into = tny_folder_get_folder_store (folder);
870 nfol = tny_folder_copy (folder, into, name, TRUE, &(priv->error));
872 g_object_unref (into);
874 g_object_unref (nfol);
876 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
880 /* Notify about operation end */
881 modest_mail_operation_notify_end (self);
885 transfer_folder_status_cb (GObject *obj,
889 XFerMsgAsyncHelper *helper = NULL;
890 ModestMailOperation *self;
891 ModestMailOperationPrivate *priv;
893 g_return_if_fail (status != NULL);
894 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER);
896 helper = (XFerMsgAsyncHelper *) user_data;
897 g_return_if_fail (helper != NULL);
899 self = helper->mail_op;
900 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
902 if ((status->position == 1) && (status->of_total == 100))
905 priv->done = status->position;
906 priv->total = status->of_total;
908 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
913 transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, GError **err, gpointer user_data)
915 XFerFolderAsyncHelper *helper = NULL;
916 ModestMailOperation *self = NULL;
917 ModestMailOperationPrivate *priv = NULL;
919 helper = (XFerFolderAsyncHelper *) user_data;
920 self = helper->mail_op;
922 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
925 priv->error = g_error_copy (*err);
927 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
928 } else if (cancelled) {
929 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
930 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
931 MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
932 _("Transference of %s was cancelled."),
933 tny_folder_get_name (folder));
936 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
940 g_slice_free (XFerFolderAsyncHelper, helper);
941 g_object_unref (folder);
942 g_object_unref (into);
943 if (new_folder != NULL)
944 g_object_unref (new_folder);
946 /* Notify about operation end */
947 modest_mail_operation_notify_end (self);
951 modest_mail_operation_xfer_folder (ModestMailOperation *self,
953 TnyFolderStore *parent,
954 gboolean delete_original)
956 ModestMailOperationPrivate *priv;
957 TnyFolder *new_folder = NULL;
958 ModestTnyFolderRules rules;
960 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
961 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
962 g_return_val_if_fail (TNY_IS_FOLDER (folder), NULL);
964 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
966 /* The moveable restriction is applied also to copy operation */
967 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
968 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
969 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
970 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
971 _("FIXME: unable to rename"));
973 /* Move/Copy folder */
974 new_folder = tny_folder_copy (folder,
976 tny_folder_get_name (folder),
981 /* Notify about operation end */
982 modest_mail_operation_notify_end (self);
988 modest_mail_operation_xfer_folder_async (ModestMailOperation *self,
990 TnyFolderStore *parent,
991 gboolean delete_original)
993 XFerFolderAsyncHelper *helper = NULL;
994 ModestMailOperationPrivate *priv = NULL;
995 ModestTnyFolderRules rules;
997 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
998 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
999 g_return_if_fail (TNY_IS_FOLDER (folder));
1001 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1003 /* Pick references for async calls */
1004 g_object_ref (folder);
1005 g_object_ref (parent);
1007 /* The moveable restriction is applied also to copy operation */
1008 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
1009 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
1010 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1011 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
1012 _("FIXME: unable to rename"));
1014 /* Notify the queue */
1015 modest_mail_operation_notify_end (self);
1017 helper = g_slice_new0 (XFerFolderAsyncHelper);
1018 helper->mail_op = self;
1020 /* Move/Copy folder */
1021 tny_folder_copy_async (folder,
1023 tny_folder_get_name (folder),
1026 transfer_folder_status_cb,
1032 /* ******************************************************************* */
1033 /* ************************** MSG ACTIONS ************************* */
1034 /* ******************************************************************* */
1036 void modest_mail_operation_get_msg (ModestMailOperation *self,
1038 GetMsgAsynUserCallback user_callback,
1041 GetMsgAsyncHelper *helper = NULL;
1043 ModestMailOperationPrivate *priv;
1045 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1046 g_return_if_fail (TNY_IS_HEADER (header));
1048 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1049 folder = tny_header_get_folder (header);
1051 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1053 /* Get message from folder */
1055 helper = g_slice_new0 (GetMsgAsyncHelper);
1056 helper->mail_op = self;
1057 helper->user_callback = user_callback;
1058 helper->pending_ops = 1;
1059 helper->user_data = user_data;
1061 tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper);
1063 g_object_unref (G_OBJECT (folder));
1065 /* Set status failed and set an error */
1066 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1067 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1068 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1069 _("Error trying to get a message. No folder found for header"));
1074 get_msg_cb (TnyFolder *folder,
1080 GetMsgAsyncHelper *helper = NULL;
1081 ModestMailOperation *self = NULL;
1082 ModestMailOperationPrivate *priv = NULL;
1084 helper = (GetMsgAsyncHelper *) user_data;
1085 g_return_if_fail (helper != NULL);
1086 self = helper->mail_op;
1087 g_return_if_fail (MODEST_IS_MAIL_OPERATION(self));
1088 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1090 helper->pending_ops--;
1092 /* Check errors and cancel */
1094 priv->error = g_error_copy (*error);
1095 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1099 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1100 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1101 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1102 _("Error trying to refresh the contents of %s"),
1103 tny_folder_get_name (folder));
1107 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1109 /* If user defined callback function was defined, call it */
1110 if (helper->user_callback) {
1111 helper->user_callback (priv->source, msg, helper->user_data);
1116 if (helper->pending_ops == 0) {
1117 g_slice_free (GetMsgAsyncHelper, helper);
1119 /* Notify about operation end */
1120 modest_mail_operation_notify_end (self);
1125 get_msg_status_cb (GObject *obj,
1129 GetMsgAsyncHelper *helper = NULL;
1130 ModestMailOperation *self;
1131 ModestMailOperationPrivate *priv;
1133 g_return_if_fail (status != NULL);
1134 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG);
1136 helper = (GetMsgAsyncHelper *) user_data;
1137 g_return_if_fail (helper != NULL);
1139 /* Temporary FIX: useful when tinymail send us status
1140 information *after* calling the function callback */
1141 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1144 self = helper->mail_op;
1145 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1147 if ((status->position == 1) && (status->of_total == 100))
1153 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1156 /****************************************************/
1158 ModestMailOperation *mail_op;
1160 GetMsgAsynUserCallback user_callback;
1162 GDestroyNotify notify;
1166 * Used by get_msgs_full_thread to emit the "progress-changed" signal
1167 * from the main loop. We call it inside an idle call to achieve that
1170 notify_get_msgs_full_observers (gpointer data)
1172 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
1174 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1176 g_object_unref (mail_op);
1182 GetMsgAsynUserCallback user_callback;
1186 } NotifyGetMsgsInfo;
1190 * Used by get_msgs_full_thread to call the user_callback for each
1191 * message that has been read
1194 notify_get_msgs_full (gpointer data)
1196 NotifyGetMsgsInfo *info;
1198 info = (NotifyGetMsgsInfo *) data;
1200 /* Call the user callback */
1201 info->user_callback (info->source, info->msg, info->user_data);
1203 g_slice_free (NotifyGetMsgsInfo, info);
1209 * Used by get_msgs_full_thread to free al the thread resources and to
1210 * call the destroy function for the passed user_data
1213 get_msgs_full_destroyer (gpointer data)
1215 GetFullMsgsInfo *info;
1217 info = (GetFullMsgsInfo *) data;
1220 info->notify (info->user_data);
1223 g_object_unref (info->headers);
1224 g_slice_free (GetFullMsgsInfo, info);
1230 get_msgs_full_thread (gpointer thr_user_data)
1232 GetFullMsgsInfo *info;
1233 ModestMailOperationPrivate *priv = NULL;
1234 TnyIterator *iter = NULL;
1236 info = (GetFullMsgsInfo *) thr_user_data;
1237 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
1239 iter = tny_list_create_iterator (info->headers);
1240 while (!tny_iterator_is_done (iter)) {
1244 header = TNY_HEADER (tny_iterator_get_current (iter));
1245 folder = tny_header_get_folder (header);
1247 /* Get message from folder */
1250 /* The callback will call it per each header */
1251 msg = tny_folder_get_msg (folder, header, &(priv->error));
1256 /* notify progress */
1257 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1258 notify_get_msgs_full_observers,
1259 g_object_ref (info->mail_op), NULL);
1261 /* The callback is the responsible for
1262 freeing the message */
1263 if (info->user_callback) {
1264 NotifyGetMsgsInfo *info_notify;
1265 info_notify = g_slice_new0 (NotifyGetMsgsInfo);
1266 info_notify->user_callback = info->user_callback;
1267 info_notify->source = priv->source;
1268 info_notify->msg = msg;
1269 info_notify->user_data = info->user_data;
1270 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1271 notify_get_msgs_full,
1274 g_object_unref (msg);
1278 /* Set status failed and set an error */
1279 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1280 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1281 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1282 "Error trying to get a message. No folder found for header");
1284 g_object_unref (header);
1285 tny_iterator_next (iter);
1288 /* Notify about operation end */
1289 g_idle_add (notify_update_account_queue, info->mail_op);
1291 /* Free thread resources. Will be called after all previous idles */
1292 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
1298 modest_mail_operation_get_msgs_full (ModestMailOperation *self,
1299 TnyList *header_list,
1300 GetMsgAsynUserCallback user_callback,
1302 GDestroyNotify notify)
1305 ModestMailOperationPrivate *priv = NULL;
1306 GetFullMsgsInfo *info = NULL;
1307 gboolean size_ok = TRUE;
1309 GError *error = NULL;
1310 const gint KB = 1024;
1312 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1314 /* Init mail operation */
1315 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1316 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1318 priv->total = tny_list_get_length(header_list);
1320 /* Get msg size limit */
1321 max_size = modest_conf_get_int (modest_runtime_get_conf (),
1322 MODEST_CONF_MSG_SIZE_LIMIT,
1325 g_clear_error (&error);
1326 max_size = G_MAXINT;
1328 max_size = max_size * KB;
1331 /* Check message size limits. If there is only one message
1332 always retrieve it */
1333 if (tny_list_get_length (header_list) > 1) {
1336 iter = tny_list_create_iterator (header_list);
1337 while (!tny_iterator_is_done (iter) && size_ok) {
1338 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1339 if (tny_header_get_message_size (header) >= max_size)
1341 g_object_unref (header);
1342 tny_iterator_next (iter);
1344 g_object_unref (iter);
1348 /* Create the info */
1349 info = g_slice_new0 (GetFullMsgsInfo);
1350 info->mail_op = self;
1351 info->user_callback = user_callback;
1352 info->user_data = user_data;
1353 info->headers = g_object_ref (header_list);
1354 info->notify = notify;
1356 thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL);
1358 /* FIXME: the error msg is different for pop */
1359 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1360 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
1361 _("emev_ni_ui_imap_msg_sizelimit_error"));
1362 /* Remove from queue and free resources */
1363 modest_mail_operation_notify_end (self);
1371 modest_mail_operation_remove_msg (ModestMailOperation *self,
1373 gboolean remove_to_trash)
1376 ModestMailOperationPrivate *priv;
1378 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1379 g_return_if_fail (TNY_IS_HEADER (header));
1381 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1382 folder = tny_header_get_folder (header);
1384 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1386 /* Delete or move to trash */
1387 if (remove_to_trash) {
1388 TnyFolder *trash_folder;
1389 TnyStoreAccount *store_account;
1391 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
1392 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
1393 TNY_FOLDER_TYPE_TRASH);
1398 headers = tny_simple_list_new ();
1399 tny_list_append (headers, G_OBJECT (header));
1400 g_object_unref (header);
1403 modest_mail_operation_xfer_msgs (self, headers, trash_folder, TRUE, NULL, NULL);
1404 g_object_unref (headers);
1405 /* g_object_unref (trash_folder); */
1407 ModestMailOperationPrivate *priv;
1409 /* Set status failed and set an error */
1410 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1411 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1412 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1413 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1414 _("Error trying to delete a message. Trash folder not found"));
1417 g_object_unref (G_OBJECT (store_account));
1419 tny_folder_remove_msg (folder, header, &(priv->error));
1421 tny_folder_sync(folder, TRUE, &(priv->error));
1426 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1428 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1431 g_object_unref (G_OBJECT (folder));
1433 /* Notify about operation end */
1434 modest_mail_operation_notify_end (self);
1438 transfer_msgs_status_cb (GObject *obj,
1442 XFerMsgAsyncHelper *helper = NULL;
1443 ModestMailOperation *self;
1444 ModestMailOperationPrivate *priv;
1446 g_return_if_fail (status != NULL);
1447 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS);
1449 helper = (XFerMsgAsyncHelper *) user_data;
1450 g_return_if_fail (helper != NULL);
1452 self = helper->mail_op;
1453 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1455 if ((status->position == 1) && (status->of_total == 100))
1458 priv->done = status->position;
1459 priv->total = status->of_total;
1461 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1466 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data)
1468 XFerMsgAsyncHelper *helper;
1469 ModestMailOperation *self;
1470 ModestMailOperationPrivate *priv;
1472 helper = (XFerMsgAsyncHelper *) user_data;
1473 self = helper->mail_op;
1475 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1478 priv->error = g_error_copy (*err);
1480 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1481 } else if (cancelled) {
1482 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1483 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1484 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1485 _("Error trying to refresh the contents of %s"),
1486 tny_folder_get_name (folder));
1489 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1492 /* If user defined callback function was defined, call it */
1493 if (helper->user_callback) {
1494 helper->user_callback (priv->source, helper->user_data);
1498 g_object_unref (helper->headers);
1499 g_object_unref (helper->dest_folder);
1500 g_object_unref (helper->mail_op);
1501 g_slice_free (XFerMsgAsyncHelper, helper);
1502 g_object_unref (folder);
1504 /* Notify about operation end */
1505 modest_mail_operation_notify_end (self);
1509 modest_mail_operation_xfer_msgs (ModestMailOperation *self,
1512 gboolean delete_original,
1513 XferMsgsAsynUserCallback user_callback,
1516 ModestMailOperationPrivate *priv;
1518 TnyFolder *src_folder;
1519 XFerMsgAsyncHelper *helper;
1522 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1523 g_return_if_fail (TNY_IS_LIST (headers));
1524 g_return_if_fail (TNY_IS_FOLDER (folder));
1526 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1529 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1531 /* Create the helper */
1532 helper = g_slice_new0 (XFerMsgAsyncHelper);
1533 helper->mail_op = g_object_ref(self);
1534 helper->dest_folder = g_object_ref(folder);
1535 helper->headers = g_object_ref(headers);
1536 helper->user_callback = user_callback;
1537 helper->user_data = user_data;
1539 /* Get source folder */
1540 iter = tny_list_create_iterator (headers);
1541 header = TNY_HEADER (tny_iterator_get_current (iter));
1542 src_folder = tny_header_get_folder (header);
1543 g_object_unref (header);
1544 g_object_unref (iter);
1546 /* Transfer messages */
1547 tny_folder_transfer_msgs_async (src_folder,
1552 transfer_msgs_status_cb,
1558 on_refresh_folder (TnyFolder *folder,
1563 ModestMailOperation *self;
1564 ModestMailOperationPrivate *priv;
1566 self = MODEST_MAIL_OPERATION (user_data);
1567 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1570 priv->error = g_error_copy (*error);
1571 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1576 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1577 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1578 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1579 _("Error trying to refresh the contents of %s"),
1580 tny_folder_get_name (folder));
1584 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1588 g_object_unref (folder);
1590 /* Notify about operation end */
1591 modest_mail_operation_notify_end (self);
1595 on_refresh_folder_status_update (GObject *obj,
1599 ModestMailOperation *self;
1600 ModestMailOperationPrivate *priv;
1602 g_return_if_fail (status != NULL);
1603 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH);
1605 /* Temporary FIX: useful when tinymail send us status
1606 information *after* calling the function callback */
1607 if (!MODEST_IS_MAIL_OPERATION (user_data))
1610 self = MODEST_MAIL_OPERATION (user_data);
1611 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1613 priv->done = status->position;
1614 priv->total = status->of_total;
1616 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1620 modest_mail_operation_refresh_folder (ModestMailOperation *self,
1623 ModestMailOperationPrivate *priv;
1625 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1627 /* Pick a reference */
1628 g_object_ref (folder);
1630 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1632 /* Refresh the folder. TODO: tinymail could issue a status
1633 updates before the callback call then this could happen. We
1634 must review the design */
1635 tny_folder_refresh_async (folder,
1637 on_refresh_folder_status_update,
1643 * It's used by the mail operation queue to notify the observers
1644 * attached to that signal that the operation finished. We need to use
1645 * that because tinymail does not give us the progress of a given
1646 * operation when it finishes (it directly calls the operation
1650 modest_mail_operation_notify_end (ModestMailOperation *self)
1652 /* Notify the observers about the mail opertation end */
1653 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1655 /* Notify the queue */
1656 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);