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"
57 /* 'private'/'protected' functions */
58 static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
59 static void modest_mail_operation_init (ModestMailOperation *obj);
60 static void modest_mail_operation_finalize (GObject *obj);
62 static void get_msg_cb (TnyFolder *folder,
68 static void get_msg_status_cb (GObject *obj,
72 static void modest_mail_operation_notify_end (ModestMailOperation *self);
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 GetMsgAsyncUserCallback 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;
283 modest_mail_operation_get_source (ModestMailOperation *self)
285 ModestMailOperationPrivate *priv;
287 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
289 return g_object_ref (priv->source);
293 modest_mail_operation_send_mail (ModestMailOperation *self,
294 TnyTransportAccount *transport_account,
297 TnySendQueue *send_queue;
299 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
300 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
301 g_return_if_fail (TNY_IS_MSG (msg));
303 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
304 if (!TNY_IS_SEND_QUEUE(send_queue))
305 g_printerr ("modest: could not find send queue for account\n");
308 tny_send_queue_add (send_queue, msg, &err);
310 g_printerr ("modest: error adding msg to send queue: %s\n",
314 /* g_message ("modest: message added to send queue"); */
318 /* Notify about operation end */
319 modest_mail_operation_notify_end (self);
323 modest_mail_operation_send_new_mail (ModestMailOperation *self,
324 TnyTransportAccount *transport_account,
325 const gchar *from, const gchar *to,
326 const gchar *cc, const gchar *bcc,
327 const gchar *subject, const gchar *plain_body,
328 const gchar *html_body,
329 const GList *attachments_list,
330 TnyHeaderFlags priority_flags)
333 ModestMailOperationPrivate *priv = NULL;
334 /* GList *node = NULL; */
336 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
337 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
339 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
341 /* Check parametters */
343 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
344 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
345 _("Error trying to send a mail. You need to set at least one recipient"));
349 if (html_body == NULL) {
350 new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
352 new_msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
355 g_printerr ("modest: failed to create a new msg\n");
359 /* TODO: add priority handling. It's received in the priority_flags operator, and
360 it should have effect in the sending operation */
362 /* Call mail operation */
363 modest_mail_operation_send_mail (self, transport_account, new_msg);
366 g_object_unref (G_OBJECT (new_msg));
370 modest_mail_operation_save_to_drafts (ModestMailOperation *self,
371 TnyTransportAccount *transport_account,
372 const gchar *from, const gchar *to,
373 const gchar *cc, const gchar *bcc,
374 const gchar *subject, const gchar *plain_body,
375 const gchar *html_body,
376 const GList *attachments_list,
377 TnyHeaderFlags priority_flags)
380 TnyFolder *folder = NULL;
381 ModestMailOperationPrivate *priv = NULL;
384 /* GList *node = NULL; */
386 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
387 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
389 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
391 if (html_body == NULL) {
392 msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
394 msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
397 g_printerr ("modest: failed to create a new msg\n");
401 folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
403 g_printerr ("modest: failed to find Drafts folder\n");
407 tny_folder_add_msg (folder, msg, &err);
409 g_printerr ("modest: error adding msg to Drafts folder: %s",
415 modest_mail_operation_notify_end (self);
420 g_object_unref (G_OBJECT(msg));
422 g_object_unref (G_OBJECT(folder));
427 ModestMailOperation *mail_op;
428 TnyStoreAccount *account;
429 TnyTransportAccount *transport_account;
432 gchar *retrieve_type;
436 recurse_folders (TnyFolderStore *store, TnyFolderStoreQuery *query, TnyList *all_folders)
439 TnyList *folders = tny_simple_list_new ();
441 tny_folder_store_get_folders (store, folders, query, NULL);
442 iter = tny_list_create_iterator (folders);
444 while (!tny_iterator_is_done (iter)) {
446 TnyFolderStore *folder = (TnyFolderStore*) tny_iterator_get_current (iter);
448 tny_list_prepend (all_folders, G_OBJECT (folder));
449 recurse_folders (folder, query, all_folders);
450 g_object_unref (G_OBJECT (folder));
452 tny_iterator_next (iter);
454 g_object_unref (G_OBJECT (iter));
455 g_object_unref (G_OBJECT (folders));
459 * Used by update_account_thread to emit the "progress-changed" signal
460 * from the main loop. We call it inside an idle call to achieve that
463 notify_update_account_observers (gpointer data)
465 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
467 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
473 * Used by update_account_thread to notify the queue from the main
474 * loop. We call it inside an idle call to achieve that
477 notify_update_account_queue (gpointer data)
479 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
481 modest_mail_operation_notify_end (mail_op);
482 g_object_unref (mail_op);
488 update_account_thread (gpointer thr_user_data)
490 UpdateAccountInfo *info;
491 TnyList *all_folders = NULL;
492 TnyIterator *iter = NULL;
493 TnyFolderStoreQuery *query = NULL;
494 ModestMailOperationPrivate *priv;
495 ModestTnySendQueue *send_queue;
498 info = (UpdateAccountInfo *) thr_user_data;
499 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
501 /* Get all the folders We can do it synchronously because
502 we're already running in a different thread than the UI */
503 all_folders = tny_simple_list_new ();
504 query = tny_folder_store_query_new ();
505 tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
506 tny_folder_store_get_folders (TNY_FOLDER_STORE (info->account),
511 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
515 iter = tny_list_create_iterator (all_folders);
516 while (!tny_iterator_is_done (iter)) {
517 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
519 recurse_folders (folder, query, all_folders);
520 tny_iterator_next (iter);
522 g_object_unref (G_OBJECT (iter));
524 /* Update status and notify. We need to call the notification
525 with a source functopm in order to call it from the main
526 loop. We need that in order not to get into trouble with
527 Gtk+. We use a timeout in order to provide more status
528 information, because the sync tinymail call does not
529 provide it for the moment */
530 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
532 /* Refresh folders */
533 iter = tny_list_create_iterator (all_folders);
534 while (!tny_iterator_is_done (iter) && !priv->error) {
536 TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter));
538 /* Refresh the folder */
539 tny_folder_refresh (TNY_FOLDER (folder), &(priv->error));
541 /* TODO: Apply retrieval types */
543 /* TODO: apply per-message size limits */
545 /* TODO: apply message count limit */
548 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
551 g_object_unref (G_OBJECT (folder));
552 tny_iterator_next (iter);
554 g_object_unref (G_OBJECT (iter));
555 g_source_remove (timeout);
558 priv->id = MODEST_MAIL_OPERATION_ID_SEND;
560 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(info->transport_account));
562 timeout = g_timeout_add (250, notify_update_account_observers, info->mail_op);
563 modest_tny_send_queue_flush (send_queue);
564 g_source_remove (timeout);
566 g_object_unref (G_OBJECT(send_queue));
568 /* Check if the operation was a success */
570 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
572 /* Update the last updated key */
573 modest_account_mgr_set_int (modest_runtime_get_account_mgr (),
574 tny_account_get_id (TNY_ACCOUNT (info->account)),
575 MODEST_ACCOUNT_LAST_UPDATED,
581 /* Notify about operation end. Note that the info could be
582 freed before this idle happens, but the mail operation will
584 g_idle_add (notify_update_account_queue, info->mail_op);
587 g_object_unref (query);
588 g_object_unref (all_folders);
589 g_object_unref (info->account);
590 g_object_unref (info->transport_account);
591 g_free (info->retrieve_type);
592 g_slice_free (UpdateAccountInfo, info);
598 modest_mail_operation_update_account (ModestMailOperation *self,
599 const gchar *account_name)
602 UpdateAccountInfo *info;
603 ModestMailOperationPrivate *priv;
604 ModestAccountMgr *mgr;
605 TnyStoreAccount *modest_account;
606 TnyTransportAccount *transport_account;
609 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
610 g_return_val_if_fail (account_name, FALSE);
612 /* Init mail operation. Set total and done to 0, and do not
613 update them, this way the progress objects will know that
614 we have no clue about the number of the objects */
615 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
618 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
620 /* Get the Modest account */
621 modest_account = (TnyStoreAccount *)
622 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store (),
624 TNY_ACCOUNT_TYPE_STORE);
626 if (!modest_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 store account for %s\n", account_name);
631 modest_mail_operation_notify_end (self);
635 /* Get the transport account, we can not do it in the thread
636 due to some problems with dbus */
637 transport_account = (TnyTransportAccount *)
638 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
640 if (!transport_account) {
641 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
642 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
643 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
644 "cannot get tny transport account for %s\n", account_name);
645 modest_mail_operation_notify_end (self);
649 /* Create the helper object */
650 info = g_slice_new (UpdateAccountInfo);
651 info->mail_op = self;
652 info->account = modest_account;
653 info->transport_account = transport_account;
655 /* Get the message retrieval global and per-account settings */
656 info->max_size = modest_conf_get_int (modest_runtime_get_conf (), MODEST_CONF_MSG_SIZE_LIMIT, NULL);
657 if (info->max_size == 0)
658 info->max_size = G_MAXINT;
660 info->max_size = max_size * KB;
662 mgr = modest_runtime_get_account_mgr ();
663 info->retrieve_type = modest_account_mgr_get_string (mgr, account_name, MODEST_ACCOUNT_RETRIEVE, FALSE);
664 info->retrieve_limit = modest_account_mgr_get_int (mgr, account_name, MODEST_ACCOUNT_LIMIT_RETRIEVE, FALSE);
666 thread = g_thread_create (update_account_thread, info, FALSE, NULL);
671 ModestMailOperationStatus
672 modest_mail_operation_get_status (ModestMailOperation *self)
674 ModestMailOperationPrivate *priv;
676 g_return_val_if_fail (self, MODEST_MAIL_OPERATION_STATUS_INVALID);
677 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self),
678 MODEST_MAIL_OPERATION_STATUS_INVALID);
680 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
685 modest_mail_operation_get_error (ModestMailOperation *self)
687 ModestMailOperationPrivate *priv;
689 g_return_val_if_fail (self, NULL);
690 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
692 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
697 modest_mail_operation_cancel (ModestMailOperation *self)
699 ModestMailOperationPrivate *priv;
701 if (!MODEST_IS_MAIL_OPERATION (self)) {
702 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
706 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
708 /* TODO: Tinymail does not support cancel operation */
709 /* tny_account_cancel (); */
712 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
714 /* Notify about operation end */
715 modest_mail_operation_notify_end (self);
721 modest_mail_operation_get_task_done (ModestMailOperation *self)
723 ModestMailOperationPrivate *priv;
725 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
727 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
732 modest_mail_operation_get_task_total (ModestMailOperation *self)
734 ModestMailOperationPrivate *priv;
736 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
738 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
743 modest_mail_operation_is_finished (ModestMailOperation *self)
745 ModestMailOperationPrivate *priv;
746 gboolean retval = FALSE;
748 if (!MODEST_IS_MAIL_OPERATION (self)) {
749 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
753 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
755 if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS ||
756 priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED ||
757 priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED ||
758 priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) {
767 /* ******************************************************************* */
768 /* ************************** STORE ACTIONS ************************* */
769 /* ******************************************************************* */
773 modest_mail_operation_create_folder (ModestMailOperation *self,
774 TnyFolderStore *parent,
777 ModestTnyFolderRules rules;
778 ModestMailOperationPrivate *priv;
779 TnyFolder *new_folder = NULL;
780 gboolean can_create = FALSE;
782 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
783 g_return_val_if_fail (name, NULL);
785 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
788 if (!TNY_IS_FOLDER (parent)) {
789 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
790 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
791 _("mail_in_ui_folder_create_error"));
793 /* Check folder rules */
794 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
795 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)
796 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
797 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
798 _("mail_in_ui_folder_create_error"));
804 /* Create the folder */
805 new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
806 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
809 /* Notify about operation end */
810 modest_mail_operation_notify_end (self);
816 modest_mail_operation_remove_folder (ModestMailOperation *self,
818 gboolean remove_to_trash)
821 ModestMailOperationPrivate *priv;
822 ModestTnyFolderRules rules;
824 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
825 g_return_if_fail (TNY_IS_FOLDER (folder));
827 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
829 /* Check folder rules */
830 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
831 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE) {
832 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
833 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
834 _("mail_in_ui_folder_delete_error"));
838 /* Get the account */
839 account = tny_folder_get_account (folder);
841 /* Delete folder or move to trash */
842 if (remove_to_trash) {
843 TnyFolder *trash_folder = NULL;
844 trash_folder = modest_tny_account_get_special_folder (account,
845 TNY_FOLDER_TYPE_TRASH);
846 /* TODO: error_handling */
847 modest_mail_operation_xfer_folder (self, folder,
848 TNY_FOLDER_STORE (trash_folder), TRUE);
850 TnyFolderStore *parent = tny_folder_get_folder_store (folder);
852 tny_folder_store_remove_folder (parent, folder, &(priv->error));
853 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
856 g_object_unref (G_OBJECT (parent));
858 g_object_unref (G_OBJECT (account));
861 /* Notify about operation end */
862 modest_mail_operation_notify_end (self);
866 modest_mail_operation_rename_folder (ModestMailOperation *self,
870 ModestMailOperationPrivate *priv;
871 ModestTnyFolderRules rules;
873 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
874 g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
875 g_return_if_fail (name);
877 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
879 /* Check folder rules */
880 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
881 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
882 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
883 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
884 _("FIXME: unable to rename"));
886 /* Rename. Camel handles folder subscription/unsubscription */
887 TnyFolderStore *into;
890 into = tny_folder_get_folder_store (folder);
891 nfol = tny_folder_copy (folder, into, name, TRUE, &(priv->error));
893 g_object_unref (into);
895 g_object_unref (nfol);
897 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
901 /* Notify about operation end */
902 modest_mail_operation_notify_end (self);
906 transfer_folder_status_cb (GObject *obj,
910 XFerMsgAsyncHelper *helper = NULL;
911 ModestMailOperation *self;
912 ModestMailOperationPrivate *priv;
914 g_return_if_fail (status != NULL);
915 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER);
917 helper = (XFerMsgAsyncHelper *) user_data;
918 g_return_if_fail (helper != NULL);
920 self = helper->mail_op;
921 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
923 if ((status->position == 1) && (status->of_total == 100))
926 priv->done = status->position;
927 priv->total = status->of_total;
929 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
934 transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, GError **err, gpointer user_data)
936 XFerFolderAsyncHelper *helper = NULL;
937 ModestMailOperation *self = NULL;
938 ModestMailOperationPrivate *priv = NULL;
940 helper = (XFerFolderAsyncHelper *) user_data;
941 self = helper->mail_op;
943 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
946 priv->error = g_error_copy (*err);
948 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
949 } else if (cancelled) {
950 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
951 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
952 MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
953 _("Transference of %s was cancelled."),
954 tny_folder_get_name (folder));
957 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
961 g_slice_free (XFerFolderAsyncHelper, helper);
962 g_object_unref (folder);
963 g_object_unref (into);
964 if (new_folder != NULL)
965 g_object_unref (new_folder);
967 /* Notify about operation end */
968 modest_mail_operation_notify_end (self);
972 modest_mail_operation_xfer_folder (ModestMailOperation *self,
974 TnyFolderStore *parent,
975 gboolean delete_original)
977 XFerFolderAsyncHelper *helper = NULL;
978 ModestMailOperationPrivate *priv = NULL;
979 ModestTnyFolderRules parent_rules, rules;
981 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
982 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
983 g_return_if_fail (TNY_IS_FOLDER (folder));
985 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
987 /* Pick references for async calls */
988 g_object_ref (folder);
989 g_object_ref (parent);
991 /* Get folder rules */
992 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
993 parent_rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
995 /* The moveable restriction is applied also to copy operation */
996 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
997 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
998 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
999 _("mail_in_ui_folder_move_target_error"));
1001 /* Notify the queue */
1002 modest_mail_operation_notify_end (self);
1003 } else if (parent_rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
1004 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1005 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
1006 _("FIXME: parent folder does not accept new folders"));
1008 /* Notify the queue */
1009 modest_mail_operation_notify_end (self);
1011 helper = g_slice_new0 (XFerFolderAsyncHelper);
1012 helper->mail_op = self;
1014 /* Move/Copy folder */
1015 tny_folder_copy_async (folder,
1017 tny_folder_get_name (folder),
1020 transfer_folder_status_cb,
1026 /* ******************************************************************* */
1027 /* ************************** MSG ACTIONS ************************* */
1028 /* ******************************************************************* */
1030 void modest_mail_operation_get_msg (ModestMailOperation *self,
1032 GetMsgAsyncUserCallback user_callback,
1035 GetMsgAsyncHelper *helper = NULL;
1037 ModestMailOperationPrivate *priv;
1039 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1040 g_return_if_fail (TNY_IS_HEADER (header));
1042 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1043 folder = tny_header_get_folder (header);
1045 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1047 /* Get message from folder */
1049 helper = g_slice_new0 (GetMsgAsyncHelper);
1050 helper->mail_op = self;
1051 helper->user_callback = user_callback;
1052 helper->pending_ops = 1;
1053 helper->user_data = user_data;
1055 tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper);
1057 g_object_unref (G_OBJECT (folder));
1059 /* Set status failed and set an error */
1060 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1061 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1062 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1063 _("Error trying to get a message. No folder found for header"));
1068 get_msg_cb (TnyFolder *folder,
1074 GetMsgAsyncHelper *helper = NULL;
1075 ModestMailOperation *self = NULL;
1076 ModestMailOperationPrivate *priv = NULL;
1078 helper = (GetMsgAsyncHelper *) user_data;
1079 g_return_if_fail (helper != NULL);
1080 self = helper->mail_op;
1081 g_return_if_fail (MODEST_IS_MAIL_OPERATION(self));
1082 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1084 helper->pending_ops--;
1086 /* Check errors and cancel */
1088 priv->error = g_error_copy (*error);
1089 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1093 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1094 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1095 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1096 _("Error trying to refresh the contents of %s"),
1097 tny_folder_get_name (folder));
1101 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1103 /* If user defined callback function was defined, call it */
1104 if (helper->user_callback) {
1105 helper->user_callback (self, NULL, msg, helper->user_data);
1110 if (helper->pending_ops == 0) {
1111 g_slice_free (GetMsgAsyncHelper, helper);
1113 /* Notify about operation end */
1114 modest_mail_operation_notify_end (self);
1119 get_msg_status_cb (GObject *obj,
1123 GetMsgAsyncHelper *helper = NULL;
1124 ModestMailOperation *self;
1125 ModestMailOperationPrivate *priv;
1127 g_return_if_fail (status != NULL);
1128 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG);
1130 helper = (GetMsgAsyncHelper *) user_data;
1131 g_return_if_fail (helper != NULL);
1133 /* Temporary FIX: useful when tinymail send us status
1134 information *after* calling the function callback */
1135 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1138 self = helper->mail_op;
1139 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1141 if ((status->position == 1) && (status->of_total == 100))
1147 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1150 /****************************************************/
1152 ModestMailOperation *mail_op;
1154 GetMsgAsyncUserCallback user_callback;
1156 GDestroyNotify notify;
1160 * Used by get_msgs_full_thread to emit the "progress-changed" signal
1161 * from the main loop. We call it inside an idle call to achieve that
1164 notify_get_msgs_full_observers (gpointer data)
1166 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
1168 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1174 GetMsgAsyncUserCallback user_callback;
1178 ModestMailOperation *mail_op;
1179 } NotifyGetMsgsInfo;
1183 * Used by get_msgs_full_thread to call the user_callback for each
1184 * message that has been read
1187 notify_get_msgs_full (gpointer data)
1189 NotifyGetMsgsInfo *info;
1191 info = (NotifyGetMsgsInfo *) data;
1193 /* Call the user callback */
1194 info->user_callback (info->mail_op, info->header, info->msg, info->user_data);
1196 g_slice_free (NotifyGetMsgsInfo, info);
1202 * Used by get_msgs_full_thread to free al the thread resources and to
1203 * call the destroy function for the passed user_data
1206 get_msgs_full_destroyer (gpointer data)
1208 GetFullMsgsInfo *info;
1210 info = (GetFullMsgsInfo *) data;
1213 info->notify (info->user_data);
1216 g_object_unref (info->headers);
1217 g_slice_free (GetFullMsgsInfo, info);
1223 get_msgs_full_thread (gpointer thr_user_data)
1225 GetFullMsgsInfo *info;
1226 ModestMailOperationPrivate *priv = NULL;
1227 TnyIterator *iter = NULL;
1229 info = (GetFullMsgsInfo *) thr_user_data;
1230 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
1232 iter = tny_list_create_iterator (info->headers);
1233 while (!tny_iterator_is_done (iter)) {
1237 header = TNY_HEADER (tny_iterator_get_current (iter));
1238 folder = tny_header_get_folder (header);
1240 /* Get message from folder */
1243 /* The callback will call it per each header */
1244 msg = tny_folder_get_msg (folder, header, &(priv->error));
1249 /* notify progress */
1250 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1251 notify_get_msgs_full_observers,
1252 info->mail_op, NULL);
1254 /* The callback is the responsible for
1255 freeing the message */
1256 if (info->user_callback) {
1257 NotifyGetMsgsInfo *info_notify;
1258 info_notify = g_slice_new0 (NotifyGetMsgsInfo);
1259 info_notify->user_callback = info->user_callback;
1260 info_notify->mail_op = info->mail_op;
1261 info_notify->header = g_object_ref (header);
1262 info_notify->msg = g_object_ref (msg);
1263 info_notify->user_data = info->user_data;
1264 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1265 notify_get_msgs_full,
1268 g_object_unref (msg);
1271 /* Set status failed and set an error */
1272 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1273 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1274 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1275 "Error trying to get a message. No folder found for header");
1277 g_object_unref (header);
1278 tny_iterator_next (iter);
1281 /* Notify about operation end */
1282 g_idle_add (notify_update_account_queue, info->mail_op);
1284 /* Free thread resources. Will be called after all previous idles */
1285 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
1291 modest_mail_operation_get_msgs_full (ModestMailOperation *self,
1292 TnyList *header_list,
1293 GetMsgAsyncUserCallback user_callback,
1295 GDestroyNotify notify)
1298 ModestMailOperationPrivate *priv = NULL;
1299 GetFullMsgsInfo *info = NULL;
1300 gboolean size_ok = TRUE;
1302 GError *error = NULL;
1304 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1306 /* Init mail operation */
1307 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1308 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1310 priv->total = tny_list_get_length(header_list);
1312 /* Get msg size limit */
1313 max_size = modest_conf_get_int (modest_runtime_get_conf (),
1314 MODEST_CONF_MSG_SIZE_LIMIT,
1317 g_clear_error (&error);
1318 max_size = G_MAXINT;
1320 max_size = max_size * KB;
1323 /* Check message size limits. If there is only one message
1324 always retrieve it */
1325 if (tny_list_get_length (header_list) > 1) {
1328 iter = tny_list_create_iterator (header_list);
1329 while (!tny_iterator_is_done (iter) && size_ok) {
1330 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1331 if (tny_header_get_message_size (header) >= max_size)
1333 g_object_unref (header);
1334 tny_iterator_next (iter);
1336 g_object_unref (iter);
1340 /* Create the info */
1341 info = g_slice_new0 (GetFullMsgsInfo);
1342 info->mail_op = self;
1343 info->user_callback = user_callback;
1344 info->user_data = user_data;
1345 info->headers = g_object_ref (header_list);
1346 info->notify = notify;
1348 thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL);
1350 /* FIXME: the error msg is different for pop */
1351 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1352 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
1353 _("emev_ni_ui_imap_msg_sizelimit_error"));
1354 /* Remove from queue and free resources */
1355 modest_mail_operation_notify_end (self);
1363 modest_mail_operation_remove_msg (ModestMailOperation *self,
1365 gboolean remove_to_trash)
1368 ModestMailOperationPrivate *priv;
1370 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1371 g_return_if_fail (TNY_IS_HEADER (header));
1373 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1374 folder = tny_header_get_folder (header);
1376 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1378 /* Delete or move to trash */
1379 if (remove_to_trash) {
1380 TnyFolder *trash_folder;
1381 TnyStoreAccount *store_account;
1383 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
1384 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
1385 TNY_FOLDER_TYPE_TRASH);
1390 headers = tny_simple_list_new ();
1391 tny_list_append (headers, G_OBJECT (header));
1392 g_object_unref (header);
1395 modest_mail_operation_xfer_msgs (self, headers, trash_folder, TRUE, NULL, NULL);
1396 g_object_unref (headers);
1397 /* g_object_unref (trash_folder); */
1399 ModestMailOperationPrivate *priv;
1401 /* Set status failed and set an error */
1402 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1403 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1404 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1405 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1406 _("Error trying to delete a message. Trash folder not found"));
1409 g_object_unref (G_OBJECT (store_account));
1411 tny_folder_remove_msg (folder, header, &(priv->error));
1413 tny_folder_sync(folder, TRUE, &(priv->error));
1418 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1420 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1423 g_object_unref (G_OBJECT (folder));
1425 /* Notify about operation end */
1426 modest_mail_operation_notify_end (self);
1430 transfer_msgs_status_cb (GObject *obj,
1434 XFerMsgAsyncHelper *helper = NULL;
1435 ModestMailOperation *self;
1436 ModestMailOperationPrivate *priv;
1438 g_return_if_fail (status != NULL);
1439 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS);
1441 helper = (XFerMsgAsyncHelper *) user_data;
1442 g_return_if_fail (helper != NULL);
1444 self = helper->mail_op;
1445 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1447 if ((status->position == 1) && (status->of_total == 100))
1450 priv->done = status->position;
1451 priv->total = status->of_total;
1453 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1458 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data)
1460 XFerMsgAsyncHelper *helper;
1461 ModestMailOperation *self;
1462 ModestMailOperationPrivate *priv;
1464 helper = (XFerMsgAsyncHelper *) user_data;
1465 self = helper->mail_op;
1467 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1470 priv->error = g_error_copy (*err);
1472 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1473 } else if (cancelled) {
1474 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1475 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1476 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1477 _("Error trying to refresh the contents of %s"),
1478 tny_folder_get_name (folder));
1481 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1484 /* If user defined callback function was defined, call it */
1485 if (helper->user_callback) {
1486 helper->user_callback (priv->source, helper->user_data);
1490 g_object_unref (helper->headers);
1491 g_object_unref (helper->dest_folder);
1492 g_object_unref (helper->mail_op);
1493 g_slice_free (XFerMsgAsyncHelper, helper);
1494 g_object_unref (folder);
1496 /* Notify about operation end */
1497 modest_mail_operation_notify_end (self);
1501 modest_mail_operation_xfer_msgs (ModestMailOperation *self,
1504 gboolean delete_original,
1505 XferMsgsAsynUserCallback user_callback,
1508 ModestMailOperationPrivate *priv;
1510 TnyFolder *src_folder;
1511 XFerMsgAsyncHelper *helper;
1513 ModestTnyFolderRules rules;
1515 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1516 g_return_if_fail (TNY_IS_LIST (headers));
1517 g_return_if_fail (TNY_IS_FOLDER (folder));
1519 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1522 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1524 /* Apply folder rules */
1525 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
1527 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
1528 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1529 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
1530 _("FIXME: folder does not accept msgs"));
1531 /* Notify the queue */
1532 modest_mail_operation_notify_end (self);
1536 /* Create the helper */
1537 helper = g_slice_new0 (XFerMsgAsyncHelper);
1538 helper->mail_op = g_object_ref(self);
1539 helper->dest_folder = g_object_ref(folder);
1540 helper->headers = g_object_ref(headers);
1541 helper->user_callback = user_callback;
1542 helper->user_data = user_data;
1544 /* Get source folder */
1545 iter = tny_list_create_iterator (headers);
1546 header = TNY_HEADER (tny_iterator_get_current (iter));
1547 src_folder = tny_header_get_folder (header);
1548 g_object_unref (header);
1549 g_object_unref (iter);
1551 /* Transfer messages */
1552 tny_folder_transfer_msgs_async (src_folder,
1557 transfer_msgs_status_cb,
1563 on_refresh_folder (TnyFolder *folder,
1568 ModestMailOperation *self;
1569 ModestMailOperationPrivate *priv;
1571 self = MODEST_MAIL_OPERATION (user_data);
1572 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1575 priv->error = g_error_copy (*error);
1576 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1581 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1582 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1583 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1584 _("Error trying to refresh the contents of %s"),
1585 tny_folder_get_name (folder));
1589 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1593 g_object_unref (folder);
1595 /* Notify about operation end */
1596 modest_mail_operation_notify_end (self);
1600 on_refresh_folder_status_update (GObject *obj,
1604 ModestMailOperation *self;
1605 ModestMailOperationPrivate *priv;
1607 g_return_if_fail (status != NULL);
1608 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH);
1610 /* Temporary FIX: useful when tinymail send us status
1611 information *after* calling the function callback */
1612 if (!MODEST_IS_MAIL_OPERATION (user_data))
1615 self = MODEST_MAIL_OPERATION (user_data);
1616 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1618 priv->done = status->position;
1619 priv->total = status->of_total;
1621 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1625 modest_mail_operation_refresh_folder (ModestMailOperation *self,
1628 ModestMailOperationPrivate *priv;
1630 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1632 /* Pick a reference */
1633 g_object_ref (folder);
1635 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1637 /* Refresh the folder. TODO: tinymail could issue a status
1638 updates before the callback call then this could happen. We
1639 must review the design */
1640 tny_folder_refresh_async (folder,
1642 on_refresh_folder_status_update,
1648 * It's used by the mail operation queue to notify the observers
1649 * attached to that signal that the operation finished. We need to use
1650 * that because tinymail does not give us the progress of a given
1651 * operation when it finishes (it directly calls the operation
1655 modest_mail_operation_notify_end (ModestMailOperation *self)
1657 /* Notify the observers about the mail opertation end */
1658 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1660 /* Notify the queue */
1661 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);