* src/modest-mail-operation.[ch]:
authorJose Dapena Paz <jdapena@igalia.com>
Tue, 10 Jul 2007 16:13:57 +0000 (16:13 +0000)
committerJose Dapena Paz <jdapena@igalia.com>
Tue, 10 Jul 2007 16:13:57 +0000 (16:13 +0000)
        * New mail operation "get_mime_part_size", asynchronous. This
          is used to show the mime part size in attachment view without
          blocking the UI when the size is big enough.
        * New mail operation "create_msg", asynchronous, that contains
          the old work done in save to drafts and send new mail for
          creating a valid TnyMsg instance to send. This is required
          because the operation can take long when the attachments are
          big enough. This operation is private.
        * Now send_new_mail and save_to_drafts use the new "create_msg"
          mail operation to avoid stalling the UI.
* src/widgets/modest-attachment-view.c:
        * Now we use the new mail operation for getting the attachment
          size. This way we don't block on attaching big files or
          from slow folders (as shared folders). We also remove the
          old synchronous implementation.
* src/modest-tny-msg.[ch]:
        * Now the constructors get a GList of attachments, not a (really
          fake) GSList.
* src/modest-ui-actions.c:
        * Now the save to drafts action does not remove the old draft
          itself, as it's now done internally in the mail operation. We
          also provide the edit window.
* src/maemo/modest-msg-edit-window.c:
        * We don't hang looping when there's an error in mime parts.
        * Now we check if the widget is visible on clipboard owner
          handler to prevent crashes on calling the handler after
          destroiying and before finalizing.

pmo-trunk-r2676

src/maemo/modest-msg-edit-window.c
src/modest-mail-operation.c
src/modest-mail-operation.h
src/modest-tny-msg.c
src/modest-tny-msg.h
src/modest-tny-send-queue.c
src/modest-ui-actions.c
src/widgets/modest-attachment-view.c

