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,
74 enum _ModestMailOperationSignals
76 PROGRESS_CHANGED_SIGNAL,
81 typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate;
82 struct _ModestMailOperationPrivate {
85 ModestMailOperationStatus status;
86 ModestMailOperationId id;
88 ErrorCheckingUserCallback error_checking;
92 #define MODEST_MAIL_OPERATION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
93 MODEST_TYPE_MAIL_OPERATION, \
94 ModestMailOperationPrivate))
96 #define CHECK_EXCEPTION(priv, new_status) if (priv->error) {\
97 priv->status = new_status;\
100 typedef struct _GetMsgAsyncHelper {
101 ModestMailOperation *mail_op;
102 GetMsgAsynUserCallback user_callback;
107 typedef struct _XFerMsgAsyncHelper
109 ModestMailOperation *mail_op;
111 TnyFolder *dest_folder;
112 XferMsgsAsynUserCallback user_callback;
114 } XFerMsgAsyncHelper;
116 typedef struct _XFerFolderAsyncHelper
118 ModestMailOperation *mail_op;
120 } XFerFolderAsyncHelper;
123 static GObjectClass *parent_class = NULL;
125 static guint signals[NUM_SIGNALS] = {0};
128 modest_mail_operation_get_type (void)
130 static GType my_type = 0;
132 static const GTypeInfo my_info = {
133 sizeof(ModestMailOperationClass),
134 NULL, /* base init */
135 NULL, /* base finalize */
136 (GClassInitFunc) modest_mail_operation_class_init,
137 NULL, /* class finalize */
138 NULL, /* class data */
139 sizeof(ModestMailOperation),
141 (GInstanceInitFunc) modest_mail_operation_init,
144 my_type = g_type_register_static (G_TYPE_OBJECT,
145 "ModestMailOperation",
152 modest_mail_operation_class_init (ModestMailOperationClass *klass)
154 GObjectClass *gobject_class;
155 gobject_class = (GObjectClass*) klass;
157 parent_class = g_type_class_peek_parent (klass);
158 gobject_class->finalize = modest_mail_operation_finalize;
160 g_type_class_add_private (gobject_class, sizeof(ModestMailOperationPrivate));
163 * ModestMailOperation::progress-changed
164 * @self: the #MailOperation that emits the signal
165 * @user_data: user data set when the signal handler was connected
167 * Emitted when the progress of a mail operation changes
169 signals[PROGRESS_CHANGED_SIGNAL] =
170 g_signal_new ("progress-changed",
171 G_TYPE_FROM_CLASS (gobject_class),
173 G_STRUCT_OFFSET (ModestMailOperationClass, progress_changed),
175 g_cclosure_marshal_VOID__VOID,
180 modest_mail_operation_init (ModestMailOperation *obj)
182 ModestMailOperationPrivate *priv;
184 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
186 priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID;
187 priv->id = MODEST_MAIL_OPERATION_ID_UNKNOWN;
195 modest_mail_operation_finalize (GObject *obj)
197 ModestMailOperationPrivate *priv;
199 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
202 g_error_free (priv->error);
206 g_object_unref (priv->source);
210 G_OBJECT_CLASS(parent_class)->finalize (obj);
214 modest_mail_operation_new (ModestMailOperationId id,
217 ModestMailOperation *obj;
218 ModestMailOperationPrivate *priv;
220 obj = MODEST_MAIL_OPERATION(g_object_new(MODEST_TYPE_MAIL_OPERATION, NULL));
221 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
225 priv->source = g_object_ref(source);
231 modest_mail_operation_new_with_error_handling (ModestMailOperationId id,
233 ErrorCheckingUserCallback error_handler)
235 ModestMailOperation *obj;
236 ModestMailOperationPrivate *priv;
238 obj = modest_mail_operation_new (id, source);
239 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
241 g_return_val_if_fail (error_handler != NULL, obj);
242 priv->error_checking = error_handler;
248 modest_mail_operation_execute_error_handler (ModestMailOperation *self)
250 ModestMailOperationPrivate *priv;
252 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
253 g_return_if_fail(priv->status != MODEST_MAIL_OPERATION_STATUS_SUCCESS);
255 if (priv->error_checking == NULL) return;
256 priv->error_checking (priv->source, self);
260 ModestMailOperationId
261 modest_mail_operation_get_id (ModestMailOperation *self)
263 ModestMailOperationPrivate *priv;
265 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
271 modest_mail_operation_is_mine (ModestMailOperation *self,
274 ModestMailOperationPrivate *priv;
276 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
277 if (priv->source == NULL) return FALSE;
279 return priv->source == me;
284 modest_mail_operation_send_mail (ModestMailOperation *self,
285 TnyTransportAccount *transport_account,
288 TnySendQueue *send_queue;
290 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
291 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
292 g_return_if_fail (TNY_IS_MSG (msg));
294 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
295 if (!TNY_IS_SEND_QUEUE(send_queue))
296 g_printerr ("modest: could not find send queue for account\n");
299 tny_send_queue_add (send_queue, msg, &err);
301 g_printerr ("modest: error adding msg to send queue: %s\n",
305 /* g_message ("modest: message added to send queue"); */
309 /* Notify the queue */
310 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
314 modest_mail_operation_send_new_mail (ModestMailOperation *self,
315 TnyTransportAccount *transport_account,
316 const gchar *from, const gchar *to,
317 const gchar *cc, const gchar *bcc,
318 const gchar *subject, const gchar *plain_body,
319 const gchar *html_body,
320 const GList *attachments_list,
321 TnyHeaderFlags priority_flags)
324 ModestMailOperationPrivate *priv = NULL;
325 /* GList *node = NULL; */
327 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
328 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
330 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
332 /* Check parametters */
334 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
335 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
336 _("Error trying to send a mail. You need to set at least one recipient"));
340 if (html_body == NULL) {
341 new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
343 new_msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
346 g_printerr ("modest: failed to create a new msg\n");
350 /* TODO: add priority handling. It's received in the priority_flags operator, and
351 it should have effect in the sending operation */
353 /* Call mail operation */
354 modest_mail_operation_send_mail (self, transport_account, new_msg);
357 g_object_unref (G_OBJECT (new_msg));
361 modest_mail_operation_save_to_drafts (ModestMailOperation *self,
362 TnyTransportAccount *transport_account,
363 const gchar *from, const gchar *to,
364 const gchar *cc, const gchar *bcc,
365 const gchar *subject, const gchar *plain_body,
366 const gchar *html_body,
367 const GList *attachments_list,
368 TnyHeaderFlags priority_flags)
371 TnyFolder *folder = NULL;
372 ModestMailOperationPrivate *priv = NULL;
375 /* GList *node = NULL; */
377 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
378 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
380 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
382 if (html_body == NULL) {
383 msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
385 msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
388 g_printerr ("modest: failed to create a new msg\n");
392 folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
394 g_printerr ("modest: failed to find Drafts folder\n");
398 tny_folder_add_msg (folder, msg, &err);
400 g_printerr ("modest: error adding msg to Drafts folder: %s",
406 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
411 g_object_unref (G_OBJECT(msg));
413 g_object_unref (G_OBJECT(folder));
418 ModestMailOperation *mail_op;
419 TnyStoreAccount *account;
420 TnyTransportAccount *transport_account;
424 recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
427 TnyList *folders = tny_simple_list_new ();
429 tny_folder_store_get_folders (store, folders, query, NULL);
430 iter = tny_list_create_iterator (folders);
432 while (!tny_iterator_is_done (iter)) {
434 TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
436 tny_list_prepend (all_folders, G_OBJECT (folder));
437 recurse_folders (folder, query, all_folders);
438 g_object_unref (G_OBJECT (folder));
440 tny_iterator_next (iter);
442 g_object_unref (G_OBJECT (iter));
443 g_object_unref (G_OBJECT (folders));
447 * Used by update_account_thread to emit the "progress-changed" signal
448 * from the main loop. We call it inside an idle call to achieve that
451 notify_update_account_observers (gpointer data)
453 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
455 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
461 * Used by update_account_thread to notify the queue from the main
462 * loop. We call it inside an idle call to achieve that
465 notify_update_account_queue (gpointer data)
467 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
469 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
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 the queue. Note that the info could be freed before
571 this idle happens, but the mail operation will be still
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_queue_remove (modest_runtime_get_mail_operation_queue (),
622 /* Get the transport account, we can not do it in the thread
623 due to some problems with dbus */
624 transport_account = (TnyTransportAccount *)
625 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
627 if (!transport_account) {
628 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
629 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
630 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
631 "cannot get tny transport account for %s\n", account_name);
632 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
637 /* Create the helper object */
638 info = g_slice_new (UpdateAccountInfo);
639 info->mail_op = self;
640 info->account = modest_account;
641 info->transport_account = transport_account;
643 thread = g_thread_create (update_account_thread, info, FALSE, NULL);
648 ModestMailOperationStatus
649 modest_mail_operation_get_status (ModestMailOperation *self)
651 ModestMailOperationPrivate *priv;
653 g_return_val_if_fail (self, MODEST_MAIL_OPERATION_STATUS_INVALID);
654 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self),
655 MODEST_MAIL_OPERATION_STATUS_INVALID);
657 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
662 modest_mail_operation_get_error (ModestMailOperation *self)
664 ModestMailOperationPrivate *priv;
666 g_return_val_if_fail (self, NULL);
667 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
669 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
674 modest_mail_operation_cancel (ModestMailOperation *self)
676 ModestMailOperationPrivate *priv;
678 if (!MODEST_IS_MAIL_OPERATION (self)) {
679 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
683 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
685 /* TODO: Tinymail does not support cancel operation */
686 /* tny_account_cancel (); */
689 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
691 /* Notify the queue */
692 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
698 modest_mail_operation_get_task_done (ModestMailOperation *self)
700 ModestMailOperationPrivate *priv;
702 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
704 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
709 modest_mail_operation_get_task_total (ModestMailOperation *self)
711 ModestMailOperationPrivate *priv;
713 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
715 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
720 modest_mail_operation_is_finished (ModestMailOperation *self)
722 ModestMailOperationPrivate *priv;
723 gboolean retval = FALSE;
725 if (!MODEST_IS_MAIL_OPERATION (self)) {
726 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
730 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
732 if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS ||
733 priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED ||
734 priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED ||
735 priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) {
744 /* ******************************************************************* */
745 /* ************************** STORE ACTIONS ************************* */
746 /* ******************************************************************* */
750 modest_mail_operation_create_folder (ModestMailOperation *self,
751 TnyFolderStore *parent,
754 ModestTnyFolderRules rules;
755 ModestMailOperationPrivate *priv;
756 TnyFolder *new_folder = NULL;
757 gboolean can_create = FALSE;
759 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
760 g_return_val_if_fail (name, NULL);
762 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
765 if (!TNY_IS_FOLDER (parent)) {
766 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
767 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
768 _("mail_in_ui_folder_create_error"));
770 /* Check folder rules */
771 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
772 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)
773 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
774 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
775 _("mail_in_ui_folder_create_error"));
781 /* Create the folder */
782 new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
783 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
786 /* Notify the queue */
787 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
793 modest_mail_operation_remove_folder (ModestMailOperation *self,
795 gboolean remove_to_trash)
798 ModestMailOperationPrivate *priv;
799 ModestTnyFolderRules rules;
801 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
802 g_return_if_fail (TNY_IS_FOLDER (folder));
804 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
806 /* Check folder rules */
807 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
808 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE) {
809 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
810 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
811 _("mail_in_ui_folder_delete_error"));
815 /* Get the account */
816 account = tny_folder_get_account (folder);
818 /* Delete folder or move to trash */
819 if (remove_to_trash) {
820 TnyFolder *trash_folder = NULL;
821 /* TnyFolder *trash_folder, *new_folder; */
822 trash_folder = modest_tny_account_get_special_folder (account,
823 TNY_FOLDER_TYPE_TRASH);
824 /* TODO: error_handling */
825 modest_mail_operation_xfer_folder (self, folder,
826 TNY_FOLDER_STORE (trash_folder), TRUE);
827 /* new_folder = modest_mail_operation_xfer_folder (self, folder, */
828 /* TNY_FOLDER_STORE (trash_folder), TRUE); */
829 /* g_object_unref (G_OBJECT (new_folder)); */
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 the queue */
843 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), 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 the queue */
883 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), 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 /* Temporary FIX: useful when tinymail send us status
902 information *after* calling the function callback */
903 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
906 self = helper->mail_op;
907 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
909 if ((status->position == 1) && (status->of_total == 100))
912 priv->done = status->position;
913 priv->total = status->of_total;
916 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
921 transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, GError **err, gpointer user_data)
923 XFerFolderAsyncHelper *helper = NULL;
924 ModestMailOperation *self = NULL;
925 ModestMailOperationPrivate *priv = NULL;
927 helper = (XFerFolderAsyncHelper *) user_data;
928 self = helper->mail_op;
930 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
933 priv->error = g_error_copy (*err);
935 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
936 } else if (cancelled) {
937 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
938 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
939 MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
940 _("Transference of %s was cancelled."),
941 tny_folder_get_name (folder));
944 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
948 g_slice_free (XFerFolderAsyncHelper, helper);
949 g_object_unref (folder);
950 g_object_unref (into);
951 if (new_folder != NULL)
952 g_object_unref (new_folder);
954 /* Notify the queue */
955 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
959 modest_mail_operation_xfer_folder (ModestMailOperation *self,
961 TnyFolderStore *parent,
962 gboolean delete_original)
964 ModestMailOperationPrivate *priv;
965 TnyFolder *new_folder = NULL;
966 ModestTnyFolderRules rules;
968 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
969 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
970 g_return_val_if_fail (TNY_IS_FOLDER (folder), NULL);
972 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
974 /* The moveable restriction is applied also to copy operation */
975 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
976 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
977 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
978 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
979 _("FIXME: unable to rename"));
981 /* Move/Copy folder */
982 new_folder = tny_folder_copy (folder,
984 tny_folder_get_name (folder),
989 /* Notify the queue */
990 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
996 modest_mail_operation_xfer_folder_async (ModestMailOperation *self,
998 TnyFolderStore *parent,
999 gboolean delete_original)
1001 XFerFolderAsyncHelper *helper = NULL;
1002 ModestMailOperationPrivate *priv = NULL;
1003 ModestTnyFolderRules rules;
1005 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1006 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
1007 g_return_if_fail (TNY_IS_FOLDER (folder));
1009 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1011 /* Pick references for async calls */
1012 g_object_ref (folder);
1013 g_object_ref (parent);
1015 /* The moveable restriction is applied also to copy operation */
1016 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
1017 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
1018 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1019 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1020 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
1021 _("FIXME: unable to rename"));
1023 /* Notify the queue */
1024 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1026 helper = g_slice_new0 (XFerFolderAsyncHelper);
1027 helper->mail_op = self;
1029 /* Move/Copy folder */
1030 tny_folder_copy_async (folder,
1032 tny_folder_get_name (folder),
1035 transfer_folder_status_cb,
1041 /* ******************************************************************* */
1042 /* ************************** MSG ACTIONS ************************* */
1043 /* ******************************************************************* */
1045 void modest_mail_operation_get_msg (ModestMailOperation *self,
1047 GetMsgAsynUserCallback user_callback,
1050 GetMsgAsyncHelper *helper = NULL;
1052 ModestMailOperationPrivate *priv;
1054 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1055 g_return_if_fail (TNY_IS_HEADER (header));
1057 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1058 folder = tny_header_get_folder (header);
1060 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1062 /* Get message from folder */
1064 helper = g_slice_new0 (GetMsgAsyncHelper);
1065 helper->mail_op = self;
1066 helper->user_callback = user_callback;
1067 helper->pending_ops = 1;
1068 helper->user_data = user_data;
1070 tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper);
1072 g_object_unref (G_OBJECT (folder));
1074 /* Set status failed and set an error */
1075 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1076 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1077 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1078 _("Error trying to get a message. No folder found for header"));
1083 get_msg_cb (TnyFolder *folder,
1089 GetMsgAsyncHelper *helper = NULL;
1090 ModestMailOperation *self = NULL;
1091 ModestMailOperationPrivate *priv = NULL;
1093 helper = (GetMsgAsyncHelper *) user_data;
1094 g_return_if_fail (helper != NULL);
1095 self = helper->mail_op;
1096 g_return_if_fail (MODEST_IS_MAIL_OPERATION(self));
1097 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1099 helper->pending_ops--;
1101 /* Check errors and cancel */
1103 priv->error = g_error_copy (*error);
1104 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1108 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1109 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1110 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1111 _("Error trying to refresh the contents of %s"),
1112 tny_folder_get_name (folder));
1116 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1118 /* If user defined callback function was defined, call it */
1119 if (helper->user_callback) {
1120 helper->user_callback (priv->source, msg, helper->user_data);
1125 if (helper->pending_ops == 0) {
1126 g_slice_free (GetMsgAsyncHelper, helper);
1128 /* Notify the queue */
1129 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1134 get_msg_status_cb (GObject *obj,
1138 GetMsgAsyncHelper *helper = NULL;
1139 ModestMailOperation *self;
1140 ModestMailOperationPrivate *priv;
1142 g_return_if_fail (status != NULL);
1143 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG);
1145 helper = (GetMsgAsyncHelper *) user_data;
1146 g_return_if_fail (helper != NULL);
1148 /* Temporary FIX: useful when tinymail send us status
1149 information *after* calling the function callback */
1150 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1153 self = helper->mail_op;
1154 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1156 if ((status->position == 1) && (status->of_total == 100))
1162 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1165 /****************************************************/
1167 ModestMailOperation *mail_op;
1169 GetMsgAsynUserCallback user_callback;
1171 GDestroyNotify notify;
1175 * Used by get_msgs_full_thread to emit the "progress-changed" signal
1176 * from the main loop. We call it inside an idle call to achieve that
1179 notify_get_msgs_full_observers (gpointer data)
1181 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
1183 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1185 g_object_unref (mail_op);
1191 GetMsgAsynUserCallback user_callback;
1195 } NotifyGetMsgsInfo;
1199 * Used by get_msgs_full_thread to call the user_callback for each
1200 * message that has been read
1203 notify_get_msgs_full (gpointer data)
1205 NotifyGetMsgsInfo *info;
1207 info = (NotifyGetMsgsInfo *) data;
1209 /* Call the user callback */
1210 info->user_callback (info->source, info->msg, info->user_data);
1212 g_slice_free (NotifyGetMsgsInfo, info);
1218 * Used by get_msgs_full_thread to free al the thread resources and to
1219 * call the destroy function for the passed user_data
1222 get_msgs_full_destroyer (gpointer data)
1224 GetFullMsgsInfo *info;
1226 info = (GetFullMsgsInfo *) data;
1229 info->notify (info->user_data);
1232 g_object_unref (info->headers);
1233 g_slice_free (GetFullMsgsInfo, info);
1239 get_msgs_full_thread (gpointer thr_user_data)
1241 GetFullMsgsInfo *info;
1242 ModestMailOperationPrivate *priv = NULL;
1243 TnyIterator *iter = NULL;
1245 info = (GetFullMsgsInfo *) thr_user_data;
1246 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
1248 iter = tny_list_create_iterator (info->headers);
1249 while (!tny_iterator_is_done (iter)) {
1253 header = TNY_HEADER (tny_iterator_get_current (iter));
1254 folder = tny_header_get_folder (header);
1256 /* Get message from folder */
1259 /* The callback will call it per each header */
1260 msg = tny_folder_get_msg (folder, header, &(priv->error));
1265 /* notify progress */
1266 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1267 notify_get_msgs_full_observers,
1268 g_object_ref (info->mail_op), NULL);
1270 /* The callback is the responsible for
1271 freeing the message */
1272 if (info->user_callback) {
1273 NotifyGetMsgsInfo *info_notify;
1274 info_notify = g_slice_new0 (NotifyGetMsgsInfo);
1275 info_notify->user_callback = info->user_callback;
1276 info_notify->source = priv->source;
1277 info_notify->msg = msg;
1278 info_notify->user_data = info->user_data;
1279 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1280 notify_get_msgs_full,
1283 g_object_unref (msg);
1287 /* Set status failed and set an error */
1288 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1289 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1290 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1291 "Error trying to get a message. No folder found for header");
1293 g_object_unref (header);
1294 tny_iterator_next (iter);
1297 /* Notify the queue */
1298 g_idle_add (notify_update_account_queue, info->mail_op);
1300 /* Free thread resources. Will be called after all previous idles */
1301 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
1307 modest_mail_operation_get_msgs_full (ModestMailOperation *self,
1308 TnyList *header_list,
1309 GetMsgAsynUserCallback user_callback,
1311 GDestroyNotify notify)
1314 ModestMailOperationPrivate *priv = NULL;
1315 GetFullMsgsInfo *info = NULL;
1316 gboolean size_ok = TRUE;
1318 GError *error = NULL;
1319 const gint KB = 1024;
1321 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1323 /* Init mail operation */
1324 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1325 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1327 priv->total = tny_list_get_length(header_list);
1329 /* Get msg size limit */
1330 max_size = modest_conf_get_int (modest_runtime_get_conf (),
1331 MODEST_CONF_MSG_SIZE_LIMIT,
1334 g_clear_error (&error);
1335 max_size = G_MAXINT;
1337 max_size = max_size * KB;
1340 /* Check message size limits. If there is only one message
1341 always retrieve it */
1342 if (tny_list_get_length (header_list) > 1) {
1345 iter = tny_list_create_iterator (header_list);
1346 while (!tny_iterator_is_done (iter) && size_ok) {
1347 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1348 if (tny_header_get_message_size (header) >= max_size)
1350 g_object_unref (header);
1351 tny_iterator_next (iter);
1353 g_object_unref (iter);
1357 /* Create the info */
1358 info = g_slice_new0 (GetFullMsgsInfo);
1359 info->mail_op = self;
1360 info->user_callback = user_callback;
1361 info->user_data = user_data;
1362 info->headers = g_object_ref (header_list);
1363 info->notify = notify;
1365 thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL);
1367 /* FIXME: the error msg is different for pop */
1368 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1369 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
1370 _("emev_ni_ui_imap_msg_sizelimit_error"));
1371 /* Remove from queue and free resources */
1372 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1380 modest_mail_operation_remove_msg (ModestMailOperation *self,
1382 gboolean remove_to_trash)
1385 ModestMailOperationPrivate *priv;
1387 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1388 g_return_if_fail (TNY_IS_HEADER (header));
1390 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1391 folder = tny_header_get_folder (header);
1393 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1395 /* Delete or move to trash */
1396 if (remove_to_trash) {
1397 TnyFolder *trash_folder;
1398 TnyStoreAccount *store_account;
1400 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
1401 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
1402 TNY_FOLDER_TYPE_TRASH);
1407 headers = tny_simple_list_new ();
1408 tny_list_append (headers, G_OBJECT (header));
1409 g_object_unref (header);
1412 modest_mail_operation_xfer_msgs (self, headers, trash_folder, TRUE, NULL, NULL);
1413 g_object_unref (headers);
1414 /* g_object_unref (trash_folder); */
1416 ModestMailOperationPrivate *priv;
1418 /* Set status failed and set an error */
1419 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1420 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1421 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1422 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1423 _("Error trying to delete a message. Trash folder not found"));
1426 g_object_unref (G_OBJECT (store_account));
1428 tny_folder_remove_msg (folder, header, &(priv->error));
1430 tny_folder_sync(folder, TRUE, &(priv->error));
1435 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1437 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1440 g_object_unref (G_OBJECT (folder));
1442 /* Notify the queue */
1443 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1447 transfer_msgs_status_cb (GObject *obj,
1451 XFerMsgAsyncHelper *helper = NULL;
1452 ModestMailOperation *self;
1453 ModestMailOperationPrivate *priv;
1455 g_return_if_fail (status != NULL);
1456 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS);
1458 helper = (XFerMsgAsyncHelper *) user_data;
1459 g_return_if_fail (helper != NULL);
1461 /* Temporary FIX: useful when tinymail send us status
1462 information *after* calling the function callback */
1463 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1466 self = helper->mail_op;
1467 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1469 if ((status->position == 1) && (status->of_total == 100))
1472 priv->done = status->position;
1473 priv->total = status->of_total;
1475 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1480 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data)
1482 XFerMsgAsyncHelper *helper;
1483 ModestMailOperation *self;
1484 ModestMailOperationPrivate *priv;
1486 helper = (XFerMsgAsyncHelper *) user_data;
1487 self = helper->mail_op;
1489 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1492 priv->error = g_error_copy (*err);
1494 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1495 } else if (cancelled) {
1496 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1497 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1498 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1499 _("Error trying to refresh the contents of %s"),
1500 tny_folder_get_name (folder));
1503 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1506 /* If user defined callback function was defined, call it */
1507 if (helper->user_callback) {
1508 helper->user_callback (priv->source, helper->user_data);
1512 g_object_unref (helper->headers);
1513 g_object_unref (helper->dest_folder);
1514 g_object_unref (helper->mail_op);
1515 g_slice_free (XFerMsgAsyncHelper, helper);
1516 g_object_unref (folder);
1518 /* Notify the queue */
1519 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1523 modest_mail_operation_xfer_msgs (ModestMailOperation *self,
1526 gboolean delete_original,
1527 XferMsgsAsynUserCallback user_callback,
1530 ModestMailOperationPrivate *priv;
1532 TnyFolder *src_folder;
1533 XFerMsgAsyncHelper *helper;
1536 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1537 g_return_if_fail (TNY_IS_LIST (headers));
1538 g_return_if_fail (TNY_IS_FOLDER (folder));
1540 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1543 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1545 /* Create the helper */
1546 helper = g_slice_new0 (XFerMsgAsyncHelper);
1547 helper->mail_op = g_object_ref(self);
1548 helper->dest_folder = g_object_ref(folder);
1549 helper->headers = g_object_ref(headers);
1550 helper->user_callback = user_callback;
1551 helper->user_data = user_data;
1553 /* Get source folder */
1554 iter = tny_list_create_iterator (headers);
1555 header = TNY_HEADER (tny_iterator_get_current (iter));
1556 src_folder = tny_header_get_folder (header);
1557 g_object_unref (header);
1558 g_object_unref (iter);
1560 /* Transfer messages */
1561 tny_folder_transfer_msgs_async (src_folder,
1566 transfer_msgs_status_cb,
1572 on_refresh_folder (TnyFolder *folder,
1577 ModestMailOperation *self;
1578 ModestMailOperationPrivate *priv;
1580 self = MODEST_MAIL_OPERATION (user_data);
1581 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1584 priv->error = g_error_copy (*error);
1585 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1590 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1591 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1592 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1593 _("Error trying to refresh the contents of %s"),
1594 tny_folder_get_name (folder));
1598 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1602 g_object_unref (folder);
1604 /* Notify the queue */
1605 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);
1609 on_refresh_folder_status_update (GObject *obj,
1613 ModestMailOperation *self;
1614 ModestMailOperationPrivate *priv;
1616 g_return_if_fail (status != NULL);
1617 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH);
1619 /* Temporary FIX: useful when tinymail send us status
1620 information *after* calling the function callback */
1621 if (!MODEST_IS_MAIL_OPERATION (user_data))
1624 self = MODEST_MAIL_OPERATION (user_data);
1625 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1627 priv->done = status->position;
1628 priv->total = status->of_total;
1630 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1634 modest_mail_operation_refresh_folder (ModestMailOperation *self,
1637 ModestMailOperationPrivate *priv;
1639 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1641 /* Pick a reference */
1642 g_object_ref (folder);
1644 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1646 /* Refresh the folder. TODO: tinymail could issue a status
1647 updates before the callback call then this could happen. We
1648 must review the design */
1649 tny_folder_refresh_async (folder,
1651 on_refresh_folder_status_update,
1656 _modest_mail_operation_notify_end (ModestMailOperation *self)
1658 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);