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 <camel/camel-stream-mem.h>
41 #include <glib/gi18n.h>
42 #include <modest-tny-account.h>
43 #include <modest-tny-send-queue.h>
44 #include <modest-runtime.h>
45 #include "modest-text-utils.h"
46 #include "modest-tny-msg.h"
47 #include "modest-tny-platform-factory.h"
48 #include "modest-marshal.h"
49 #include "modest-formatter.h"
50 #include "modest-error.h"
52 /* 'private'/'protected' functions */
53 static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
54 static void modest_mail_operation_init (ModestMailOperation *obj);
55 static void modest_mail_operation_finalize (GObject *obj);
57 static void status_update_cb (TnyFolder *folder,
62 static void folder_refresh_cb (TnyFolder *folder,
66 static void update_folders_cb (TnyFolderStore *self,
70 static void add_attachments (TnyMsg *msg,
71 GList *attachments_list);
73 static void modest_mail_operation_xfer_folder (ModestMailOperation *self,
75 TnyFolderStore *parent,
76 gboolean delete_original);
78 static gboolean modest_mail_operation_xfer_msg (ModestMailOperation *self,
81 gboolean delete_original);
83 enum _ModestMailOperationSignals
85 PROGRESS_CHANGED_SIGNAL,
90 typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate;
91 struct _ModestMailOperationPrivate {
94 ModestMailOperationStatus status;
98 #define MODEST_MAIL_OPERATION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
99 MODEST_TYPE_MAIL_OPERATION, \
100 ModestMailOperationPrivate))
102 #define CHECK_EXCEPTION(priv, new_status, op) if (priv->error) {\
103 priv->status = new_status;\
107 typedef struct _RefreshFolderAsyncHelper
109 ModestMailOperation *mail_op;
114 } RefreshFolderAsyncHelper;
117 static GObjectClass *parent_class = NULL;
119 static guint signals[NUM_SIGNALS] = {0};
122 modest_mail_operation_get_type (void)
124 static GType my_type = 0;
126 static const GTypeInfo my_info = {
127 sizeof(ModestMailOperationClass),
128 NULL, /* base init */
129 NULL, /* base finalize */
130 (GClassInitFunc) modest_mail_operation_class_init,
131 NULL, /* class finalize */
132 NULL, /* class data */
133 sizeof(ModestMailOperation),
135 (GInstanceInitFunc) modest_mail_operation_init,
138 my_type = g_type_register_static (G_TYPE_OBJECT,
139 "ModestMailOperation",
146 modest_mail_operation_class_init (ModestMailOperationClass *klass)
148 GObjectClass *gobject_class;
149 gobject_class = (GObjectClass*) klass;
151 parent_class = g_type_class_peek_parent (klass);
152 gobject_class->finalize = modest_mail_operation_finalize;
154 g_type_class_add_private (gobject_class, sizeof(ModestMailOperationPrivate));
157 * ModestMailOperation::progress-changed
158 * @self: the #MailOperation that emits the signal
159 * @user_data: user data set when the signal handler was connected
161 * Emitted when the progress of a mail operation changes
163 signals[PROGRESS_CHANGED_SIGNAL] =
164 g_signal_new ("progress_changed",
165 G_TYPE_FROM_CLASS (gobject_class),
167 G_STRUCT_OFFSET (ModestMailOperationClass, progress_changed),
169 g_cclosure_marshal_VOID__VOID,
174 modest_mail_operation_init (ModestMailOperation *obj)
176 ModestMailOperationPrivate *priv;
178 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
180 priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID;
187 modest_mail_operation_finalize (GObject *obj)
189 ModestMailOperationPrivate *priv;
191 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj);
194 g_error_free (priv->error);
198 G_OBJECT_CLASS(parent_class)->finalize (obj);
202 modest_mail_operation_new (void)
204 return MODEST_MAIL_OPERATION(g_object_new(MODEST_TYPE_MAIL_OPERATION, NULL));
209 modest_mail_operation_send_mail (ModestMailOperation *self,
210 TnyTransportAccount *transport_account,
213 TnySendQueue *send_queue;
215 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
216 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
218 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
219 if (!TNY_IS_SEND_QUEUE(send_queue))
220 g_printerr ("modest: could not find send queue for account\n");
222 tny_send_queue_add (send_queue, msg);
226 modest_mail_operation_send_new_mail (ModestMailOperation *self,
227 TnyTransportAccount *transport_account,
228 const gchar *from, const gchar *to,
229 const gchar *cc, const gchar *bcc,
230 const gchar *subject, const gchar *body,
231 const GList *attachments_list)
234 ModestMailOperationPrivate *priv = NULL;
236 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
237 g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
239 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
241 /* Check parametters */
243 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
244 MODEST_MAIL_OPERATION_ERROR_MISSING_PARAMETER,
245 _("Error trying to send a mail. You need to set at least one recipient"));
249 new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, body, NULL); /* FIXME: attachments */
251 g_printerr ("modest: failed to create a new msg\n");
255 modest_mail_operation_send_mail (self, transport_account, new_msg);
257 g_object_unref (G_OBJECT(new_msg));
261 add_if_attachment (gpointer data, gpointer user_data)
264 GList *attachments_list;
266 part = TNY_MIME_PART (data);
267 attachments_list = (GList *) user_data;
269 if (tny_mime_part_is_attachment (part))
270 attachments_list = g_list_prepend (attachments_list, part);
275 create_reply_forward_mail (TnyMsg *msg, const gchar *from, gboolean is_reply, guint type)
277 TnyPlatformFactory *fact;
279 TnyHeader *new_header, *header;
282 ModestFormatter *formatter;
284 /* Get body from original msg. Always look for the text/plain
285 part of the message to create the reply/forwarded mail */
286 header = tny_msg_get_header (msg);
287 body = modest_tny_msg_find_body_part (msg, FALSE);
289 /* TODO: select the formatter from account prefs */
290 formatter = modest_formatter_new ("text/plain");
292 /* Format message body */
295 case MODEST_MAIL_OPERATION_REPLY_TYPE_CITE:
297 new_msg = modest_formatter_cite (formatter, body, header);
299 case MODEST_MAIL_OPERATION_REPLY_TYPE_QUOTE:
300 new_msg = modest_formatter_quote (formatter, body, header);
305 case MODEST_MAIL_OPERATION_FORWARD_TYPE_INLINE:
307 new_msg = modest_formatter_inline (formatter, body, header);
309 case MODEST_MAIL_OPERATION_FORWARD_TYPE_ATTACHMENT:
310 new_msg = modest_formatter_attach (formatter, body, header);
314 g_object_unref (G_OBJECT(formatter));
315 g_object_unref (G_OBJECT(body));
317 /* Fill the header */
318 fact = modest_tny_platform_factory_get_instance ();
319 new_header = TNY_HEADER (tny_platform_factory_new_header (fact));
320 tny_msg_set_header (new_msg, new_header);
321 tny_header_set_from (new_header, from);
322 tny_header_set_replyto (new_header, from);
324 /* Change the subject */
326 (gchar *) modest_text_utils_derived_subject (tny_header_get_subject(header),
327 (is_reply) ? _("Re:") : _("Fwd:"));
328 tny_header_set_subject (new_header, (const gchar *) new_subject);
329 g_free (new_subject);
332 g_object_unref (G_OBJECT (new_header));
333 g_object_unref (G_OBJECT (header));
339 modest_mail_operation_create_forward_mail (TnyMsg *msg,
341 ModestMailOperationForwardType forward_type)
344 TnyList *parts = NULL;
345 GList *attachments_list = NULL;
347 new_msg = create_reply_forward_mail (msg, from, FALSE, forward_type);
349 /* Add attachments */
350 parts = TNY_LIST (tny_simple_list_new());
351 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
352 tny_list_foreach (parts, add_if_attachment, attachments_list);
353 add_attachments (new_msg, attachments_list);
356 if (attachments_list)
357 g_list_free (attachments_list);
358 g_object_unref (G_OBJECT (parts));
364 modest_mail_operation_create_reply_mail (TnyMsg *msg,
366 ModestMailOperationReplyType reply_type,
367 ModestMailOperationReplyMode reply_mode)
369 TnyMsg *new_msg = NULL;
370 TnyHeader *new_header, *header;
371 const gchar* reply_to;
372 gchar *new_cc = NULL;
373 const gchar *cc = NULL, *bcc = NULL;
376 new_msg = create_reply_forward_mail (msg, from, TRUE, reply_type);
378 /* Fill the header */
379 header = tny_msg_get_header (msg);
380 new_header = tny_msg_get_header (new_msg);
381 reply_to = tny_header_get_replyto (header);
384 tny_header_set_to (new_header, reply_to);
386 tny_header_set_to (new_header, tny_header_get_from (header));
388 switch (reply_mode) {
389 case MODEST_MAIL_OPERATION_REPLY_MODE_SENDER:
390 /* Do not fill neither cc nor bcc */
392 case MODEST_MAIL_OPERATION_REPLY_MODE_LIST:
395 case MODEST_MAIL_OPERATION_REPLY_MODE_ALL:
396 /* Concatenate to, cc and bcc */
397 cc = tny_header_get_cc (header);
398 bcc = tny_header_get_bcc (header);
400 tmp = g_string_new (tny_header_get_to (header));
401 if (cc) g_string_append_printf (tmp, ",%s",cc);
402 if (bcc) g_string_append_printf (tmp, ",%s",bcc);
404 /* Remove my own address from the cc list. TODO:
405 remove also the To: of the new message, needed due
406 to the new reply_to feature */
408 modest_text_utils_remove_address ((const gchar *) tmp->str,
410 /* FIXME: remove also the mails from the new To: */
411 tny_header_set_cc (new_header, new_cc);
414 g_string_free (tmp, TRUE);
420 g_object_unref (G_OBJECT (new_header));
421 g_object_unref (G_OBJECT (header));
427 status_update_cb (TnyFolder *folder, const gchar *what, gint status, gint oftotal, gpointer user_data)
429 g_print ("%s status: %d, of total %d\n", what, status, oftotal);
433 folder_refresh_cb (TnyFolder *folder, gboolean canceled, GError **err, gpointer user_data)
435 ModestMailOperation *self = NULL;
436 ModestMailOperationPrivate *priv = NULL;
437 RefreshFolderAsyncHelper *helper;
439 helper = (RefreshFolderAsyncHelper *) user_data;
440 self = MODEST_MAIL_OPERATION (helper->mail_op);
441 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
443 if ((canceled && *err) || *err) {
444 priv->error = g_error_copy (*err);
446 } else if (canceled) {
448 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
449 MODEST_MAIL_OPERATION_ERROR_OPERATION_CANCELED,
450 _("Error trying to refresh folder %s. Operation canceled"),
451 tny_folder_get_name (folder));
456 if (priv->done == priv->total)
457 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
458 else if ((priv->done + helper->canceled + helper->failed) == priv->total) {
459 if (helper->failed == priv->total)
460 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
461 else if (helper->failed == priv->total)
462 priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELED;
464 priv->status = MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS;
466 tny_iterator_next (helper->iter);
467 if (tny_iterator_is_done (helper->iter)) {
469 list = tny_iterator_get_list (helper->iter);
470 g_object_unref (G_OBJECT (helper->iter));
471 g_object_unref (G_OBJECT (list));
472 g_slice_free (RefreshFolderAsyncHelper, helper);
474 TnyFolder *folder = TNY_FOLDER (tny_iterator_get_current (helper->iter));
475 tny_folder_refresh_async (folder, folder_refresh_cb,
478 g_object_unref (G_OBJECT(folder));
480 g_signal_emit (G_OBJECT (self), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
485 update_folders_cb (TnyFolderStore *folder_store, TnyList *list, GError **err, gpointer user_data)
487 ModestMailOperation *self;
488 ModestMailOperationPrivate *priv;
489 RefreshFolderAsyncHelper *helper;
492 self = MODEST_MAIL_OPERATION (user_data);
493 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
496 priv->error = g_error_copy (*err);
497 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
501 priv->total = tny_list_get_length (list);
503 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
505 helper = g_slice_new0 (RefreshFolderAsyncHelper);
506 helper->mail_op = self;
507 helper->iter = tny_list_create_iterator (list);
509 helper->canceled = 0;
511 /* Async refresh folders */
512 folder = TNY_FOLDER (tny_iterator_get_current (helper->iter));
513 tny_folder_refresh_async (folder, folder_refresh_cb,
514 status_update_cb, helper);
515 g_object_unref (G_OBJECT(folder));
519 modest_mail_operation_update_account (ModestMailOperation *self,
520 TnyStoreAccount *store_account)
522 ModestMailOperationPrivate *priv;
524 TnyFolderStoreQuery *query;
526 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
527 g_return_val_if_fail (TNY_IS_STORE_ACCOUNT(store_account), FALSE);
529 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
531 /* Get subscribed folders & refresh them */
532 folders = TNY_LIST (tny_simple_list_new ());
533 query = tny_folder_store_query_new ();
534 tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
535 tny_folder_store_get_folders_async (TNY_FOLDER_STORE (store_account),
536 folders, update_folders_cb, query, self);
537 g_object_unref (query);
542 ModestMailOperationStatus
543 modest_mail_operation_get_status (ModestMailOperation *self)
545 ModestMailOperationPrivate *priv;
547 g_return_val_if_fail (self, MODEST_MAIL_OPERATION_STATUS_INVALID);
548 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self),
549 MODEST_MAIL_OPERATION_STATUS_INVALID);
551 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
556 modest_mail_operation_get_error (ModestMailOperation *self)
558 ModestMailOperationPrivate *priv;
560 g_return_val_if_fail (self, NULL);
561 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
563 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
568 modest_mail_operation_cancel (ModestMailOperation *self)
575 modest_mail_operation_get_task_done (ModestMailOperation *self)
577 ModestMailOperationPrivate *priv;
579 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
581 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
586 modest_mail_operation_get_task_total (ModestMailOperation *self)
588 ModestMailOperationPrivate *priv;
590 g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), 0);
592 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
597 modest_mail_operation_is_finished (ModestMailOperation *self)
599 ModestMailOperationPrivate *priv;
600 gboolean retval = FALSE;
602 if (!MODEST_IS_MAIL_OPERATION (self)) {
603 g_warning ("%s: invalid parametter", G_GNUC_FUNCTION);
607 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
609 if (priv->status == MODEST_MAIL_OPERATION_STATUS_SUCCESS ||
610 priv->status == MODEST_MAIL_OPERATION_STATUS_FAILED ||
611 priv->status == MODEST_MAIL_OPERATION_STATUS_CANCELED ||
612 priv->status == MODEST_MAIL_OPERATION_STATUS_FINISHED_WITH_ERRORS) {
621 /* ******************************************************************* */
622 /* ************************** STORE ACTIONS ************************* */
623 /* ******************************************************************* */
627 modest_mail_operation_create_folder (ModestMailOperation *self,
628 TnyFolderStore *parent,
631 ModestMailOperationPrivate *priv;
632 TnyFolder *new_folder = NULL;
633 TnyStoreAccount *store_account;
635 g_return_val_if_fail (TNY_IS_FOLDER_STORE (parent), NULL);
636 g_return_val_if_fail (name, NULL);
638 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
640 /* Create the folder */
641 new_folder = tny_folder_store_create_folder (parent, name, &(priv->error));
642 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, return NULL);
644 /* Subscribe to folder */
645 if (!tny_folder_is_subscribed (new_folder)) {
646 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (TNY_FOLDER (parent)));
647 tny_store_account_subscribe (store_account, new_folder);
648 g_object_unref (G_OBJECT (store_account));
655 modest_mail_operation_remove_folder (ModestMailOperation *self,
657 gboolean remove_to_trash)
659 TnyFolderStore *folder_store;
661 g_return_if_fail (TNY_IS_FOLDER (folder));
663 /* Get folder store */
664 folder_store = TNY_FOLDER_STORE (tny_folder_get_account (folder));
666 /* Delete folder or move to trash */
667 if (remove_to_trash) {
668 TnyFolder *trash_folder;
669 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(folder_store),
670 TNY_FOLDER_TYPE_TRASH);
671 /* TODO: error_handling */
672 modest_mail_operation_move_folder (self, folder,
673 TNY_FOLDER_STORE (trash_folder));
675 tny_folder_store_remove_folder (folder_store, folder, NULL); /* FIXME */
676 g_object_unref (G_OBJECT (folder));
680 g_object_unref (G_OBJECT (folder_store));
684 modest_mail_operation_rename_folder (ModestMailOperation *self,
688 ModestMailOperationPrivate *priv;
690 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
691 g_return_if_fail (TNY_IS_FOLDER_STORE (folder));
692 g_return_if_fail (name);
694 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
696 /* FIXME: better error handling */
697 if (strrchr (name, '/') != NULL)
700 /* Rename. Camel handles folder subscription/unsubscription */
701 tny_folder_set_name (folder, name, &(priv->error));
702 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, return);
706 modest_mail_operation_move_folder (ModestMailOperation *self,
708 TnyFolderStore *parent)
710 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
711 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
712 g_return_if_fail (TNY_IS_FOLDER (folder));
714 modest_mail_operation_xfer_folder (self, folder, parent, TRUE);
718 modest_mail_operation_copy_folder (ModestMailOperation *self,
720 TnyFolderStore *parent)
722 g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
723 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
724 g_return_if_fail (TNY_IS_FOLDER (folder));
726 modest_mail_operation_xfer_folder (self, folder, parent, FALSE);
730 modest_mail_operation_xfer_folder (ModestMailOperation *self,
732 TnyFolderStore *parent,
733 gboolean delete_original)
735 ModestMailOperationPrivate *priv;
736 const gchar *folder_name;
737 TnyFolder *dest_folder = NULL, *child = NULL;
738 TnyIterator *iter = NULL;
739 TnyList *folders = NULL, *headers = NULL;
741 g_return_if_fail (TNY_IS_FOLDER (folder));
742 g_return_if_fail (TNY_IS_FOLDER_STORE (parent));
744 priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
746 /* Create the destination folder */
747 folder_name = tny_folder_get_name (folder);
748 dest_folder = modest_mail_operation_create_folder (self, parent, folder_name);
749 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, goto clean);
751 /* Transfer messages */
752 headers = TNY_LIST (tny_simple_list_new ());
753 tny_folder_get_headers (folder, headers, FALSE, &(priv->error));
754 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, goto clean);
756 tny_folder_transfer_msgs (folder, headers, dest_folder, delete_original, &(priv->error));
757 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, goto clean);
759 /* Recurse children */
760 folders = TNY_LIST (tny_simple_list_new ());
761 tny_folder_store_get_folders (TNY_FOLDER_STORE (folder), folders, NULL, &(priv->error));
762 CHECK_EXCEPTION (priv, MODEST_MAIL_OPERATION_STATUS_FAILED, goto clean);
764 iter = tny_list_create_iterator (folders);
765 while (!tny_iterator_is_done (iter)) {
766 child = TNY_FOLDER (tny_iterator_get_current (iter));
767 modest_mail_operation_xfer_folder (self, child, TNY_FOLDER_STORE (dest_folder),
769 tny_iterator_next (iter);
770 g_object_unref (G_OBJECT(child));
773 /* Delete source folder (if needed) */
775 modest_mail_operation_remove_folder (self, folder, FALSE);
780 g_object_unref (G_OBJECT (dest_folder));
782 g_object_unref (G_OBJECT (headers));
784 g_object_unref (G_OBJECT (folders));
786 g_object_unref (G_OBJECT (iter));
790 /* ******************************************************************* */
791 /* ************************** MSG ACTIONS ************************* */
792 /* ******************************************************************* */
795 modest_mail_operation_copy_msg (ModestMailOperation *self,
799 g_return_val_if_fail (TNY_IS_HEADER (header), FALSE);
800 g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE);
802 return modest_mail_operation_xfer_msg (self, header, folder, FALSE);
806 modest_mail_operation_move_msg (ModestMailOperation *self,
810 g_return_val_if_fail (TNY_IS_HEADER (header), FALSE);
811 g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE);
813 return modest_mail_operation_xfer_msg (self, header, folder, TRUE);
817 modest_mail_operation_remove_msg (ModestMailOperation *self,
819 gboolean remove_to_trash)
823 g_return_if_fail (TNY_IS_HEADER (header));
825 folder = tny_header_get_folder (header);
827 /* Delete or move to trash */
828 if (remove_to_trash) {
829 TnyFolder *trash_folder;
830 TnyStoreAccount *store_account;
832 store_account = TNY_STORE_ACCOUNT (tny_folder_get_account (folder));
833 trash_folder = modest_tny_account_get_special_folder (TNY_ACCOUNT(store_account),
834 TNY_FOLDER_TYPE_TRASH);
836 modest_mail_operation_move_msg (self, header, trash_folder);
837 /* g_object_unref (trash_folder); */
839 ModestMailOperationPrivate *priv;
841 /* Set status failed and set an error */
842 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
843 priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
844 g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
845 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
846 _("Error trying to delete a message. Trash folder not found"));
849 g_object_unref (G_OBJECT (store_account));
851 tny_folder_remove_msg (folder, header, NULL); /* FIXME */
852 tny_folder_sync(folder, TRUE, NULL); /* FIXME */
856 g_object_unref (folder);
860 transfer_msgs_cb (TnyFolder *folder, GError **err, gpointer user_data)
862 ModestMailOperationPrivate *priv;
864 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(user_data);
866 priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
868 g_signal_emit (G_OBJECT (user_data), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL);
872 modest_mail_operation_xfer_msg (ModestMailOperation *self,
875 gboolean delete_original)
877 ModestMailOperationPrivate *priv;
878 TnyFolder *src_folder;
881 src_folder = tny_header_get_folder (header);
882 headers = tny_simple_list_new ();
884 priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
887 priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
889 tny_list_prepend (headers, G_OBJECT (header));
890 tny_folder_transfer_msgs_async (src_folder, headers, folder,
891 delete_original, transfer_msgs_cb, self);
894 g_object_unref (headers);
895 g_object_unref (folder);
901 /* ******************************************************************* */
902 /* ************************* UTILIY FUNCTIONS ************************ */
903 /* ******************************************************************* */
906 add_attachments (TnyMsg *msg, GList *attachments_list)
909 TnyMimePart *attachment_part, *old_attachment;
910 const gchar *attachment_content_type;
911 const gchar *attachment_filename;
912 TnyStream *attachment_stream;
913 TnyPlatformFactory *fact;
915 fact = modest_tny_platform_factory_get_instance ();
916 for (pos = (GList *)attachments_list; pos; pos = pos->next) {
918 old_attachment = pos->data;
919 attachment_filename = tny_mime_part_get_filename (old_attachment);
920 attachment_stream = tny_mime_part_get_stream (old_attachment);
921 attachment_part = tny_platform_factory_new_mime_part (fact);
923 attachment_content_type = tny_mime_part_get_content_type (old_attachment);
925 tny_mime_part_construct_from_stream (attachment_part,
927 attachment_content_type);
928 tny_stream_reset (attachment_stream);
930 tny_mime_part_set_filename (attachment_part, attachment_filename);
932 tny_mime_part_add_part (TNY_MIME_PART (msg), attachment_part);
933 /* g_object_unref (attachment_part); */