index da23b5d..503739c 100644 (file)
@@ -1082,6 +1082,7 @@ modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
        while (cursor) {
                if (!(TNY_IS_MIME_PART(cursor->data))) {
                        g_warning ("strange data in attachment list");
        while (cursor) {
                if (!(TNY_IS_MIME_PART(cursor->data))) {
                        g_warning ("strange data in attachment list");
+                       cursor = g_list_next (cursor);
                        continue;
                }
                data->attachments = g_list_append (data->attachments,
                        continue;
                }
                data->attachments = g_list_append (data->attachments,
@@ -2665,6 +2666,9 @@ modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
 
        priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
        parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
 
        priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
        parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
+
+       if (!GTK_WIDGET_VISIBLE (window))
+               return;
        has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
        focused = gtk_window_get_focus (GTK_WINDOW (window));
 
        has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
        focused = gtk_window_get_focus (GTK_WINDOW (window));
 
index 07e85cd..b21a831 100644 (file)
@@ -37,6 +37,7 @@
 #include <tny-camel-pop-store-account.h>
 #include <tny-camel-pop-folder.h>
 #include <tny-camel-imap-folder.h>
 #include <tny-camel-pop-store-account.h>
 #include <tny-camel-pop-folder.h>
 #include <tny-camel-imap-folder.h>
+#include <tny-camel-mem-stream.h>
 #include <tny-simple-list.h>
 #include <tny-send-queue.h>
 #include <tny-status.h>
 #include <tny-simple-list.h>
 #include <tny-send-queue.h>
 #include <tny-status.h>
@@ -56,6 +57,7 @@
 #include "modest-mail-operation.h"
 
 #define KB 1024
 #include "modest-mail-operation.h"
 
 #define KB 1024
+#define GET_SIZE_BUFFER_SIZE 128
 
 /* 'private'/'protected' functions */
 static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
 
 /* 'private'/'protected' functions */
 static void modest_mail_operation_class_init (ModestMailOperationClass *klass);
@@ -127,6 +129,44 @@ typedef struct _XFerMsgAsyncHelper
        gpointer user_data;
 } XFerMsgAsyncHelper;
 
        gpointer user_data;
 } XFerMsgAsyncHelper;
 
+typedef void (*ModestMailOperationCreateMsgCallback) (ModestMailOperation *mail_op,
+                                                     TnyMsg *msg,
+                                                     gpointer userdata);
+
+static void          modest_mail_operation_create_msg (ModestMailOperation *self,
+                                                      const gchar *from, const gchar *to,
+                                                      const gchar *cc, const gchar *bcc,
+                                                      const gchar *subject, const gchar *plain_body,
+                                                      const gchar *html_body, const GList *attachments_list,
+                                                      TnyHeaderFlags priority_flags,
+                                                      ModestMailOperationCreateMsgCallback callback,
+                                                      gpointer userdata);
+
+static gboolean      idle_notify_queue (gpointer data);
+typedef struct
+{
+       ModestMailOperation *mail_op;
+       gchar *from;
+       gchar *to;
+       gchar *cc;
+       gchar *bcc;
+       gchar *subject;
+       gchar *plain_body;
+       gchar *html_body;
+       GList *attachments_list;
+       TnyHeaderFlags priority_flags;
+       ModestMailOperationCreateMsgCallback callback;
+       gpointer userdata;
+} CreateMsgInfo;
+
+typedef struct
+{
+       ModestMailOperation *mail_op;
+       TnyMsg *msg;
+       ModestMailOperationCreateMsgCallback callback;
+       gpointer userdata;
+} CreateMsgIdleInfo;
+
 /* globals */
 static GObjectClass *parent_class = NULL;
 
 /* globals */
 static GObjectClass *parent_class = NULL;
 
@@ -527,6 +567,165 @@ modest_mail_operation_send_mail (ModestMailOperation *self,
        modest_mail_operation_notify_end (self);
 }
 
        modest_mail_operation_notify_end (self);
 }
 
+static gboolean
+idle_create_msg_cb (gpointer idle_data)
+{
+       CreateMsgIdleInfo *info = (CreateMsgIdleInfo *) idle_data;
+
+       gdk_threads_enter ();
+       info->callback (info->mail_op, info->msg, info->userdata);
+       gdk_threads_leave ();
+       g_object_unref (info->mail_op);
+       if (info->msg)
+               g_object_unref (info->msg);
+       g_slice_free (CreateMsgIdleInfo, info);
+
+       return FALSE;
+}
+
+static gpointer 
+create_msg_thread (gpointer thread_data)
+{
+       CreateMsgInfo *info = (CreateMsgInfo *) thread_data;
+       TnyMsg *new_msg = NULL;
+       ModestMailOperationPrivate *priv;
+
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
+       if (info->html_body == NULL) {
+               new_msg = modest_tny_msg_new (info->to, info->from, info->cc, 
+                                             info->bcc, info->subject, info->plain_body, 
+                                             info->attachments_list); /* FIXME: attachments */
+       } else {
+               new_msg = modest_tny_msg_new_html_plain (info->to, info->from, info->cc,
+                                                        info->bcc, info->subject, info->html_body,
+                                                        info->plain_body, info->attachments_list);
+       }
+
+       if (new_msg) {
+               TnyHeader *header;
+               /* Set priority flags in message */
+               header = tny_msg_get_header (new_msg);
+               if (info->priority_flags != 0)
+                       tny_header_set_flags (header, info->priority_flags);
+               if (info->attachments_list != NULL) {
+                       tny_header_set_flags (header, TNY_HEADER_FLAG_ATTACHMENTS);
+               }
+               g_object_unref (G_OBJECT(header));
+       } else {
+               priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+               g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
+                            MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED,
+                            "modest: failed to create a new msg\n");
+       }
+
+
+       g_free (info->to);
+       g_free (info->from);
+       g_free (info->cc);
+       g_free (info->bcc);
+       g_free (info->plain_body);
+       g_free (info->html_body);
+       g_free (info->subject);
+       g_list_foreach (info->attachments_list, (GFunc) g_object_unref, NULL);
+       g_list_free (info->attachments_list);
+
+       if (info->callback) {
+               CreateMsgIdleInfo *idle_info;
+               idle_info = g_slice_new0 (CreateMsgIdleInfo);
+               idle_info->mail_op = info->mail_op;
+               g_object_ref (info->mail_op);
+               idle_info->msg = new_msg;
+               if (new_msg)
+                       g_object_ref (new_msg);
+               idle_info->callback = info->callback;
+               idle_info->userdata = info->userdata;
+               g_idle_add (idle_create_msg_cb, idle_info);
+       } else {
+               g_idle_add (idle_notify_queue, g_object_ref (info->mail_op));
+       }
+
+       g_object_unref (info->mail_op);
+       g_slice_free (CreateMsgInfo, info);
+       return NULL;
+}
+
+void
+modest_mail_operation_create_msg (ModestMailOperation *self,
+                                 const gchar *from, const gchar *to,
+                                 const gchar *cc, const gchar *bcc,
+                                 const gchar *subject, const gchar *plain_body,
+                                 const gchar *html_body,
+                                 const GList *attachments_list,
+                                 TnyHeaderFlags priority_flags,
+                                 ModestMailOperationCreateMsgCallback callback,
+                                 gpointer userdata)
+{
+       CreateMsgInfo *info = NULL;
+
+       info = g_slice_new0 (CreateMsgInfo);
+       info->mail_op = self;
+       g_object_ref (self);
+
+       info->from = g_strdup (from);
+       info->to = g_strdup (to);
+       info->cc = g_strdup (cc);
+       info->subject = g_strdup (subject);
+       info->plain_body = g_strdup (plain_body);
+       info->html_body = g_strdup (html_body);
+       info->attachments_list = g_list_copy ((GList *) attachments_list);
+       g_list_foreach (info->attachments_list, (GFunc) g_object_ref, NULL);
+       info->priority_flags = priority_flags;
+
+       info->callback = callback;
+       info->userdata = userdata;
+
+       g_thread_create (create_msg_thread, info, FALSE, NULL);
+}
+
+typedef struct
+{
+       TnyTransportAccount *transport_account;
+       TnyMsg *draft_msg;
+} SendNewMailInfo;
+
+static void
+modest_mail_operation_send_new_mail_cb (ModestMailOperation *self,
+                                       TnyMsg *msg,
+                                       gpointer userdata)
+{
+       SendNewMailInfo *info = (SendNewMailInfo *) userdata;
+       TnyFolder *folder;
+       TnyHeader *header;
+
+       if (!msg) {
+               goto end;
+       }
+
+       /* Call mail operation */
+       modest_mail_operation_send_mail (self, info->transport_account, msg);
+
+       folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_DRAFTS);
+       if (folder) {
+               if (info->draft_msg != NULL) {
+                       header = tny_msg_get_header (info->draft_msg);
+                       /* Note: This can fail (with a warning) if the message is not really already in a folder,
+                        * because this function requires it to have a UID. */
+                       tny_folder_remove_msg (folder, header, NULL);
+                       tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED);
+                       tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
+                       g_object_unref (header);
+               }
+       }
+
+end:
+       if (info->draft_msg)
+               g_object_unref (info->draft_msg);
+       if (info->transport_account)
+               g_object_unref (info->transport_account);
+       g_slice_free (SendNewMailInfo, info);
+       modest_mail_operation_notify_end (self);
+}
+
 void
 modest_mail_operation_send_new_mail (ModestMailOperation *self,
                                     TnyTransportAccount *transport_account,
 void
 modest_mail_operation_send_new_mail (ModestMailOperation *self,
                                     TnyTransportAccount *transport_account,
@@ -538,10 +737,8 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
                                     const GList *attachments_list,
                                     TnyHeaderFlags priority_flags)
 {
                                     const GList *attachments_list,
                                     TnyHeaderFlags priority_flags)
 {
-       TnyMsg *new_msg = NULL;
-       TnyFolder *folder = NULL;
-       TnyHeader *header = NULL;
        ModestMailOperationPrivate *priv = NULL;
        ModestMailOperationPrivate *priv = NULL;
+       SendNewMailInfo *info;
 
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
 
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
@@ -557,75 +754,37 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
                             _("Error trying to send a mail. You need to set at least one recipient"));
                return;
        }
                             _("Error trying to send a mail. You need to set at least one recipient"));
                return;
        }
