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;
608 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
609 g_return_val_if_fail (account_name, FALSE);
611 /* Init mail operation. Set total and done to 0, and do not
612 update them, this way the progress objects will know that
613 we have no clue about the number of the objects */
614 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
617 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
619 /* Get the Modest account */
620 modest_account = (TnyStoreAccount *)
621 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store (),
623 TNY_ACCOUNT_TYPE_STORE);
625 if (!modest_account) {
626 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
627 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
628 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
629 "cannot get tny store account for %s\n", account_name);
630 modest_mail_operation_notify_end (self);
634 /* Get the transport account, we can not do it in the thread
635 due to some problems with dbus */
636 transport_account = (TnyTransportAccount *)
637 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
639 if (!transport_account) {
640 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
641 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
642 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
643 "cannot get tny transport account for %s\n", account_name);
644 modest_mail_operation_notify_end (self);
648 /* Create the helper object */
649 info = g_slice_new (UpdateAccountInfo);
650 info->mail_op = self;
651 info->account = modest_account;
652 info->transport_account = transport_account;
654 /* Get the message retrieval global and per-account settings */
655 info->max_size = modest_conf_get_int (modest_runtime_get_conf (), MODEST_CONF_MSG_SIZE_LIMIT, NULL);
656 if (info->max_size == 0)
657 info->max_size = G_MAXINT;
659 info->max_size = info->max_size * KB; /* TODO: review this fix */
661 mgr = modest_runtime_get_account_mgr ();
662 info->retrieve_type = modest_account_mgr_get_string (mgr, account_name, MODEST_ACCOUNT_RETRIEVE, FALSE);
663 info->retrieve_limit = modest_account_mgr_get_int (mgr, account_name, MODEST_ACCOUNT_LIMIT_RETRIEVE, FALSE);
665 thread = g_thread_create (update_account_thread, info, FALSE, NULL);
670 ModestMailOperationStatus
671 modest_mail_operation_get_status (ModestMailOperation *self)
673 ModestMailOperationPrivate *priv;
675 g_return_val_if_fail (self, MODEST_MAIL_OPERATION_STATUS_INVALID);
676 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self),
677 MODEST_MAIL_OPERATION_STATUS_INVALID);
679 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
684 modest_mail_operation_get_error (ModestMailOperation *self)
686 ModestMailOperationPrivate *priv;
688 g_return_val_if_fail (self, NULL);
689 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
691 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
696 modest_mail_operation_cancel (ModestMailOperation *self)
698 ModestMailOperationPrivate *priv;
700 if (!MODEST_IS_MAIL_OPERATION (self)) {
701 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
705 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
707 /* TODO: Tinymail does not support cancel operation */
708 /* tny_account_cancel (); */
711 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
713 /* Notify about operation end */
714 modest_mail_operation_notify_end (self);
720 modest_mail_operation_get_task_done (ModestMailOperation *self)
722 ModestMailOperationPrivate *priv;
724 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
726 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
731 modest_mail_operation_get_task_total (ModestMailOperation *self)
733 ModestMailOperationPrivate *priv;
735 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
737 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
742 modest_mail_operation_is_finished (ModestMailOperation *self)
744 ModestMailOperationPrivate *priv;
745 gboolean retval = FALSE;
747 if (!MODEST_IS_MAIL_OPERATION (self)) {
748 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
752 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
754 if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS ||
755 priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED ||
756 priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED ||
757 priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) {
766 /* ******************************************************************* */
767 /* ************************** STORE ACTIONS ************************* */
768 /* ******************************************************************* */
772 modest_mail_operation_create_folder (ModestMailOperation *self,
773 TnyFolderStore *parent,
776 ModestTnyFolderRules rules;
777 ModestMailOperationPrivate *priv;
778 TnyFolder *new_folder = NULL;
779 gboolean can_create = FALSE;
781 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
782 g_return_val_if_fail (name, NULL);
784 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
787 if (!TNY_IS_FOLDER (parent)) {
788 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
789 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
790 _("mail_in_ui_folder_create_error"));
792 /* Check folder rules */
793 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
794 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE)
795 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
796 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
797 _("mail_in_ui_folder_create_error"));
803 /* Create the folder */
804 new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
805 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
808 /* Notify about operation end */
809 modest_mail_operation_notify_end (self);
815 modest_mail_operation_remove_folder (ModestMailOperation *self,
817 gboolean remove_to_trash)
820 ModestMailOperationPrivate *priv;
821 ModestTnyFolderRules rules;
823 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
824 g_return_if_fail (TNY_IS_FOLDER (folder));
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_DELETABLE) {
831 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
832 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
833 _("mail_in_ui_folder_delete_error"));
837 /* Get the account */
838 account = tny_folder_get_account (folder);
840 /* Delete folder or move to trash */
841 if (remove_to_trash) {
842 TnyFolder *trash_folder = NULL;
843 trash_folder = modest_tny_account_get_special_folder (account,
844 TNY_FOLDER_TYPE_TRASH);
845 /* TODO: error_handling */
846 modest_mail_operation_xfer_folder (self, folder,
847 TNY_FOLDER_STORE (trash_folder), TRUE);
849 TnyFolderStore *parent = tny_folder_get_folder_store (folder);
851 tny_folder_store_remove_folder (parent, folder, &(priv->error));
852 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
855 g_object_unref (G_OBJECT (parent));
857 g_object_unref (G_OBJECT (account));
860 /* Notify about operation end */
861 modest_mail_operation_notify_end (self);
865 modest_mail_operation_rename_folder (ModestMailOperation *self,
869 ModestMailOperationPrivate *priv;
870 ModestTnyFolderRules rules;
872 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
873 g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
874 g_return_if_fail (name);
876 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
878 /* Check folder rules */
879 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
880 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE) {
881 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
882 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
883 _("FIXME: unable to rename"));
885 /* Rename. Camel handles folder subscription/unsubscription */
886 TnyFolderStore *into;
889 into = tny_folder_get_folder_store (folder);
890 nfol = tny_folder_copy (folder, into, name, TRUE, &(priv->error));
892 g_object_unref (into);
894 g_object_unref (nfol);
896 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED);
900 /* Notify about operation end */
901 modest_mail_operation_notify_end (self);
905 transfer_folder_status_cb (GObject *obj,
909 XFerMsgAsyncHelper *helper = NULL;
910 ModestMailOperation *self;
911 ModestMailOperationPrivate *priv;
913 g_return_if_fail (status != NULL);
914 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_COPY_FOLDER);
916 helper = (XFerMsgAsyncHelper *) user_data;
917 g_return_if_fail (helper != NULL);
919 self = helper->mail_op;
920 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
922 if ((status->position == 1) && (status->of_total == 100))
925 priv->done = status->position;
926 priv->total = status->of_total;
928 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
933 transfer_folder_cb (TnyFolder *folder, TnyFolderStore *into, gboolean cancelled, TnyFolder *new_folder, GError **err, gpointer user_data)
935 XFerFolderAsyncHelper *helper = NULL;
936 ModestMailOperation *self = NULL;
937 ModestMailOperationPrivate *priv = NULL;
939 helper = (XFerFolderAsyncHelper *) user_data;
940 self = helper->mail_op;
942 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
945 priv->error = g_error_copy (*err);
947 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
948 } else if (cancelled) {
949 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
950 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
951 MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
952 _("Transference of %s was cancelled."),
953 tny_folder_get_name (folder));
956 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
960 g_slice_free (XFerFolderAsyncHelper, helper);
961 g_object_unref (folder);
962 g_object_unref (into);
963 if (new_folder != NULL)
964 g_object_unref (new_folder);
966 /* Notify about operation end */
967 modest_mail_operation_notify_end (self);
971 modest_mail_operation_xfer_folder (ModestMailOperation *self,
973 TnyFolderStore *parent,
974 gboolean delete_original)
976 XFerFolderAsyncHelper *helper = NULL;
977 ModestMailOperationPrivate *priv = NULL;
978 ModestTnyFolderRules parent_rules, rules;
980 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
981 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
982 g_return_if_fail (TNY_IS_FOLDER (folder));
984 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
986 /* Pick references for async calls */
987 g_object_ref (folder);
988 g_object_ref (parent);
990 /* Get folder rules */
991 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
992 parent_rules = modest_tny_folder_get_rules (TNY_FOLDER (parent));
994 /* The moveable restriction is applied also to copy operation */
995 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE) {
996 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
997 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
998 _("mail_in_ui_folder_move_target_error"));
1000 /* Notify the queue */
1001 modest_mail_operation_notify_end (self);
1002 } else if (parent_rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
1003 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1004 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
1005 _("FIXME: parent folder does not accept new folders"));
1007 /* Notify the queue */
1008 modest_mail_operation_notify_end (self);
1010 helper = g_slice_new0 (XFerFolderAsyncHelper);
1011 helper->mail_op = self;
1013 /* Move/Copy folder */
1014 tny_folder_copy_async (folder,
1016 tny_folder_get_name (folder),
1019 transfer_folder_status_cb,
1025 /* ******************************************************************* */
1026 /* ************************** MSG ACTIONS ************************* */
1027 /* ******************************************************************* */
1029 void modest_mail_operation_get_msg (ModestMailOperation *self,
1031 GetMsgAsyncUserCallback user_callback,
1034 GetMsgAsyncHelper *helper = NULL;
1036 ModestMailOperationPrivate *priv;
1038 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1039 g_return_if_fail (TNY_IS_HEADER (header));
1041 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1042 folder = tny_header_get_folder (header);
1044 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1046 /* Get message from folder */
1048 helper = g_slice_new0 (GetMsgAsyncHelper);
1049 helper->mail_op = self;
1050 helper->user_callback = user_callback;
1051 helper->pending_ops = 1;
1052 helper->user_data = user_data;
1054 tny_folder_get_msg_async (folder, header, get_msg_cb, get_msg_status_cb, helper);
1056 g_object_unref (G_OBJECT (folder));
1058 /* Set status failed and set an error */
1059 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1060 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1061 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1062 _("Error trying to get a message. No folder found for header"));
1067 get_msg_cb (TnyFolder *folder,
1073 GetMsgAsyncHelper *helper = NULL;
1074 ModestMailOperation *self = NULL;
1075 ModestMailOperationPrivate *priv = NULL;
1077 helper = (GetMsgAsyncHelper *) user_data;
1078 g_return_if_fail (helper != NULL);
1079 self = helper->mail_op;
1080 g_return_if_fail (MODEST_IS_MAIL_OPERATION(self));
1081 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1083 helper->pending_ops--;
1085 /* Check errors and cancel */
1087 priv->error = g_error_copy (*error);
1088 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1092 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1093 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1094 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1095 _("Error trying to refresh the contents of %s"),
1096 tny_folder_get_name (folder));
1100 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1102 /* If user defined callback function was defined, call it */
1103 if (helper->user_callback) {
1104 helper->user_callback (self, NULL, msg, helper->user_data);
1109 if (helper->pending_ops == 0) {
1110 g_slice_free (GetMsgAsyncHelper, helper);
1112 /* Notify about operation end */
1113 modest_mail_operation_notify_end (self);
1118 get_msg_status_cb (GObject *obj,
1122 GetMsgAsyncHelper *helper = NULL;
1123 ModestMailOperation *self;
1124 ModestMailOperationPrivate *priv;
1126 g_return_if_fail (status != NULL);
1127 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_GET_MSG);
1129 helper = (GetMsgAsyncHelper *) user_data;
1130 g_return_if_fail (helper != NULL);
1132 /* Temporary FIX: useful when tinymail send us status
1133 information *after* calling the function callback */
1134 if (!MODEST_IS_MAIL_OPERATION (helper->mail_op))
1137 self = helper->mail_op;
1138 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1140 if ((status->position == 1) && (status->of_total == 100))
1146 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1149 /****************************************************/
1151 ModestMailOperation *mail_op;
1153 GetMsgAsyncUserCallback user_callback;
1155 GDestroyNotify notify;
1159 * Used by get_msgs_full_thread to emit the "progress-changed" signal
1160 * from the main loop. We call it inside an idle call to achieve that
1163 notify_get_msgs_full_observers (gpointer data)
1165 ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
1167 g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1173 GetMsgAsyncUserCallback user_callback;
1177 ModestMailOperation *mail_op;
1178 } NotifyGetMsgsInfo;
1182 * Used by get_msgs_full_thread to call the user_callback for each
1183 * message that has been read
1186 notify_get_msgs_full (gpointer data)
1188 NotifyGetMsgsInfo *info;
1190 info = (NotifyGetMsgsInfo *) data;
1192 /* Call the user callback */
1193 info->user_callback (info->mail_op, info->header, info->msg, info->user_data);
1195 g_slice_free (NotifyGetMsgsInfo, info);
1201 * Used by get_msgs_full_thread to free al the thread resources and to
1202 * call the destroy function for the passed user_data
1205 get_msgs_full_destroyer (gpointer data)
1207 GetFullMsgsInfo *info;
1209 info = (GetFullMsgsInfo *) data;
1212 info->notify (info->user_data);
1215 g_object_unref (info->headers);
1216 g_slice_free (GetFullMsgsInfo, info);
1222 get_msgs_full_thread (gpointer thr_user_data)
1224 GetFullMsgsInfo *info;
1225 ModestMailOperationPrivate *priv = NULL;
1226 TnyIterator *iter = NULL;
1228 info = (GetFullMsgsInfo *) thr_user_data;
1229 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
1231 iter = tny_list_create_iterator (info->headers);
1232 while (!tny_iterator_is_done (iter)) {
1236 header = TNY_HEADER (tny_iterator_get_current (iter));
1237 folder = tny_header_get_folder (header);
1239 /* Get message from folder */
1242 /* The callback will call it per each header */
1243 msg = tny_folder_get_msg (folder, header, &(priv->error));
1248 /* notify progress */
1249 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1250 notify_get_msgs_full_observers,
1251 info->mail_op, NULL);
1253 /* The callback is the responsible for
1254 freeing the message */
1255 if (info->user_callback) {
1256 NotifyGetMsgsInfo *info_notify;
1257 info_notify = g_slice_new0 (NotifyGetMsgsInfo);
1258 info_notify->user_callback = info->user_callback;
1259 info_notify->mail_op = info->mail_op;
1260 info_notify->header = g_object_ref (header);
1261 info_notify->msg = g_object_ref (msg);
1262 info_notify->user_data = info->user_data;
1263 g_idle_add_full (G_PRIORITY_HIGH_IDLE,
1264 notify_get_msgs_full,
1267 g_object_unref (msg);
1270 /* Set status failed and set an error */
1271 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1272 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1273 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1274 "Error trying to get a message. No folder found for header");
1276 g_object_unref (header);
1277 tny_iterator_next (iter);
1280 /* Notify about operation end */
1281 g_idle_add (notify_update_account_queue, info->mail_op);
1283 /* Free thread resources. Will be called after all previous idles */
1284 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
1290 modest_mail_operation_get_msgs_full (ModestMailOperation *self,
1291 TnyList *header_list,
1292 GetMsgAsyncUserCallback user_callback,
1294 GDestroyNotify notify)
1297 ModestMailOperationPrivate *priv = NULL;
1298 GetFullMsgsInfo *info = NULL;
1299 gboolean size_ok = TRUE;
1301 GError *error = NULL;
1303 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1305 /* Init mail operation */
1306 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1307 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1309 priv->total = tny_list_get_length(header_list);
1311 /* Get msg size limit */
1312 max_size = modest_conf_get_int (modest_runtime_get_conf (),
1313 MODEST_CONF_MSG_SIZE_LIMIT,
1316 g_clear_error (&error);
1317 max_size = G_MAXINT;
1319 max_size = max_size * KB;
1322 /* Check message size limits. If there is only one message
1323 always retrieve it */
1324 if (tny_list_get_length (header_list) > 1) {
1327 iter = tny_list_create_iterator (header_list);
1328 while (!tny_iterator_is_done (iter) && size_ok) {
1329 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1330 if (tny_header_get_message_size (header) >= max_size)
1332 g_object_unref (header);
1333 tny_iterator_next (iter);
1335 g_object_unref (iter);
1339 /* Create the info */
1340 info = g_slice_new0 (GetFullMsgsInfo);
1341 info->mail_op = self;
1342 info->user_callback = user_callback;
1343 info->user_data = user_data;
1344 info->headers = g_object_ref (header_list);
1345 info->notify = notify;
1347 thread = g_thread_create (get_msgs_full_thread, info, FALSE, NULL);
1349 /* FIXME: the error msg is different for pop */
1350 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1351 MODEST_MAIL_OPERATION_ERROR_BAD_PARAMETER,
1352 _("emev_ni_ui_imap_msg_sizelimit_error"));
1353 /* Remove from queue and free resources */
1354 modest_mail_operation_notify_end (self);
1362 modest_mail_operation_remove_msg (ModestMailOperation *self,
1364 gboolean remove_to_trash)
1367 ModestMailOperationPrivate *priv;
1369 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1370 g_return_if_fail (TNY_IS_HEADER (header));
1372 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1373 folder = tny_header_get_folder (header);
1375 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1377 /* Delete or move to trash */
1378 if (remove_to_trash) {
1379 TnyFolder *trash_folder;
1380 TnyStoreAccount *store_account;
1382 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
1383 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
1384 TNY_FOLDER_TYPE_TRASH);
1389 headers = tny_simple_list_new ();
1390 tny_list_append (headers, G_OBJECT (header));
1391 g_object_unref (header);
1394 modest_mail_operation_xfer_msgs (self, headers, trash_folder, TRUE, NULL, NULL);
1395 g_object_unref (headers);
1396 /* g_object_unref (trash_folder); */
1398 ModestMailOperationPrivate *priv;
1400 /* Set status failed and set an error */
1401 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1402 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1403 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1404 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1405 _("Error trying to delete a message. Trash folder not found"));
1408 g_object_unref (G_OBJECT (store_account));
1410 tny_folder_remove_msg (folder, header, &(priv->error));
1412 tny_folder_sync(folder, TRUE, &(priv->error));
1417 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1419 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1422 g_object_unref (G_OBJECT (folder));
1424 /* Notify about operation end */
1425 modest_mail_operation_notify_end (self);
1429 transfer_msgs_status_cb (GObject *obj,
1433 XFerMsgAsyncHelper *helper = NULL;
1434 ModestMailOperation *self;
1435 ModestMailOperationPrivate *priv;
1437 g_return_if_fail (status != NULL);
1438 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_XFER_MSGS);
1440 helper = (XFerMsgAsyncHelper *) user_data;
1441 g_return_if_fail (helper != NULL);
1443 self = helper->mail_op;
1444 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1446 if ((status->position == 1) && (status->of_total == 100))
1449 priv->done = status->position;
1450 priv->total = status->of_total;
1452 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1457 transfer_msgs_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data)
1459 XFerMsgAsyncHelper *helper;
1460 ModestMailOperation *self;
1461 ModestMailOperationPrivate *priv;
1463 helper = (XFerMsgAsyncHelper *) user_data;
1464 self = helper->mail_op;
1466 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
1469 priv->error = g_error_copy (*err);
1471 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1472 } else if (cancelled) {
1473 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1474 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1475 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1476 _("Error trying to refresh the contents of %s"),
1477 tny_folder_get_name (folder));
1480 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1483 /* If user defined callback function was defined, call it */
1484 if (helper->user_callback) {
1485 helper->user_callback (priv->source, helper->user_data);
1489 g_object_unref (helper->headers);
1490 g_object_unref (helper->dest_folder);
1491 g_object_unref (helper->mail_op);
1492 g_slice_free (XFerMsgAsyncHelper, helper);
1493 g_object_unref (folder);
1495 /* Notify about operation end */
1496 modest_mail_operation_notify_end (self);
1500 modest_mail_operation_xfer_msgs (ModestMailOperation *self,
1503 gboolean delete_original,
1504 XferMsgsAsynUserCallback user_callback,
1507 ModestMailOperationPrivate *priv;
1509 TnyFolder *src_folder;
1510 XFerMsgAsyncHelper *helper;
1512 ModestTnyFolderRules rules;
1514 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
1515 g_return_if_fail (TNY_IS_LIST (headers));
1516 g_return_if_fail (TNY_IS_FOLDER (folder));
1518 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1521 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1523 /* Apply folder rules */
1524 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder));
1526 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
1527 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1528 MODEST_MAIL_OPERATION_ERROR_FOLDER_RULES,
1529 _("FIXME: folder does not accept msgs"));
1530 /* Notify the queue */
1531 modest_mail_operation_notify_end (self);
1535 /* Create the helper */
1536 helper = g_slice_new0 (XFerMsgAsyncHelper);
1537 helper->mail_op = g_object_ref(self);
1538 helper->dest_folder = g_object_ref(folder);
1539 helper->headers = g_object_ref(headers);
1540 helper->user_callback = user_callback;
1541 helper->user_data = user_data;
1543 /* Get source folder */
1544 iter = tny_list_create_iterator (headers);
1545 header = TNY_HEADER (tny_iterator_get_current (iter));
1546 src_folder = tny_header_get_folder (header);
1547 g_object_unref (header);
1548 g_object_unref (iter);
1550 /* Transfer messages */
1551 tny_folder_transfer_msgs_async (src_folder,
1556 transfer_msgs_status_cb,
1562 on_refresh_folder (TnyFolder *folder,
1567 ModestMailOperation *self;
1568 ModestMailOperationPrivate *priv;
1570 self = MODEST_MAIL_OPERATION (user_data);
1571 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1574 priv->error = g_error_copy (*error);
1575 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
1580 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
1581 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
1582 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1583 _("Error trying to refresh the contents of %s"),
1584 tny_folder_get_name (folder));
1588 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
1592 g_object_unref (folder);
1594 /* Notify about operation end */
1595 modest_mail_operation_notify_end (self);
1599 on_refresh_folder_status_update (GObject *obj,
1603 ModestMailOperation *self;
1604 ModestMailOperationPrivate *priv;
1606 g_return_if_fail (status != NULL);
1607 g_return_if_fail (status->code == TNY_FOLDER_STATUS_CODE_REFRESH);
1609 /* Temporary FIX: useful when tinymail send us status
1610 information *after* calling the function callback */
1611 if (!MODEST_IS_MAIL_OPERATION (user_data))
1614 self = MODEST_MAIL_OPERATION (user_data);
1615 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1617 priv->done = status->position;
1618 priv->total = status->of_total;
1620 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1624 modest_mail_operation_refresh_folder (ModestMailOperation *self,
1627 ModestMailOperationPrivate *priv;
1629 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
1631 /* Pick a reference */
1632 g_object_ref (folder);
1634 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
1636 /* Refresh the folder. TODO: tinymail could issue a status
1637 updates before the callback call then this could happen. We
1638 must review the design */
1639 tny_folder_refresh_async (folder,
1641 on_refresh_folder_status_update,
1647 * It's used by the mail operation queue to notify the observers
1648 * attached to that signal that the operation finished. We need to use
1649 * that because tinymail does not give us the progress of a given
1650 * operation when it finishes (it directly calls the operation
1654 modest_mail_operation_notify_end (ModestMailOperation *self)
1656 /* Notify the observers about the mail opertation end */
1657 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
1659 /* Notify the queue */
1660 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), self);