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-tny-account.h>
45 #include <modest-tny-send-queue.h>
46 #include <modest-runtime.h>
47 #include "modest-text-utils.h"
48 #include "modest-tny-msg.h"
49 #include "modest-tny-folder.h"
50 #include "modest-tny-platform-factory.h"
51 #include "modest-marshal.h"
52 #include "modest-error.h"
54 /* 'private'/'protected' functions */
55 static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
56 static void modest_mail_operation_init (ModestMailOperation *obj);
57 static void modest_mail_operation_finalize (GObject *obj);
59 /* static void update_process_msg_status_cb (GObject *obj, */
60 /* TnyStatus *status, */
61 /* gpointer user_data); */
62 static void get_msg_cb (TnyFolder *folder,
68 static void get_msg_status_cb (GObject *obj,
73 enum _ModestMailOperationSignals
75 PROGRESS_CHANGED_SIGNAL,
80 typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate;
81 struct _ModestMailOperationPrivate {
84 ModestMailOperationStatus status;
85 ModestMailOperationId id;
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 GetMsgAsynUserCallback 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 ModestMailOperationId
230 modest_mail_operation_get_id (ModestMailOperation *self)
232 ModestMailOperationPrivate *priv;
234 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
240 modest_mail_operation_is_mine (ModestMailOperation *self,
243 ModestMailOperationPrivate *priv;
245 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
246 if (priv->source == NULL) return FALSE;
248 return priv->source == me;
253 modest_mail_operation_send_mail (ModestMailOperation *self,
254 TnyTransportAccount *transport_account,
257 TnySendQueue *send_queue;
259 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
260 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
261 g_return_if_fail (TNY_IS_MSG (msg));
263 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
264 if (!TNY_IS_SEND_QUEUE(send_queue))
265 g_printerr ("modest: could not find send queue for account\n");
268 tny_send_queue_add (send_queue, msg, &err);
270 g_printerr ("modest: error adding msg to send queue: %s\n",
274 /* g_message ("modest: message added to send queue"); */
278 /* Notify the queue */
279 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
283 modest_mail_operation_send_new_mail (ModestMailOperation *self,
284 TnyTransportAccount *transport_account,
285 const gchar *from, const gchar *to,
286 const gchar *cc, const gchar *bcc,
287 const gchar *subject, const gchar *plain_body,
288 const gchar *html_body,
289 const GList *attachments_list,
290 TnyHeaderFlags priority_flags)
293 ModestMailOperationPrivate *priv = NULL;
294 /* GList *node = NULL; */
296 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
297 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
299 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
301 /* Check parametters */
303 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
304 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
305 _("Error trying to send a mail. You need to set at least one recipient"));
309 if (html_body == NULL) {
310 new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
312 new_msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
315 g_printerr ("modest: failed to create a new msg\n");
319 /* TODO: add priority handling. It's received in the priority_flags operator, and
320 it should have effect in the sending operation */
322 /* Call mail operation */
323 modest_mail_operation_send_mail (self, transport_account, new_msg);
326 g_object_unref (G_OBJECT (new_msg));
330 modest_mail_operation_save_to_drafts (ModestMailOperation *self,
331 TnyTransportAccount *transport_account,
332 const gchar *from, const gchar *to,
333 const gchar *cc, const gchar *bcc,
334 const gchar *subject, const gchar *plain_body,
335 const gchar *html_body,
336 const GList *attachments_list,
337 TnyHeaderFlags priority_flags)
340 TnyFolder *folder = NULL;
341 ModestMailOperationPrivate *priv = NULL;
344 /* GList *node = NULL; */
346 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
347 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
349 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
351 if (html_body == NULL) {
352 msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
354 msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
357 g_printerr ("modest: failed to create a new msg\n");
361 folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
363 g_printerr ("modest: failed to find Drafts folder\n");
367 tny_folder_add_msg (folder, msg, &err);
369 g_printerr ("modest: error adding msg to Drafts folder: %s",
375 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
380 g_object_unref (G_OBJECT(msg));
382 g_object_unref (G_OBJECT(folder));
387 ModestMailOperation *mail_op;
388 TnyStoreAccount *account;
389 TnyTransportAccount *transport_account;
393 recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
396 TnyList *folders = tny_simple_list_new ();
398 tny_folder_store_get_folders (store, folders, query, NULL);
399 iter = tny_list_create_iterator (folders);
401 while (!tny_iterator_is_done (iter)) {
403 TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
405 tny_list_prepend (all_folders, G_OBJECT (folder));
406 recurse_folders (folder, query, all_folders);
407 g_object_unref (G_OBJECT (folder));
409 tny_iterator_next (iter);
411 g_object_unref (G_OBJECT (iter));
412 g_object_unref (G_OBJECT (folders));
416 * Used by update_account_thread to emit the "progress-changed" signal
417 * from the main loop. We call it inside an idle call to achieve that
420 notify_update_account_observers (gpointer data)
422 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
424 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
430 * Used by update_account_thread to notify the queue from the main
431 * loop. We call it inside an idle call to achieve that
434 notify_update_account_queue (gpointer data)
436 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
438 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
440 g_object_unref (mail_op);
446 update_account_thread (gpointer thr_user_data)
448 UpdateAccountInfo *info;
449 TnyList *all_folders = NULL;
450 TnyIterator *iter = NULL;
451 TnyFolderStoreQuery *query = NULL;
452 ModestMailOperationPrivate *priv;
453 ModestTnySendQueue *send_queue;
456 info = (UpdateAccountInfo *) thr_user_data;
457 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
459 /* Get all the folders We can do it synchronously because
460 we're already running in a different thread than the UI */
461 all_folders = tny_simple_list_new ();
462 query = tny_folder_store_query_new ();
463 tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
464 tny_folder_store_get_folders (TNY_FOLDER_STORE (info->account),
469 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
473 iter = tny_list_create_iterator (all_folders);
474 while (!tny_iterator_is_done (iter)) {
475 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
477 recurse_folders (folder, query, all_folders);
478 tny_iterator_next (iter);
480 g_object_unref (G_OBJECT (iter));
482 /* Update status and notify. We need to call the notification
483 with a source functopm in order to call it from the main
484 loop. We need that in order not to get into trouble with
485 Gtk+. We use a timeout in order to provide more status
486 information, because the sync tinymail call does not
487 provide it for the moment */
488 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
490 /* Refresh folders */
491 iter = tny_list_create_iterator (all_folders);
492 while (!tny_iterator_is_done (iter) && !priv->error) {
494 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
496 /* Refresh the folder */
497 tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
499 /* TODO: Apply retrieval types */
501 /* TODO: apply per-message size limits */
503 /* TODO: apply message count limit */
506 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
509 g_object_unref (G_OBJECT (folder));
510 tny_iterator_next (iter);
512 g_object_unref (G_OBJECT (iter));
513 g_source_remove (timeout);
516 priv->id = MODEST_MAIL_OPERATION_ID_SEND;
518 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(info->transport_account));
520 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
521 modest_tny_send_queue_flush (send_queue);
522 g_source_remove (timeout);
524 g_object_unref (G_OBJECT(send_queue));
526 /* Check if the operation was a success */
528 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
530 /* Update the last updated key */
531 modest_account_mgr_set_int (modest_runtime_get_account_mgr (),
532 tny_account_get_id (TNY_ACCOUNT (info->account)),
533 MODEST_ACCOUNT_LAST_UPDATED,
539 /* Notify the queue. Note that the info could be freed before
540 this idle happens, but the mail operation will be still
542 g_idle_add (notify_update_account_queue, info->mail_op);
545 g_object_unref (query);
546 g_object_unref (all_folders);
547 g_object_unref (info->account);
548 g_object_unref (info->transport_account);
549 g_slice_free (UpdateAccountInfo, info);
555 modest_mail_operation_update_account (ModestMailOperation *self,
556 const gchar *account_name)
559 UpdateAccountInfo *info;
560 ModestMailOperationPrivate *priv;
561 TnyStoreAccount *modest_account;
562 TnyTransportAccount *transport_account;
564 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
565 g_return_val_if_fail (account_name, FALSE);
567 /* Init mail operation. Set total and done to 0, and do not
568 update them, this way the progress objects will know that
569 we have no clue about the number of the objects */
570 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
573 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
575 /* Get the Modest account */
576 modest_account = (TnyStoreAccount *)
577 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store (),
579 TNY_ACCOUNT_TYPE_STORE);
581 if (!modest_account) {
582 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
583 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
584 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
585 "cannot get tny store account for %s\n", account_name);
586 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
591 /* Get the transport account, we can not do it in the thread
592 due to some problems with dbus */
593 transport_account = (TnyTransportAccount *)
594 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
596 if (!transport_account) {
597 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
598 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
599 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
600 "cannot get tny transport account for %s\n", account_name);
601 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
606 /* Create the helper object */
607 info = g_slice_new (UpdateAccountInfo);
608 info->mail_op = self;
609 info->account = modest_account;
610 info->transport_account = transport_account;
612 thread = g_thread_create (update_account_thread, info, FALSE, NULL);
617 ModestMailOperationStatus
618 modest_mail_operation_get_status (ModestMailOperation *self)
620 ModestMailOperationPrivate *priv;
622 g_return_val_if_fail (self, MODEST_MAIL_OPERATION_STATUS_INVALID);
623 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self),
624 MODEST_MAIL_OPERATION_STATUS_INVALID);
626 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
631 modest_mail_operation_get_error (ModestMailOperation *self)
633 ModestMailOperationPrivate *priv;
635 g_return_val_if_fail (self, NULL);
636 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
638 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
643 modest_mail_operation_cancel (ModestMailOperation *self)
645 ModestMailOperationPrivate *priv;
647 if (!MODEST_IS_MAIL_OPERATION (self)) {
648 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
652 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
654 /* TODO: Tinymail does not support cancel operation */
657 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
659 /* Notify the queue */
660 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
666 modest_mail_operation_get_task_done (ModestMailOperation *self)
668 ModestMailOperationPrivate *priv;
670 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
672 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
677 modest_mail_operation_get_task_total (ModestMailOperation *self)
679 ModestMailOperationPrivate *priv;
681 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
683 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
688 modest_mail_operation_is_finished (ModestMailOperation *self)
690 ModestMailOperationPrivate *priv;
691 gboolean retval = FALSE;
693 if (!MODEST_IS_MAIL_OPERATION (self)) {
694 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
698 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
700 if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS ||
701 priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED ||
702 priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED ||
703 priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) {
712 /* ******************************************************************* */
713 /* ************************** STORE ACTIONS ************************* */
714 /* ******************************************************************* */
718 modest_mail_operation_create_folder (ModestMailOperation *self,
719 TnyFolderStore *parent,
722 ModestTnyFolderRules rules;
723 ModestMailOperationPrivate *priv;
724 TnyFolder *new_folder = NULL;
725 gboolean can_create = FALSE;
727 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
728 g_return_val_if_fail (name, NULL);
730 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
733 if (!TNY_IS_FOLDER (parent)) {
734 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
735 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
736 _("mail_in_ui_folder_create_error"));
738 /* Check folder rules */
739 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
740 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)
741 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
742 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
743 _("mail_in_ui_folder_create_error"));
749 /* Create the folder */
750 new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
751 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
754 /* Notify the queue */
755 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
761 modest_mail_operation_remove_folder (ModestMailOperation *self,
763 gboolean remove_to_trash)
766 ModestMailOperationPrivate *priv;
767 ModestTnyFolderRules rules;
769 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
770 g_return_if_fail (TNY_IS_FOLDER (folder));
772 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
774 /* Check folder rules */
775 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
776 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE) {
777 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
778 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
779 _("mail_in_ui_folder_delete_error"));
783 /* Get the account */
784 account = tny_folder_get_account (folder);
786 /* Delete folder or move to trash */
787 if (remove_to_trash) {
788 TnyFolder *trash_folder = NULL;
789 /* TnyFolder *trash_folder, *new_folder; */
790 trash_folder = modest_tny_account_get_special_folder (account,
791 TNY_FOLDER_TYPE_TRASH);
792 /* TODO: error_handling */
793 modest_mail_operation_xfer_folder (self, folder,
794 TNY_FOLDER_STORE (trash_folder), TRUE);
795 /* new_folder = modest_mail_operation_xfer_folder (self, folder, */
796 /* TNY_FOLDER_STORE (trash_folder), TRUE); */
797 /* g_object_unref (G_OBJECT (new_folder)); */
799 TnyFolderStore *parent = tny_folder_get_folder_store (folder);
801 tny_folder_store_remove_folder (parent, folder, &(priv->error));
802 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
805 g_object_unref (G_OBJECT (parent));
807 g_object_unref (G_OBJECT (account));
810 /* Notify the queue */
811 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
815 modest_mail_operation_rename_folder (ModestMailOperation *self,
819 ModestMailOperationPrivate *priv;
820 ModestTnyFolderRules rules;
822 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
823 g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
824 g_return_if_fail (name);
826 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
828 /* Check folder rules */
829 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
830 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
831 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
832 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
833 _("FIXME: unable to rename"));
835 /* Rename. Camel handles folder subscription/unsubscription */
837 TnyFolderStore *into;
840 into = tny_folder_get_folder_store (folder);
841 nfol = tny_folder_copy (folder, into, name, TRUE, &(priv->error));
843 g_object_unref (into);
845 g_object_unref (nfol);
847 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
850 /* Notify the queue */
851 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
855 transfer_folder_status_cb (GObject *obj,
859 XFerMsgAsyncHelper *helper = NULL;
860 ModestMailOperation *self;
861 ModestMailOperationPrivate *priv;
863 g_return_if_fail (status != NULL);
864 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER);
866 helper = (XFerMsgAsyncHelper *) user_data;
867 g_return_if_fail (helper != NULL);
869 /* Temporary FIX: useful when tinymail send us status
870 information *after* calling the function callback */
871 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
874 self = helper->mail_op;
875 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
877 if ((status->position == 1) && (status->of_total == 100))
880 priv->done = status->position;
881 priv->total = status->of_total;
884 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
889 transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, GError **err, gpointer user_data)
891 XFerFolderAsyncHelper *helper = NULL;
892 ModestMailOperation *self = NULL;
893 ModestMailOperationPrivate *priv = NULL;
895 helper = (XFerFolderAsyncHelper *) user_data;
896 self = helper->mail_op;
898 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
901 priv->error = g_error_copy (*err);
903 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
904 } else if (cancelled) {
905 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
906 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
907 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
908 _("Error trying to refresh the contents of %s"),
909 tny_folder_get_name (folder));
912 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
916 g_slice_free (XFerFolderAsyncHelper, helper);
917 g_object_unref (folder);
918 g_object_unref (into);
919 g_object_unref (new_folder);
921 /* Notify the queue */
922 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
926 modest_mail_operation_xfer_folder (ModestMailOperation *self,
928 TnyFolderStore *parent,
929 gboolean delete_original)
931 ModestMailOperationPrivate *priv;
932 TnyFolder *new_folder = NULL;
933 ModestTnyFolderRules rules;
935 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
936 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
937 g_return_val_if_fail (TNY_IS_FOLDER (folder), NULL);
939 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
941 /* The moveable restriction is applied also to copy operation */
942 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
943 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
944 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
945 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
946 _("FIXME: unable to rename"));
948 /* Move/Copy folder */
949 new_folder = tny_folder_copy (folder,
951 tny_folder_get_name (folder),
956 /* Notify the queue */
957 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
963 modest_mail_operation_xfer_folder_async (ModestMailOperation *self,
965 TnyFolderStore *parent,
966 gboolean delete_original)
968 XFerFolderAsyncHelper *helper = NULL;
969 ModestMailOperationPrivate *priv = NULL;
970 ModestTnyFolderRules rules;
972 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
973 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
974 g_return_if_fail (TNY_IS_FOLDER (folder));
976 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
978 /* Pick references for async calls */
979 g_object_ref (folder);
980 g_object_ref (parent);
982 /* The moveable restriction is applied also to copy operation */
983 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
984 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
985 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
986 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
987 _("FIXME: unable to rename"));
989 helper = g_slice_new0 (XFerFolderAsyncHelper);
990 helper->mail_op = self;
992 /* Move/Copy folder */
993 tny_folder_copy_async (folder,
995 tny_folder_get_name (folder),
998 transfer_folder_status_cb,
1004 /* ******************************************************************* */
1005 /* ************************** MSG ACTIONS ************************* */
1006 /* ******************************************************************* */
1008 void modest_mail_operation_get_msg (ModestMailOperation *self,
1010 GetMsgAsynUserCallback user_callback,
1013 GetMsgAsyncHelper *helper = NULL;
1015 ModestMailOperationPrivate *priv;
1017 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1018 g_return_if_fail (TNY_IS_HEADER (header));
1020 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1021 folder = tny_header_get_folder (header);
1023 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1025 /* Get message from folder */
1027 helper = g_slice_new0 (GetMsgAsyncHelper);
1028 helper->mail_op = self;
1029 helper->user_callback = user_callback;
1030 helper->pending_ops = 1;
1031 helper->user_data = user_data;
1033 tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper);
1035 g_object_unref (G_OBJECT (folder));
1037 /* Set status failed and set an error */
1038 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1039 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1040 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1041 _("Error trying to get a message. No folder found for header"));
1046 get_msg_cb (TnyFolder *folder,
1052 GetMsgAsyncHelper *helper = NULL;
1053 ModestMailOperation *self = NULL;
1054 ModestMailOperationPrivate *priv = NULL;
1056 helper = (GetMsgAsyncHelper *) user_data;
1057 g_return_if_fail (helper != NULL);
1058 self = helper->mail_op;
1059 g_return_if_fail (MODEST_IS_MAIL_OPERATION(self));
1060 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1062 helper->pending_ops--;
1064 /* Check errors and cancel */
1066 priv->error = g_error_copy (*error);
1067 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1071 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1072 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1073 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1074 _("Error trying to refresh the contents of %s"),
1075 tny_folder_get_name (folder));
1079 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1081 /* If user defined callback function was defined, call it */
1082 if (helper->user_callback) {
1083 helper->user_callback (priv->source, msg, helper->user_data);
1088 if (helper->pending_ops == 0) {
1089 g_slice_free (GetMsgAsyncHelper, helper);
1091 /* Notify the queue */
1092 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1097 get_msg_status_cb (GObject *obj,
1101 GetMsgAsyncHelper *helper = NULL;
1102 ModestMailOperation *self;
1103 ModestMailOperationPrivate *priv;
1105 g_return_if_fail (status != NULL);
1106 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG);
1108 helper = (GetMsgAsyncHelper *) user_data;
1109 g_return_if_fail (helper != NULL);
1111 /* Temporary FIX: useful when tinymail send us status
1112 information *after* calling the function callback */
1113 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1116 self = helper->mail_op;
1117 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1119 if ((status->position == 1) && (status->of_total == 100))
1125 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1128 /****************************************************/
1130 ModestMailOperation *mail_op;
1132 GetMsgAsynUserCallback user_callback;
1134 GDestroyNotify notify;
1138 * Used by get_msgs_full_thread to emit the "progress-changed" signal
1139 * from the main loop. We call it inside an idle call to achieve that
1142 notify_get_msgs_full_observers (gpointer data)
1144 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
1146 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1148 g_object_unref (mail_op);
1154 GetMsgAsynUserCallback user_callback;
1158 } NotifyGetMsgsInfo;
1162 * Used by get_msgs_full_thread to call the user_callback for each
1163 * message that has been read
1166 notify_get_msgs_full (gpointer data)
1168 NotifyGetMsgsInfo *info;
1170 info = (NotifyGetMsgsInfo *) data;
1172 /* Call the user callback */
1173 info->user_callback (info->source, info->msg, info->user_data);
1175 g_slice_free (NotifyGetMsgsInfo, info);
1181 * Used by get_msgs_full_thread to free al the thread resources and to
1182 * call the destroy function for the passed user_data
1185 get_msgs_full_destroyer (gpointer data)
1187 GetFullMsgsInfo *info;
1189 info = (GetFullMsgsInfo *) data;
1192 info->notify (info->user_data);
1195 g_object_unref (info->headers);
1196 g_slice_free (GetFullMsgsInfo, info);
1202 get_msgs_full_thread (gpointer thr_user_data)
1204 GetFullMsgsInfo *info;
1205 ModestMailOperationPrivate *priv = NULL;
1206 TnyIterator *iter = NULL;
1208 info = (GetFullMsgsInfo *) thr_user_data;
1209 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
1211 iter = tny_list_create_iterator (info->headers);
1212 while (!tny_iterator_is_done (iter)) {
1216 header = TNY_HEADER (tny_iterator_get_current (iter));
1217 folder = tny_header_get_folder (header);
1219 /* Get message from folder */
1222 /* The callback will call it per each header */
1223 msg = tny_folder_get_msg (folder, header, &(priv->error));
1228 /* notify progress */
1229 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1230 notify_get_msgs_full_observers,
1231 g_object_ref (info->mail_op), NULL);
1233 /* The callback is the responsible for
1234 freeing the message */
1235 if (info->user_callback) {
1236 NotifyGetMsgsInfo *info_notify;
1237 info_notify = g_slice_new0 (NotifyGetMsgsInfo);
1238 info_notify->user_callback = info->user_callback;
1239 info_notify->source = priv->source;
1240 info_notify->msg = msg;
1241 info_notify->user_data = info->user_data;
1242 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1243 notify_get_msgs_full,
1246 g_object_unref (msg);
1250 /* Set status failed and set an error */
1251 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1252 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1253 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1254 "Error trying to get a message. No folder found for header");
1256 g_object_unref (header);
1257 tny_iterator_next (iter);
1260 /* Notify the queue */
1261 g_idle_add (notify_update_account_queue, info->mail_op);
1263 /* Free thread resources. Will be called after all previous idles */
1264 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
1270 modest_mail_operation_get_msgs_full (ModestMailOperation *self,
1271 TnyList *header_list,
1272 GetMsgAsynUserCallback user_callback,
1274 GDestroyNotify notify)
1277 ModestMailOperationPrivate *priv = NULL;
1278 GetFullMsgsInfo *info = NULL;
1279 gboolean size_ok = TRUE;
1281 GError *error = NULL;
1282 const gint KB = 1024;
1284 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1286 /* Init mail operation */
1287 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1288 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1290 priv->total = tny_list_get_length(header_list);
1292 /* Get msg size limit */
1293 max_size = modest_conf_get_int (modest_runtime_get_conf (),
1294 MODEST_CONF_MSG_SIZE_LIMIT,
1297 g_clear_error (&error);
1298 max_size = G_MAXINT;
1300 max_size = max_size * KB;
1303 /* Check message size limits. If there is only one message
1304 always retrieve it */
1305 if (tny_list_get_length (header_list) > 1) {
1308 iter = tny_list_create_iterator (header_list);
1309 while (!tny_iterator_is_done (iter) && size_ok) {
1310 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1311 if (tny_header_get_message_size (header) >= max_size)
1313 g_object_unref (header);
1314 tny_iterator_next (iter);
1316 g_object_unref (iter);
1320 /* Create the info */
1321 info = g_slice_new0 (GetFullMsgsInfo);
1322 info->mail_op = self;
1323 info->user_callback = user_callback;
1324 info->user_data = user_data;
1325 info->headers = g_object_ref (header_list);
1326 info->notify = notify;
1328 thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL);
1330 /* FIXME: the error msg is different for pop */
1331 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1332 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
1333 _("emev_ni_ui_imap_msg_sizelimit_error"));
1334 /* Remove from queue and free resources */
1335 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1343 modest_mail_operation_remove_msg (ModestMailOperation *self,
1345 gboolean remove_to_trash)
1348 ModestMailOperationPrivate *priv;
1350 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1351 g_return_if_fail (TNY_IS_HEADER (header));
1353 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1354 folder = tny_header_get_folder (header);
1356 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1358 /* Delete or move to trash */
1359 if (remove_to_trash) {
1360 TnyFolder *trash_folder;
1361 TnyStoreAccount *store_account;
1363 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
1364 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
1365 TNY_FOLDER_TYPE_TRASH);
1370 headers = tny_simple_list_new ();
1371 tny_list_append (headers, G_OBJECT (header));
1372 g_object_unref (header);
1375 modest_mail_operation_xfer_msgs (self, headers, trash_folder, TRUE, NULL, NULL);
1376 g_object_unref (headers);
1377 /* g_object_unref (trash_folder); */
1379 ModestMailOperationPrivate *priv;
1381 /* Set status failed and set an error */
1382 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1383 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1384 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1385 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1386 _("Error trying to delete a message. Trash folder not found"));
1389 g_object_unref (G_OBJECT (store_account));
1391 tny_folder_remove_msg (folder, header, &(priv->error));
1393 tny_folder_sync(folder, TRUE, &(priv->error));
1398 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1400 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1403 g_object_unref (G_OBJECT (folder));
1405 /* Notify the queue */
1406 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1410 transfer_msgs_status_cb (GObject *obj,
1414 XFerMsgAsyncHelper *helper = NULL;
1415 ModestMailOperation *self;
1416 ModestMailOperationPrivate *priv;
1418 g_return_if_fail (status != NULL);
1419 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS);
1421 helper = (XFerMsgAsyncHelper *) user_data;
1422 g_return_if_fail (helper != NULL);
1424 /* Temporary FIX: useful when tinymail send us status
1425 information *after* calling the function callback */
1426 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1429 self = helper->mail_op;
1430 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1432 if ((status->position == 1) && (status->of_total == 100))
1435 priv->done = status->position;
1436 priv->total = status->of_total;
1438 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1443 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data)
1445 XFerMsgAsyncHelper *helper;
1446 ModestMailOperation *self;
1447 ModestMailOperationPrivate *priv;
1449 helper = (XFerMsgAsyncHelper *) user_data;
1450 self = helper->mail_op;
1452 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1455 priv->error = g_error_copy (*err);
1457 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1458 } else if (cancelled) {
1459 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1460 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1461 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1462 _("Error trying to refresh the contents of %s"),
1463 tny_folder_get_name (folder));
1466 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1469 /* If user defined callback function was defined, call it */
1470 if (helper->user_callback) {
1471 helper->user_callback (priv->source, helper->user_data);
1475 g_object_unref (helper->headers);
1476 g_object_unref (helper->dest_folder);
1477 g_object_unref (helper->mail_op);
1478 g_slice_free (XFerMsgAsyncHelper, helper);
1479 g_object_unref (folder);
1481 /* Notify the queue */
1482 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1486 modest_mail_operation_xfer_msgs (ModestMailOperation *self,
1489 gboolean delete_original,
1490 XferMsgsAsynUserCallback user_callback,
1493 ModestMailOperationPrivate *priv;
1495 TnyFolder *src_folder;
1496 XFerMsgAsyncHelper *helper;
1499 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1500 g_return_if_fail (TNY_IS_LIST (headers));
1501 g_return_if_fail (TNY_IS_FOLDER (folder));
1503 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1506 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1508 /* Create the helper */
1509 helper = g_slice_new0 (XFerMsgAsyncHelper);
1510 helper->mail_op = g_object_ref(self);
1511 helper->dest_folder = g_object_ref(folder);
1512 helper->headers = g_object_ref(headers);
1513 helper->user_callback = user_callback;
1514 helper->user_data = user_data;
1516 /* Get source folder */
1517 iter = tny_list_create_iterator (headers);
1518 header = TNY_HEADER (tny_iterator_get_current (iter));
1519 src_folder = tny_header_get_folder (header);
1520 g_object_unref (header);
1521 g_object_unref (iter);
1523 /* Transfer messages */
1524 tny_folder_transfer_msgs_async (src_folder,
1529 transfer_msgs_status_cb,
1535 on_refresh_folder (TnyFolder *folder,
1540 ModestMailOperation *self;
1541 ModestMailOperationPrivate *priv;
1543 self = MODEST_MAIL_OPERATION (user_data);
1544 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1547 priv->error = g_error_copy (*error);
1548 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1553 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1554 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1555 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1556 _("Error trying to refresh the contents of %s"),
1557 tny_folder_get_name (folder));
1561 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1565 g_object_unref (folder);
1567 /* Notify the queue */
1568 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1572 on_refresh_folder_status_update (GObject *obj,
1576 ModestMailOperation *self;
1577 ModestMailOperationPrivate *priv;
1579 g_return_if_fail (status != NULL);
1580 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH);
1582 /* Temporary FIX: useful when tinymail send us status
1583 information *after* calling the function callback */
1584 if (!MODEST_IS_MAIL_OPERATION (user_data))
1587 self = MODEST_MAIL_OPERATION (user_data);
1588 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1590 priv->done = status->position;
1591 priv->total = status->of_total;
1593 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1597 modest_mail_operation_refresh_folder (ModestMailOperation *self,
1600 ModestMailOperationPrivate *priv;
1602 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1604 /* Pick a reference */
1605 g_object_ref (folder);
1607 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1609 /* Refresh the folder. TODO: tinymail could issue a status
1610 updates before the callback call then this could happen. We
1611 must review the design */
1612 tny_folder_refresh_async (folder,
1614 on_refresh_folder_status_update,
1619 _modest_mail_operation_notify_end (ModestMailOperation *self)
1621 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);