+       info = g_slice_new0 (SendNewMailInfo);
+       info->transport_account = transport_account;
+       if (transport_account)
+               g_object_ref (transport_account);
+       info->draft_msg = draft_msg;
+       if (draft_msg)
+               g_object_ref (draft_msg);
+       modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body,
+                                         attachments_list, priority_flags,
+                                         modest_mail_operation_send_new_mail_cb, info);
 
 
-       if (html_body == NULL) {
-               new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
-       } else {
-               new_msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
-       }
-       if (!new_msg) {
-               g_printerr ("modest: failed to create a new msg\n");
-               return;
-       }
-
-       /* Set priority flags in message */
-       header = tny_msg_get_header (new_msg);
-       if (priority_flags != 0)
-               tny_header_set_flags (header, priority_flags);
-       if (attachments_list != NULL) {
-               tny_header_set_flags (header, TNY_HEADER_FLAG_ATTACHMENTS);
-       }
-       g_object_unref (G_OBJECT(header));
-
-       /* Call mail operation */
-       modest_mail_operation_send_mail (self, transport_account, new_msg);
-
-       folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
-       if (folder) {
-               if (draft_msg != NULL) {
-                       header = tny_msg_get_header (draft_msg);
-                       /* Note: This can fail (with a warning) if the message is not really already in a folder,
-                        * because this function requires it to have a UID. */
-                       tny_folder_remove_msg (folder, header, NULL);
-                       tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED);
-                       tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
-                       g_object_unref (header);
-               }
-       }
-
-       /* Free */
-       g_object_unref (G_OBJECT (new_msg));
 }
 
 }
 
-TnyMsg*
-modest_mail_operation_save_to_drafts (ModestMailOperation *self,
-                                     TnyTransportAccount *transport_account,
-                                     TnyMsg *draft_msg,
-                                     const gchar *from,  const gchar *to,
-                                     const gchar *cc,  const gchar *bcc,
-                                     const gchar *subject, const gchar *plain_body,
-                                     const gchar *html_body,
-                                     const GList *attachments_list,
-                                     TnyHeaderFlags priority_flags)
+typedef struct
+{
+       TnyTransportAccount *transport_account;
+       TnyMsg *draft_msg;
+       ModestMsgEditWindow *edit_window;
+} SaveToDraftsInfo;
+
+static void
+modest_mail_operation_save_to_drafts_cb (ModestMailOperation *self,
+                                        TnyMsg *msg,
+                                        gpointer userdata)
 {
 {
-       TnyMsg *msg = NULL;
        TnyFolder *folder = NULL;
        TnyHeader *header = NULL;
        ModestMailOperationPrivate *priv = NULL;
        TnyFolder *folder = NULL;
        TnyHeader *header = NULL;
        ModestMailOperationPrivate *priv = NULL;
-
-       g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), NULL);
-       g_return_val_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account), NULL);
+       SaveToDraftsInfo *info = (SaveToDraftsInfo *) userdata;
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
 
        priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
-
-       /* Get account and set it into mail_operation */
-       priv->account = g_object_ref (transport_account);
-
-       if (html_body == NULL) {
-               msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
-       } else {
-               msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
-       }
        if (!msg) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
        if (!msg) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
@@ -634,14 +793,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self,
                goto end;
        }
 
                goto end;
        }
 
-       /* add priority flags */
-       header = tny_msg_get_header (msg);
-       tny_header_set_flags (header, priority_flags);
-       if (attachments_list != NULL)
-               tny_header_set_flags (header, TNY_HEADER_FLAG_ATTACHMENTS);
-       g_object_unref (G_OBJECT(header));
-
-       folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (transport_account), TNY_FOLDER_TYPE_DRAFTS);
+       folder = modest_tny_account_get_special_folder (TNY_ACCOUNT (info->transport_account), TNY_FOLDER_TYPE_DRAFTS);
        if (!folder) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
        if (!folder) {
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
                g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
@@ -650,8 +802,8 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self,
                goto end;
        }
 
                goto end;
        }
 
-       if (draft_msg != NULL) {
-               header = tny_msg_get_header (draft_msg);
+       if (info->draft_msg != NULL) {
+               header = tny_msg_get_header (info->draft_msg);
                /* Remove the old draft expunging it */
                tny_folder_remove_msg (folder, header, NULL);
                tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED);
                /* Remove the old draft expunging it */
                tny_folder_remove_msg (folder, header, NULL);
                tny_header_set_flags (header, TNY_HEADER_FLAG_DELETED);
@@ -668,12 +820,60 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self,
        else
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
 
        else
                priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
 
+       if (info->edit_window)
+               modest_msg_edit_window_set_draft (info->edit_window, msg);
+
+
 end:
        if (folder)
                g_object_unref (G_OBJECT(folder));
 end:
        if (folder)
                g_object_unref (G_OBJECT(folder));
+       if (info->edit_window)
+               g_object_unref (G_OBJECT(info->edit_window));
+       if (info->draft_msg)
+               g_object_unref (G_OBJECT (info->draft_msg));
+       if (info->transport_account)
+               g_object_unref (G_OBJECT(info->transport_account));
+       g_slice_free (SaveToDraftsInfo, info);
 
        modest_mail_operation_notify_end (self);
 
        modest_mail_operation_notify_end (self);
-       return msg;
+}
+
+void
+modest_mail_operation_save_to_drafts (ModestMailOperation *self,
+                                     TnyTransportAccount *transport_account,
+                                     TnyMsg *draft_msg,
+                                     ModestMsgEditWindow *edit_window,
+                                     const gchar *from,  const gchar *to,
+                                     const gchar *cc,  const gchar *bcc,
+                                     const gchar *subject, const gchar *plain_body,
+                                     const gchar *html_body,
+                                     const GList *attachments_list,
+                                     TnyHeaderFlags priority_flags)
+{
+       ModestMailOperationPrivate *priv = NULL;
+       SaveToDraftsInfo *info = NULL;
+
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
+
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self);
+
+       /* Get account and set it into mail_operation */
+       priv->account = g_object_ref (transport_account);
+
+       info = g_slice_new0 (SaveToDraftsInfo);
+       info->transport_account = g_object_ref (transport_account);
+       info->draft_msg = draft_msg;
+       if (draft_msg)
+               g_object_ref (draft_msg);
+       info->edit_window = edit_window;
+       if (edit_window)
+               g_object_ref (edit_window);
+
+       modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body,
+                                         attachments_list, priority_flags,
+                                         modest_mail_operation_save_to_drafts_cb, info);
+
 }
 
 typedef struct 
 }
 
 typedef struct 
@@ -690,6 +890,15 @@ typedef struct
        gint new_headers;
 } UpdateAccountInfo;
 
        gint new_headers;
 } UpdateAccountInfo;
 
+typedef struct
+{
+       ModestMailOperation *mail_op;
+       TnyMimePart *mime_part;
+       gssize size;
+       GetMimePartSizeCallback callback;
+       gpointer userdata;
+} GetMimePartSizeInfo;
+
 /***** I N T E R N A L    F O L D E R    O B S E R V E R *****/
 /* We use this folder observer to track the headers that have been
  * added to a folder */
 /***** I N T E R N A L    F O L D E R    O B S E R V E R *****/
 /* We use this folder observer to track the headers that have been
  * added to a folder */
@@ -836,16 +1045,13 @@ idle_notify_progress_once (gpointer data)
 }
 
 /* 
 }
 
 /* 
- * Used by update_account_thread to notify the queue from the main
+ * Used to notify the queue from the main
  * loop. We call it inside an idle call to achieve that
  */
 static gboolean
  * loop. We call it inside an idle call to achieve that
  */
 static gboolean
-idle_notify_update_account_queue (gpointer data)
+idle_notify_queue (gpointer data)
 {
        ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
 {
        ModestMailOperation *mail_op = MODEST_MAIL_OPERATION (data);
-       ModestMailOperationPrivate *priv = NULL;
-
-       priv = MODEST_MAIL_OPERATION_GET_PRIVATE(mail_op);
 
        /* Do not need to block, the notify end will do it for us */    
        modest_mail_operation_notify_end (mail_op);
 
        /* Do not need to block, the notify end will do it for us */    
        modest_mail_operation_notify_end (mail_op);
@@ -1138,7 +1344,7 @@ update_account_thread (gpointer thr_user_data)
        /* Notify about operation end. Note that the info could be
           freed before this idle happens, but the mail operation will
           be still alive */
        /* Notify about operation end. Note that the info could be
           freed before this idle happens, but the mail operation will
           be still alive */
-       g_idle_add (idle_notify_update_account_queue, g_object_ref (info->mail_op));
+       g_idle_add (idle_notify_queue, g_object_ref (info->mail_op));
 
        /* Frees */
        g_object_unref (query);
 
        /* Frees */
        g_object_unref (query);
@@ -1622,6 +1828,99 @@ void modest_mail_operation_get_msg (ModestMailOperation *self,
        }
 }
 
        }
 }
 
+static gboolean
+idle_get_mime_part_size_cb (gpointer userdata)
+{
+       GetMimePartSizeInfo *idle_info;
+
+       idle_info = (GetMimePartSizeInfo *) userdata;
+
+       gdk_threads_enter ();
+       idle_info->callback (idle_info->mail_op,
+                            idle_info->size,
+                            idle_info->userdata);
+       gdk_threads_leave ();
+
+       g_object_unref (idle_info->mail_op);
+       g_slice_free (GetMimePartSizeInfo, idle_info);
+
+       return FALSE;
+}
+
+static gpointer
+get_mime_part_size_thread (gpointer thr_user_data)
+{
+       GetMimePartSizeInfo *info;
+       gchar read_buffer[GET_SIZE_BUFFER_SIZE];
+       TnyStream *stream;
+       gssize readed_size;
+       gssize total = 0;
+       ModestMailOperationPrivate *priv;
+
+       info = (GetMimePartSizeInfo *) thr_user_data;
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (info->mail_op);
+
+       stream = tny_camel_mem_stream_new ();
+       tny_mime_part_decode_to_stream (info->mime_part, stream);
+       tny_stream_reset (stream);
+       if (tny_stream_is_eos (stream)) {
+               tny_stream_close (stream);
+               stream = tny_mime_part_get_stream (info->mime_part);
+       }
+       
+       while (!tny_stream_is_eos (stream)) {
+               readed_size = tny_stream_read (stream, read_buffer, GET_SIZE_BUFFER_SIZE);
+               total += readed_size;
+       }
+
+       if (info->callback) {
+               GetMimePartSizeInfo *idle_info;
+
+               idle_info = g_slice_new0 (GetMimePartSizeInfo);
+               idle_info->mail_op = g_object_ref (info->mail_op);
+               idle_info->size = total;
+               idle_info->callback = info->callback;
+               idle_info->userdata = info->userdata;
+               g_idle_add (idle_get_mime_part_size_cb, idle_info);
+       }
+
+       g_idle_add (idle_notify_queue, g_object_ref (info->mail_op));
+
+       g_object_unref (info->mail_op);
+       g_object_unref (stream);
+       g_object_unref (info->mime_part);
+       g_slice_free  (GetMimePartSizeInfo, info);
+
+       return NULL;
+}
+
+void          
+modest_mail_operation_get_mime_part_size (ModestMailOperation *self,
+                                         TnyMimePart *part,
+                                         GetMimePartSizeCallback user_callback,
+                                         gpointer user_data,
+                                         GDestroyNotify notify)
+{
+       GetMimePartSizeInfo *info;
+       ModestMailOperationPrivate *priv;
+       GThread *thread;
+       
+       g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
+       g_return_if_fail (TNY_IS_MIME_PART (part));
+       
+       priv = MODEST_MAIL_OPERATION_GET_PRIVATE (self);
+
+       priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
+       info = g_slice_new0 (GetMimePartSizeInfo);
+       info->mail_op = g_object_ref (self);
+       info->mime_part = g_object_ref (part);
+       info->callback = user_callback;
+       info->userdata = user_data;
+
+       thread = g_thread_create (get_mime_part_size_thread, info, FALSE, NULL);
+
+}
+
 static void
 get_msg_cb (TnyFolder *folder, 
            gboolean cancelled, 
 static void
 get_msg_cb (TnyFolder *folder, 
            gboolean cancelled, 
@@ -1836,7 +2135,7 @@ get_msgs_full_thread (gpointer thr_user_data)
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
 
        /* Notify about operation end */
                priv->status = MODEST_MAIL_OPERATION_STATUS_SUCCESS;
 
        /* Notify about operation end */
-       g_idle_add (idle_notify_update_account_queue, g_object_ref (info->mail_op));
+       g_idle_add (idle_notify_queue, g_object_ref (info->mail_op));
 
        /* Free thread resources. Will be called after all previous idles */
        g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
 
        /* Free thread resources. Will be called after all previous idles */
        g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1, get_msgs_full_destroyer, info, NULL);
index 980b037..fcc7bd6 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <tny-transport-account.h>
 #include <tny-folder-store.h>
 
 #include <tny-transport-account.h>
 #include <tny-folder-store.h>
+#include <widgets/modest-msg-edit-window.h>
 
 G_BEGIN_DECLS
 
 
 G_BEGIN_DECLS
 
@@ -103,6 +104,18 @@ typedef void (*GetMsgAsyncUserCallback) (ModestMailOperation *mail_op,
                                         gpointer user_data);
 
 /**
                                         gpointer user_data);
 
 /**
+ * GetMimePartSizeCallback:
+ *
+ * @mail_op: the current #ModestMailOperation.
+ * @size: size of the attachment
+ * @user_data: generic data passed to user defined function.
+ *
+ */
+typedef void (*GetMimePartSizeCallback) (ModestMailOperation *mail_op, 
+                                        gssize size,
+                                        gpointer user_data);
+
+/**
  * XferMsgAsynUserCallback:
  *
  * @obj: a #GObject generic object which has created current mail operation.
  * XferMsgAsynUserCallback:
  *
  * @obj: a #GObject generic object which has created current mail operation.
@@ -317,20 +330,20 @@ void    modest_mail_operation_send_new_mail   (ModestMailOperation *self,
  * #ModestMailOperation should not be added to any
  * #ModestMailOperationQueue
  *
  * #ModestMailOperation should not be added to any
  * #ModestMailOperationQueue
  *
- * Returns: the newly created message with an own reference.
   **/
   **/
-TnyMsg* modest_mail_operation_save_to_drafts   (ModestMailOperation *self,
-                                               TnyTransportAccount *transport_account,
-                                               TnyMsg *draft_msg,
-                                               const gchar *from,
-                                               const gchar *to,
-                                               const gchar *cc,
-                                               const gchar *bcc,
-                                               const gchar *subject,
-                                               const gchar *plain_body,
-                                               const gchar *html_body,
-                                               const GList *attachments_list,
-                                               TnyHeaderFlags priority_flags);
+void modest_mail_operation_save_to_drafts   (ModestMailOperation *self,
+                                            TnyTransportAccount *transport_account,
+                                            TnyMsg *draft_msg,
+                                            ModestMsgEditWindow *edit_window,
+                                            const gchar *from,
+                                            const gchar *to,
+                                            const gchar *cc,
+                                            const gchar *bcc,
+                                            const gchar *subject,
+                                            const gchar *plain_body,
+                                            const gchar *html_body,
+                                            const GList *attachments_list,
+                                            TnyHeaderFlags priority_flags);
 /**
  * modest_mail_operation_update_account:
  * @self: a #ModestMailOperation
 /**
  * modest_mail_operation_update_account:
  * @self: a #ModestMailOperation
@@ -524,6 +537,21 @@ void          modest_mail_operation_get_msgs_full   (ModestMailOperation *self,
                                                     gpointer user_data,
                                                     GDestroyNotify notify);
 
                                                     gpointer user_data,
                                                     GDestroyNotify notify);
 
+/**
+ * modest_mail_operation_get_mime_part_size:
+ * @self: a #ModestMailOperation
+ * @part: a #TnyMimePart
+ * @user_callback: a #GetMimePartSizeAsyncUserCallback
+ * @user_data: user data passed to the user callback
+ *
+ * gets the size of the mime part, simply getting all the stream.
+ */
+void          modest_mail_operation_get_mime_part_size (ModestMailOperation *self,
+                                                       TnyMimePart *part,
+                                                       GetMimePartSizeCallback user_callback,
+                                                       gpointer user_data,
+                                                       GDestroyNotify notify);
+
 /* Functions to control mail operations */
 /**
  * modest_mail_operation_get_task_done:
 /* Functions to control mail operations */
 /**
  * modest_mail_operation_get_task_done:
index 89f8ea3..0164e21 100644 (file)
@@ -35,6 +35,8 @@
 #include <modest-runtime.h>
 #include "modest-formatter.h"
 #include <tny-camel-stream.h>
 #include <modest-runtime.h>
 #include "modest-formatter.h"
 #include <tny-camel-stream.h>
+#include <tny-camel-mime-part.h>
+#include <camel/camel-stream-buffer.h>
 #include <camel/camel-stream-mem.h>
 #include <glib/gprintf.h>
 
 #include <camel/camel-stream-mem.h>
 #include <glib/gprintf.h>
 
@@ -56,7 +58,7 @@ static gboolean is_ascii(const gchar *s);
 TnyMsg*
 modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc,
                    const gchar *bcc, const gchar* subject, const gchar *body,
 TnyMsg*
 modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc,
                    const gchar *bcc, const gchar* subject, const gchar *body,
-                   GSList *attachments)
+                   GList *attachments)
 {
        TnyMsg *new_msg;
        TnyHeader *header;
 {
        TnyMsg *new_msg;
        TnyHeader *header;
@@ -89,7 +91,7 @@ modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc,
                       
        /* Add attachments */
        if (attachments)
                       
        /* Add attachments */
        if (attachments)
-               add_attachments (new_msg, (GList*) attachments);
+               add_attachments (new_msg, attachments);
 
        return new_msg;
 }
 
        return new_msg;
 }
@@ -98,7 +100,7 @@ TnyMsg*
 modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* from, const gchar *cc,
                               const gchar *bcc, const gchar* subject, 
                               const gchar *html_body, const gchar *plain_body,
 modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* from, const gchar *cc,
                               const gchar *bcc, const gchar* subject, 
                               const gchar *html_body, const gchar *plain_body,
-                              GSList *attachments)
+                              GList *attachments)
 {
        TnyMsg *new_msg;
        TnyHeader *header;
 {
        TnyMsg *new_msg;
        TnyHeader *header;
@@ -130,7 +132,7 @@ modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* from, const gch
        g_free (content_type);
                       
        /* Add attachments */
        g_free (content_type);
                       
        /* Add attachments */
-       add_attachments (new_msg, (GList*) attachments);
+       add_attachments (new_msg, attachments);
 
        return new_msg;
 }
 
        return new_msg;
 }
@@ -223,7 +225,7 @@ copy_mime_part (TnyMimePart *part)
        attachment_cid = tny_mime_part_get_content_id (part);
        
        /* fill the stream */
        attachment_cid = tny_mime_part_get_content_id (part);
        
        /* fill the stream */
-       attachment_stream = tny_mime_part_get_stream (part);
+       attachment_stream = tny_mime_part_get_stream (part);
        tny_stream_reset (attachment_stream);
        tny_mime_part_construct_from_stream (result,
                                             attachment_stream,
        tny_stream_reset (attachment_stream);
        tny_mime_part_construct_from_stream (result,
                                             attachment_stream,
index 5166b88..f43b9b5 100644 (file)
@@ -77,7 +77,7 @@ typedef enum _ModestTnyMsgReplyMode {
  */     
 TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gchar *cc,
                            const gchar *bcc, const gchar* subject, const gchar *body,
  */     
 TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gchar *cc,
                            const gchar *bcc, const gchar* subject, const gchar *body,
-                           GSList *attachments);
+                           GList *attachments);
 
 /**
  * modest_tny_msg_new_html_plain:
 
 /**
  * modest_tny_msg_new_html_plain:
@@ -97,7 +97,7 @@ TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gc
 TnyMsg* modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* mailfrom, const gchar *cc,
                                       const gchar *bcc, const gchar* subject, 
                                       const gchar *html_body, const gchar *plain_body,
 TnyMsg* modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* mailfrom, const gchar *cc,
                                       const gchar *bcc, const gchar* subject, 
                                       const gchar *html_body, const gchar *plain_body,
-                                      GSList *attachments);
+                                      GList *attachments);
 
 /**
  * modest_tny_msg_find_body_part:
 
 /**
  * modest_tny_msg_find_body_part:
index 40518b8..8f7e2ca 100644 (file)
@@ -187,7 +187,7 @@ modest_tny_send_queue_add (TnySendQueue *self, TnyMsg *msg, GError **err)
 
        /* Check whether the mail is already in the queue */
 /*     msg_id = tny_header_get_message_id (header); */
 
        /* Check whether the mail is already in the queue */
 /*     msg_id = tny_header_get_message_id (header); */
-       msg_id = tny_header_get_uid (header);
+       msg_id = tny_header_get_uid (header);   
        g_return_if_fail (msg_id != NULL);
        existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_id);
        if(existing != NULL)
        g_return_if_fail (msg_id != NULL);
        existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_id);
        if(existing != NULL)
index 36e3a9d..4d168be 100644 (file)
@@ -1839,7 +1839,6 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
        gchar *account_name, *from;
        ModestAccountMgr *account_mgr;
        gchar *info_text = NULL;
        gchar *account_name, *from;
        ModestAccountMgr *account_mgr;
        gchar *info_text = NULL;
-       TnyMsg *new_draft = NULL;
 
        g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
        
 
        g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
        
@@ -1876,18 +1875,19 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
        mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
 
        mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
        modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
 
-       new_draft = modest_mail_operation_save_to_drafts (mail_operation,
-                                                         transport_account,
-                                                         data->draft_msg,
-                                                         from,
-                                                         data->to, 
-                                                         data->cc, 
-                                                         data->bcc,
-                                                         data->subject, 
-                                                         data->plain_body, 
-                                                         data->html_body,
-                                                         data->attachments,
-                                                         data->priority_flags);
+       modest_mail_operation_save_to_drafts (mail_operation,
+                                             transport_account,
+                                             data->draft_msg,
+                                             edit_window,
+                                             from,
+                                             data->to, 
+                                             data->cc, 
+                                             data->bcc,
+                                             data->subject, 
+                                             data->plain_body, 
+                                             data->html_body,
+                                             data->attachments,
+                                             data->priority_flags);
        /* Frees */
        g_free (from);
        g_free (account_name);
        /* Frees */
        g_free (from);
        g_free (account_name);
@@ -1896,10 +1896,6 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi
 
        modest_msg_edit_window_free_msg_data (edit_window, data);
 
 
        modest_msg_edit_window_free_msg_data (edit_window, data);
 
-       modest_msg_edit_window_set_draft (edit_window, new_draft);
-       if (new_draft != NULL)
-               g_object_unref (new_draft);
-
        info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
        modest_platform_information_banner (NULL, NULL, info_text);
        g_free (info_text);
        info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
        modest_platform_information_banner (NULL, NULL, info_text);
        g_free (info_text);
index 12bb23c..e972f79 100644 (file)
@@ -39,6 +39,9 @@
 #include <modest-text-utils.h>
 #include <tny-msg.h>
 #include <tny-camel-mem-stream.h>
 #include <modest-text-utils.h>
 #include <tny-msg.h>
 #include <tny-camel-mem-stream.h>
+#include <modest-mail-operation.h>
+#include <modest-mail-operation-queue.h>
+#include <modest-runtime.h>
 
 static GObjectClass *parent_class = NULL;
 
 
 static GObjectClass *parent_class = NULL;
 
@@ -62,7 +65,6 @@ struct _ModestAttachmentViewPriv
 };
 
 #define UNKNOWN_FILE_ICON "qgn_list_gene_unknown_file"
 };
 
 #define UNKNOWN_FILE_ICON "qgn_list_gene_unknown_file"
-#define GET_SIZE_BUFFER_SIZE 128
 
 #define MODEST_ATTACHMENT_VIEW_GET_PRIVATE(o)  \
        (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ATTACHMENT_VIEW, ModestAttachmentViewPriv))
 
 #define MODEST_ATTACHMENT_VIEW_GET_PRIVATE(o)  \
        (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ATTACHMENT_VIEW, ModestAttachmentViewPriv))
@@ -86,9 +88,32 @@ static void tny_mime_part_view_init (gpointer g, gpointer iface_data);
 
 
 
 
 
 
-static gboolean get_size_idle_func (gpointer data);
 static void update_filename_request (ModestAttachmentView *self);
 
 static void update_filename_request (ModestAttachmentView *self);
 
+static void get_mime_part_size_cb (ModestMailOperation *mail_op,
+                                  gssize size,
+                                  gpointer userdata);
+
+
+static void 
+get_mime_part_size_cb (ModestMailOperation *mail_op,
+                      gssize size,
+                      gpointer userdata)
+{
+       ModestAttachmentView *att_view = MODEST_ATTACHMENT_VIEW (userdata);
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (att_view);
+       gchar *size_str;
+       gchar *label_text;
+
+       if (GTK_WIDGET_VISIBLE (att_view)) {
+               size_str = modest_text_utils_get_display_size (size);
+               label_text = g_strdup_printf (" (%s)", size_str);
+               g_free (size_str);
+               gtk_label_set_text (GTK_LABEL (priv->size_view), label_text);
+               g_free (label_text);
+       }
+}
+
 
 
 static TnyMimePart *
 
 
 static TnyMimePart *
@@ -128,50 +153,6 @@ modest_attachment_view_set_part (TnyMimePartView *self, TnyMimePart *mime_part)
 }
 
 
 }
 
 
-static gboolean
-get_size_idle_func (gpointer data)
-{      
-       ModestAttachmentView *self = (ModestAttachmentView *) data;
-       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (self);
-       gssize readed_size;
-       gchar read_buffer[GET_SIZE_BUFFER_SIZE];
-       gchar *size_string;
-
-       if (priv->get_size_stream == NULL) {
-               priv->get_size_stream = tny_camel_mem_stream_new ();
-               tny_mime_part_decode_to_stream (priv->mime_part, priv->get_size_stream);
-               tny_stream_reset (priv->get_size_stream);
-               if (tny_stream_is_eos (priv->get_size_stream)) {
-                       tny_stream_close (priv->get_size_stream);
-                       priv->get_size_stream = tny_mime_part_get_stream (priv->mime_part);
-               }
-       }
-
-       readed_size = tny_stream_read (priv->get_size_stream, read_buffer, GET_SIZE_BUFFER_SIZE);
-       priv->size += readed_size;
-
-       if (tny_stream_is_eos (priv->get_size_stream)) {
-               gchar *display_size;
-
-               gdk_threads_enter ();
-
-               display_size = modest_text_utils_get_display_size (priv->size);
-               size_string = g_strdup_printf (" (%s)", display_size);
-               g_free (display_size);
-               gtk_label_set_text (GTK_LABEL (priv->size_view), size_string);
-               g_free (size_string);
-
-               g_object_unref (priv->get_size_stream);
-
-               gtk_widget_queue_resize (priv->size_view);
-               priv->get_size_stream = NULL;
-               priv->get_size_idle_id = 0;
-
-               gdk_threads_leave ();
-       }
-       return (priv->get_size_stream != NULL);
-}
-
 static void
 modest_attachment_view_set_part_default (TnyMimePartView *self, TnyMimePart *mime_part)
 {
 static void
 modest_attachment_view_set_part_default (TnyMimePartView *self, TnyMimePart *mime_part)
 {
@@ -190,16 +171,6 @@ modest_attachment_view_set_part_default (TnyMimePartView *self, TnyMimePart *mim
 
        priv->mime_part = mime_part;
 
 
        priv->mime_part = mime_part;
 
-       if (priv->get_size_idle_id != 0) {
-               g_source_remove (priv->get_size_idle_id);
-               priv->get_size_idle_id = 0;
-       }
-
-       if (priv->get_size_stream != NULL) {
-               g_object_unref (priv->get_size_stream);
-               priv->get_size_stream = NULL;
-       }
-
        priv->size = 0;
        priv->is_purged = tny_mime_part_is_purged (mime_part);
        
        priv->size = 0;
        priv->is_purged = tny_mime_part_is_purged (mime_part);
        
@@ -246,8 +217,14 @@ modest_attachment_view_set_part_default (TnyMimePartView *self, TnyMimePart *mim
 
        gtk_label_set_text (GTK_LABEL (priv->size_view), "");
 
 
        gtk_label_set_text (GTK_LABEL (priv->size_view), "");
 
-       if (show_size)
-               priv->get_size_idle_id = g_idle_add ((GSourceFunc) get_size_idle_func, (gpointer) self);
+       if (show_size) {
+               ModestMailOperation *mail_op = 
+                       modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT (self));
+               modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
+               modest_mail_operation_get_mime_part_size (mail_op, mime_part, get_mime_part_size_cb,
+                                                         self, NULL);
+               g_object_unref (mail_op);
+       }
 
        gtk_widget_queue_draw (GTK_WIDGET (self));
 }
 
        gtk_widget_queue_draw (GTK_WIDGET (self));
 }