From b9b928dee5f5169c3317df86b153b4d069b814d0 Mon Sep 17 00:00:00 2001 From: Jose Dapena Paz Date: Fri, 28 Sep 2007 14:54:55 +0000 Subject: [PATCH] This commit implements a new handling of image attachments. We follow the standard of mime, adding the image attachment in a multipart/related with the body. These together form the complete body of the message. This fixes NB#64463. * src/widgets/modest-msg-edit-window.h: * Add attribute images to the MsgData. * src/widgets/modest-attachments-view.c: * We only add attachments from message if it's not a multipart/related (as they would be attached images and they shouldn't be represented in attachments view). * src/modest-tny-msg.[ch]: * (modest_formatter_create_message): now it accepts a new parameter "has_images", to create the proper structure of image attachments (including the multipart/related). * /modest_tny_msg_new_html_plain): now it receives also a list of image mime parts. It adds them properly to the message using the new add_images() method. * (add_attachment). Now it allows adding attachments as children of an arbitrary part. This is required to add image attachments to multipart/related. It also accepts a new parameter "add_inline" to set the disposition as attachment or inline depending on the parameter used. * (add_images): this new method searches the multipart/related mime part, and adds a list of image mime parts to it. * src/modest-ui-actions.c: * Add images parameter to save to drafts and send new mail actions. * src/maemo/modest-msg-edit-window.c: * Now we maintain an internal list of images in body buffer, separated from the list of attachments. * (replace_with_attachments): renamed to replace_with_images as it's intended to replace image replacers with attached images in priv->images list. * New method (get_related_images): searches the multipart/related mime part, and obtains all the image children it has. Then it adds the images to the priv->images list. * Now last_cid is updated using the images and attachments list. * (modest_msg_edit_window_get_msg_data): now we also obtain the list of images attached (unless a image is in priv->image and not refernced in the buffer). * src/modest-formatter.[ch]: * Added internal method find_body_parent (), to refactor the work to find the part where body should be attached to. * (modest_formatter_create_message): now it takes into account the new attribute has_images to create the proper mime part multipart/related. * src/modest-mail-operation.[ch]: * (modest_mail_operation_create_message): now we pass the images list to the lower layers. pmo-trunk-r3438 --- src/maemo/modest-msg-edit-window.c | 103 +++++++++++++++++++++++++++++--- src/modest-formatter.c | 106 +++++++++++++++++++++++---------- src/modest-formatter.h | 7 ++- src/modest-mail-operation.c | 18 ++++-- src/modest-mail-operation.h | 4 ++ src/modest-tny-msg.c | 58 +++++++++++++++--- src/modest-tny-msg.h | 5 +- src/modest-ui-actions.c | 2 + src/widgets/modest-attachments-view.c | 10 ++++ src/widgets/modest-msg-edit-window.h | 1 + 10 files changed, 258 insertions(+), 56 deletions(-) diff --git a/src/maemo/modest-msg-edit-window.c b/src/maemo/modest-msg-edit-window.c index 0ece256..e09c165 100644 --- a/src/maemo/modest-msg-edit-window.c +++ b/src/maemo/modest-msg-edit-window.c @@ -244,6 +244,7 @@ struct _ModestMsgEditWindowPrivate { gint last_cid; GList *attachments; + GList *images; TnyHeaderFlags priority_flags; @@ -347,6 +348,7 @@ modest_msg_edit_window_init (ModestMsgEditWindow *obj) priv->bcc_field = NULL; priv->subject_field = NULL; priv->attachments = NULL; + priv->images = NULL; priv->last_cid = 0; priv->zoom_level = 1.0; @@ -735,7 +737,7 @@ pixbuf_from_stream (TnyStream *stream, const gchar *mime_type) } static void -replace_with_attachments (ModestMsgEditWindow *self, GList *attachments) +replace_with_images (ModestMsgEditWindow *self, GList *attachments) { ModestMsgEditWindowPrivate *priv; GList *node; @@ -760,6 +762,62 @@ replace_with_attachments (ModestMsgEditWindow *self, GList *attachments) } static void +get_related_images (ModestMsgEditWindow *self, TnyMsg *msg) +{ + TnyMimePart *parent = NULL; + const gchar *content_type = NULL; + ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self); + + content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg)); + + if (content_type && !g_strcasecmp (content_type, "multipart/related")) { + parent = g_object_ref (msg); + } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) { + TnyList *parts = TNY_LIST (tny_simple_list_new ()); + TnyIterator *iter; + + tny_mime_part_get_parts (TNY_MIME_PART (msg), parts); + iter = tny_list_create_iterator (parts); + while (!tny_iterator_is_done (iter)) { + TnyMimePart *part; + part = TNY_MIME_PART (tny_iterator_get_current (iter)); + content_type = tny_mime_part_get_content_type (part); + if (content_type && !g_strcasecmp (content_type, "multipart/related")) { + parent = part; + break; + } else { + g_object_unref (part); + } + tny_iterator_next (iter); + } + g_object_unref (iter); + g_object_unref (parts); + } + + if (parent != NULL) { + TnyList *parts = TNY_LIST (tny_simple_list_new ()); + TnyIterator *iter; + + tny_mime_part_get_parts (TNY_MIME_PART (parent), parts); + iter = tny_list_create_iterator (parts); + while (!tny_iterator_is_done (iter)) { + TnyMimePart *part; + part = TNY_MIME_PART (tny_iterator_get_current (iter)); + content_type = tny_mime_part_get_content_type (part); + if (content_type && g_str_has_prefix (content_type, "image/")) { + priv->images = g_list_prepend (priv->images, part); + } else { + g_object_unref (part); + } + tny_iterator_next (iter); + } + g_object_unref (iter); + g_object_unref (parts); + g_object_unref (parent); + } +} + +static void update_last_cid (ModestMsgEditWindow *self, GList *attachments) { GList *node; @@ -851,9 +909,11 @@ set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich) } else { gtk_widget_set_no_show_all (priv->attachments_caption, FALSE); gtk_widget_show_all (priv->attachments_caption); - replace_with_attachments (self, priv->attachments); } + get_related_images (self, msg); update_last_cid (self, priv->attachments); + update_last_cid (self, priv->images); + replace_with_images (self, priv->images); if (preserve_is_rich && !is_html) { wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE); @@ -1353,6 +1413,35 @@ modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window) g_object_ref (cursor->data)); cursor = g_list_next (cursor); } + + GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer)); + cursor = priv->images; + data->images = NULL; + while (cursor) { + const gchar *cid; + if (!(TNY_IS_MIME_PART(cursor->data))) { + g_warning ("strange data in attachment list"); + cursor = g_list_next (cursor); + continue; + } + cid = tny_mime_part_get_content_id (cursor->data); + if (cid) { + gchar *image_tag_id; + GtkTextTag *image_tag; + GtkTextIter iter; + image_tag_id = g_strdup_printf ("image-tag-%s", cid); + image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id); + g_free (image_tag_id); + + gtk_text_buffer_get_start_iter (priv->text_buffer, &iter); + if (image_tag && + ((gtk_text_iter_has_tag (&iter, image_tag))|| + (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag)))) + data->images = g_list_append (data->images, + g_object_ref (cursor->data)); + } + cursor = g_list_next (cursor); + } data->priority_flags = priv->priority_flags; @@ -1392,6 +1481,8 @@ modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window, g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL); g_list_free (data->attachments); + g_list_foreach (data->images, (GFunc)unref_gobject, NULL); + g_list_free (data->images); g_slice_free (MsgData, data); } @@ -1803,11 +1894,7 @@ modest_msg_edit_window_insert_image (ModestMsgEditWindow *window) wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf); } - priv->attachments = g_list_prepend (priv->attachments, mime_part); - modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), - mime_part); - gtk_widget_set_no_show_all (priv->attachments_caption, FALSE); - gtk_widget_show_all (priv->attachments_caption); + priv->images = g_list_prepend (priv->images, mime_part); gtk_text_buffer_set_modified (priv->text_buffer, TRUE); g_free (filename); @@ -3103,7 +3190,7 @@ text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag, if (tag == NULL+13) return; g_object_get (G_OBJECT (tag), "name", &tag_name, NULL); if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) { - replace_with_attachments (window, priv->attachments); + replace_with_images (window, priv->images); } } diff --git a/src/modest-formatter.c b/src/modest-formatter.c index 39f0448..f055b0a 100644 --- a/src/modest-formatter.c +++ b/src/modest-formatter.c @@ -62,6 +62,8 @@ static gchar* modest_formatter_wrapper_quote (ModestFormatter *self, const gch static gchar* modest_formatter_wrapper_inline (ModestFormatter *self, const gchar *text, TnyHeader *header, GList *attachments); +static TnyMimePart *find_body_parent (TnyMimePart *part); + static gchar * extract_text (ModestFormatter *self, TnyMimePart *body) { @@ -133,7 +135,7 @@ modest_formatter_do (ModestFormatter *self, TnyMimePart *body, TnyHeader *header g_return_val_if_fail (func, NULL); /* Build new part */ - new_msg = modest_formatter_create_message (self, TRUE, attachments != NULL); + new_msg = modest_formatter_create_message (self, TRUE, attachments != NULL, FALSE); body_part = modest_formatter_create_body_part (self, new_msg); if (body) @@ -181,7 +183,7 @@ modest_formatter_attach (ModestFormatter *self, TnyMsg *msg, TnyHeader *header) fact = modest_runtime_get_platform_factory (); /* Build new part */ - new_msg = modest_formatter_create_message (self, TRUE, TRUE); + new_msg = modest_formatter_create_message (self, TRUE, TRUE, FALSE); body_part = modest_formatter_create_body_part (self, new_msg); /* Create the two parts */ @@ -347,21 +349,44 @@ modest_formatter_wrapper_quote (ModestFormatter *self, const gchar *text, TnyHea } TnyMsg * -modest_formatter_create_message (ModestFormatter *self, gboolean single_body, gboolean has_attachments) +modest_formatter_create_message (ModestFormatter *self, gboolean single_body, + gboolean has_attachments, gboolean has_images) { TnyMsg *result = NULL; TnyPlatformFactory *fact = NULL; TnyMimePart *body_mime_part = NULL; + TnyMimePart *related_mime_part = NULL; + fact = modest_runtime_get_platform_factory (); result = tny_platform_factory_new_msg (fact); if (has_attachments) { tny_mime_part_set_content_type (TNY_MIME_PART (result), "multipart/mixed"); + if (has_images) { + related_mime_part = tny_platform_factory_new_mime_part (fact); + tny_mime_part_set_content_type (related_mime_part, "multipart/related"); + tny_mime_part_add_part (TNY_MIME_PART (result), related_mime_part); + } else { + related_mime_part = g_object_ref (result); + } + + if (!single_body) { + body_mime_part = tny_platform_factory_new_mime_part (fact); + tny_mime_part_set_content_type (body_mime_part, "multipart/alternative"); + tny_mime_part_add_part (TNY_MIME_PART (related_mime_part), body_mime_part); + g_object_unref (body_mime_part); + } + + g_object_unref (related_mime_part); + } else if (has_images) { + tny_mime_part_set_content_type (TNY_MIME_PART (result), "multipart/related"); + if (!single_body) { body_mime_part = tny_platform_factory_new_mime_part (fact); tny_mime_part_set_content_type (body_mime_part, "multipart/alternative"); tny_mime_part_add_part (TNY_MIME_PART (result), body_mime_part); g_object_unref (body_mime_part); } + } else if (!single_body) { tny_mime_part_set_content_type (TNY_MIME_PART (result), "multipart/alternative"); } @@ -369,35 +394,32 @@ modest_formatter_create_message (ModestFormatter *self, gboolean single_body, gb return result; } -TnyMimePart * -modest_formatter_create_body_part (ModestFormatter *self, TnyMsg *msg) +TnyMimePart * +find_body_parent (TnyMimePart *part) { - TnyMimePart *result = NULL; const gchar *msg_content_type = NULL; - TnyPlatformFactory *fact = NULL; + msg_content_type = tny_mime_part_get_content_type (part); - fact = modest_runtime_get_platform_factory (); - msg_content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg)); - /* First it checks if the main part is alternative */ - if ((msg_content_type != NULL) && - (!g_strcasecmp (msg_content_type, "multipart/alternative"))) { - result = tny_platform_factory_new_mime_part (fact); - tny_mime_part_add_part (TNY_MIME_PART (msg), result); - return result; - } else if ((msg_content_type != NULL) && - (!g_strcasecmp (msg_content_type, "multipart/mixed"))) { - TnyList *parts = NULL; + if ((msg_content_type != NULL) && + (!g_strcasecmp (msg_content_type, "multipart/alternative"))) + return g_object_ref (part); + else if ((msg_content_type != NULL) && + (g_str_has_prefix (msg_content_type, "multipart/"))) { TnyIterator *iter = NULL; TnyMimePart *alternative_part = NULL; - - parts = TNY_LIST (tny_simple_list_new ()); - tny_mime_part_get_parts (TNY_MIME_PART (msg), parts); + TnyMimePart *related_part = NULL; + TnyList *parts = TNY_LIST (tny_simple_list_new ()); + tny_mime_part_get_parts (TNY_MIME_PART (part), parts); iter = tny_list_create_iterator (parts); + while (!tny_iterator_is_done (iter)) { TnyMimePart *part = TNY_MIME_PART (tny_iterator_get_current (iter)); if (part && !g_strcasecmp(tny_mime_part_get_content_type (part), "multipart/alternative")) { alternative_part = part; break; + } else if (part && !g_strcasecmp (tny_mime_part_get_content_type (part), "multipart/related")) { + related_part = part; + break; } if (part) @@ -405,18 +427,38 @@ modest_formatter_create_body_part (ModestFormatter *self, TnyMsg *msg) tny_iterator_next (iter); } + g_object_unref (iter); + g_object_unref (parts); + if (related_part) { + TnyMimePart *result; + result = find_body_parent (related_part); + g_object_unref (related_part); + return result; + } else if (alternative_part) + return alternative_part; + else + return g_object_ref (part); + } else + return NULL; +} + +TnyMimePart * +modest_formatter_create_body_part (ModestFormatter *self, TnyMsg *msg) +{ + TnyMimePart *result = NULL; + TnyPlatformFactory *fact = NULL; + TnyMimePart *parent = NULL; + + parent = find_body_parent (TNY_MIME_PART (msg)); + fact = modest_runtime_get_platform_factory (); + if (parent != NULL) { result = tny_platform_factory_new_mime_part (fact); - if (alternative_part != NULL) { - tny_mime_part_add_part (alternative_part, result); - } else { - tny_mime_part_add_part (TNY_MIME_PART (msg), result); - } - g_object_unref (G_OBJECT (parts)); - return result; + tny_mime_part_add_part (TNY_MIME_PART (parent), result); + g_object_unref (parent); } else { - /* We add a reference as this method is intended to obtain - a ref'ed part */ - g_object_ref (msg); - return TNY_MIME_PART (msg); + result = g_object_ref (msg); } + + return result; + } diff --git a/src/modest-formatter.h b/src/modest-formatter.h index 338c2a0..15c00ed 100644 --- a/src/modest-formatter.h +++ b/src/modest-formatter.h @@ -174,6 +174,7 @@ TnyMsg * modest_formatter_attach (ModestFormatter *self, TnyMsg *msg, TnyHeader * @self: a #ModestFormatter * @single_body: a #gboolean * @has_attachments: a #gboolean + * @has_images: a #gboolean * * Creates an empty #TnyMsg with the expected parts for Modest * formatters and body embedders. @@ -186,8 +187,12 @@ TnyMsg * modest_formatter_attach (ModestFormatter *self, TnyMsg *msg, TnyHeader * If @single_body is %TRUE, the body will be stored as a * "multipart/alternative", and the parts will be the different * alternatives. If %FALSE, this body will be stored directly. + * + * If @has_images is %TRUE, the body will be embedded in a + * multipart/related, that will also host attached images. */ -TnyMsg * modest_formatter_create_message (ModestFormatter *self, gboolean single_body, gboolean has_attachments); +TnyMsg * modest_formatter_create_message (ModestFormatter *self, gboolean single_body, + gboolean has_attachments, gboolean has_images); /** * modest_formatter_create_body_part: diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index e7e9774..678e9c2 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -144,6 +144,7 @@ static void modest_mail_operation_create_msg (ModestMailOperation *self const gchar *cc, const gchar *bcc, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags, ModestMailOperationCreateMsgCallback callback, gpointer userdata); @@ -160,6 +161,7 @@ typedef struct gchar *plain_body; gchar *html_body; GList *attachments_list; + GList *images_list; TnyHeaderFlags priority_flags; ModestMailOperationCreateMsgCallback callback; gpointer userdata; @@ -613,11 +615,12 @@ create_msg_thread (gpointer thread_data) 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 */ + info->attachments_list); } 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); + info->plain_body, info->attachments_list, + info->images_list); } if (new_msg) { @@ -652,6 +655,8 @@ create_msg_thread (gpointer thread_data) g_free (info->subject); g_list_foreach (info->attachments_list, (GFunc) g_object_unref, NULL); g_list_free (info->attachments_list); + g_list_foreach (info->images_list, (GFunc) g_object_unref, NULL); + g_list_free (info->images_list); if (info->callback) { CreateMsgIdleInfo *idle_info; @@ -680,6 +685,7 @@ modest_mail_operation_create_msg (ModestMailOperation *self, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags, ModestMailOperationCreateMsgCallback callback, gpointer userdata) @@ -699,6 +705,8 @@ modest_mail_operation_create_msg (ModestMailOperation *self, 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->images_list = g_list_copy ((GList *) images_list); + g_list_foreach (info->images_list, (GFunc) g_object_ref, NULL); info->priority_flags = priority_flags; info->callback = callback; @@ -782,6 +790,7 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags) { ModestMailOperationPrivate *priv = NULL; @@ -809,7 +818,7 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self, 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, + attachments_list, images_list, priority_flags, modest_mail_operation_send_new_mail_cb, info); } @@ -903,6 +912,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self, const gchar *subject, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags) { ModestMailOperationPrivate *priv = NULL; @@ -926,7 +936,7 @@ modest_mail_operation_save_to_drafts (ModestMailOperation *self, g_object_ref (edit_window); modest_mail_operation_create_msg (self, from, to, cc, bcc, subject, plain_body, html_body, - attachments_list, priority_flags, + attachments_list, images_list, priority_flags, modest_mail_operation_save_to_drafts_cb, info); } diff --git a/src/modest-mail-operation.h b/src/modest-mail-operation.h index eac5235..f4212b4 100644 --- a/src/modest-mail-operation.h +++ b/src/modest-mail-operation.h @@ -289,6 +289,7 @@ void modest_mail_operation_send_mail (ModestMailOperation *self, * @html_body: the html version of the body of the new mail. If NULL, the mail will * be sent with the plain body only. * @attachments_list: a #GList of attachments, each attachment must be a #TnyMimePart + * @images_list: a #GList of image attachments, each attachment must be a #TnyMimePart * * Sends a new mail message using the provided * #TnyTransportAccount. This operation is synchronous, so the @@ -306,6 +307,7 @@ void modest_mail_operation_send_new_mail (ModestMailOperation *self, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags); @@ -324,6 +326,7 @@ void modest_mail_operation_send_new_mail (ModestMailOperation *self, * @html_body: the html version of the body of the new mail. If NULL, the mail will * be sent with the plain body only. * @attachments_list: a #GList of attachments, each attachment must be a #TnyMimePart + * @images_list: a #GList of image attachments, each attachment must be a #TnyMimePart * * Save a mail message to drafts using the provided * #TnyTransportAccount. This operation is synchronous, so the @@ -343,6 +346,7 @@ void modest_mail_operation_save_to_drafts (ModestMailOperation *self, const gchar *plain_body, const gchar *html_body, const GList *attachments_list, + const GList *images_list, TnyHeaderFlags priority_flags); /** * modest_mail_operation_update_account: diff --git a/src/modest-tny-msg.c b/src/modest-tny-msg.c index 36cfc47..857d065 100644 --- a/src/modest-tny-msg.c +++ b/src/modest-tny-msg.c @@ -51,7 +51,8 @@ static TnyMimePart * add_body_part (TnyMsg *msg, const gchar *body, const gchar *content_type); static TnyMimePart * add_html_body_part (TnyMsg *msg, const gchar *body); -static void add_attachments (TnyMsg *msg, GList *attachments_list); +static void add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline); +static void add_images (TnyMsg *msg, GList *attachments_list); static char * get_content_type(const gchar *s); static gboolean is_ascii(const gchar *s); @@ -66,7 +67,7 @@ modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc, gchar *content_type; /* Create new msg */ - new_msg = modest_formatter_create_message (NULL, TRUE, (attachments != NULL)); + new_msg = modest_formatter_create_message (NULL, TRUE, (attachments != NULL), FALSE); header = tny_msg_get_header (new_msg); if ((from != NULL) && (strlen(from) > 0)) { @@ -92,7 +93,7 @@ modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc, /* Add attachments */ if (attachments) - add_attachments (new_msg, attachments); + add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE); return new_msg; } @@ -101,14 +102,14 @@ 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, - GList *attachments) + GList *attachments, GList *images) { TnyMsg *new_msg; TnyHeader *header; gchar *content_type; /* Create new msg */ - new_msg = modest_formatter_create_message (NULL, FALSE, (attachments != NULL)); + new_msg = modest_formatter_create_message (NULL, FALSE, (attachments != NULL), (images != NULL)); header = tny_msg_get_header (new_msg); if ((from != NULL) && (strlen(from) > 0)) { @@ -133,7 +134,8 @@ modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* from, const gch g_free (content_type); /* Add attachments */ - add_attachments (new_msg, attachments); + add_attachments (TNY_MIME_PART (new_msg), attachments, FALSE); + add_images (new_msg, images); return new_msg; } @@ -259,7 +261,7 @@ copy_mime_part (TnyMimePart *part) } static void -add_attachments (TnyMsg *msg, GList *attachments_list) +add_attachments (TnyMimePart *part, GList *attachments_list, gboolean add_inline) { GList *pos; TnyMimePart *attachment_part, *old_attachment; @@ -269,12 +271,50 @@ add_attachments (TnyMsg *msg, GList *attachments_list) old_attachment = pos->data; if (!tny_mime_part_is_purged (old_attachment)) { attachment_part = copy_mime_part (old_attachment); - tny_mime_part_add_part (TNY_MIME_PART (msg), attachment_part); + tny_mime_part_add_part (TNY_MIME_PART (part), attachment_part); + tny_mime_part_set_header_pair (attachment_part, "Content-Disposition", + add_inline?"inline":"attachment"); g_object_unref (attachment_part); } } } +static void +add_images (TnyMsg *msg, GList *images_list) +{ + TnyMimePart *related_part = NULL; + const gchar *content_type; + + content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg)); + + if ((content_type != NULL) && !strcasecmp (content_type, "multipart/related")) { + related_part = g_object_ref (msg); + } else if ((content_type != NULL) && !strcasecmp (content_type, "multipart/mixed")) { + TnyList *parts = TNY_LIST (tny_simple_list_new ()); + TnyIterator *iter = NULL; + tny_mime_part_get_parts (TNY_MIME_PART (msg), parts); + iter = tny_list_create_iterator (parts); + + while (!tny_iterator_is_done (iter)) { + TnyMimePart *part = TNY_MIME_PART (tny_iterator_get_current (iter)); + if (part && !g_strcasecmp (tny_mime_part_get_content_type (part), "multipart/related")) { + related_part = part; + break; + } else { + g_object_unref (part); + } + tny_iterator_next (iter); + } + g_object_unref (iter); + g_object_unref (parts); + } + + if (related_part != NULL) { + /* TODO: attach images in their proper place */ + add_attachments (related_part, images_list, TRUE); + } +} + gchar * modest_tny_msg_get_body (TnyMsg *msg, gboolean want_html, gboolean *is_html) @@ -526,7 +566,7 @@ modest_tny_msg_create_forward_msg (TnyMsg *msg, new_msg = create_reply_forward_mail (msg, NULL, from, signature, FALSE, forward_type, attachments_list); - add_attachments (new_msg, attachments_list); + add_attachments (TNY_MIME_PART (new_msg), attachments_list, FALSE); /* Clean */ if (attachments_list) diff --git a/src/modest-tny-msg.h b/src/modest-tny-msg.h index e3da25d..95bfbc6 100644 --- a/src/modest-tny-msg.h +++ b/src/modest-tny-msg.h @@ -88,7 +88,8 @@ TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gc * @subject: subject for the message * @html_body: body for the message in HTML * @plain_body: body for the message in plain text - * @attachments: a list of attachments (local URIs) + * @attachments: a list of attachments (mime parts) + * @attachments: a list of images (mime parts) * * create a new TnyMsg with the given parameters * @@ -97,7 +98,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, - GList *attachments); + GList *attachments, GList *images); /** * modest_tny_msg_find_body_part: diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 341914a..3d154ca 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -2194,6 +2194,7 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi data->plain_body, data->html_body, data->attachments, + data->images, data->priority_flags); /* Frees */ g_free (from); @@ -2272,6 +2273,7 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) data->plain_body, data->html_body, data->attachments, + data->images, data->priority_flags); /* Free data: */ diff --git a/src/widgets/modest-attachments-view.c b/src/widgets/modest-attachments-view.c index aec2c18..f70a4c3 100644 --- a/src/widgets/modest-attachments-view.c +++ b/src/widgets/modest-attachments-view.c @@ -107,6 +107,7 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn ModestAttachmentsViewPrivate *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (attachments_view); TnyList *parts; TnyIterator *iter; + const gchar *msg_content_type = NULL; if (msg == priv->msg) return; @@ -126,6 +127,15 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn return; } + /* If the top mime part is a multipart/related, we don't show the attachments, as they're + * embedded images in body */ + msg_content_type = tny_mime_part_get_content_type (TNY_MIME_PART (priv->msg)); + if ((msg_content_type != NULL) && !strcasecmp (msg_content_type, "multipart/related")) { + gtk_widget_queue_draw (GTK_WIDGET (attachments_view)); + return; + } + + parts = TNY_LIST (tny_simple_list_new ()); tny_mime_part_get_parts (TNY_MIME_PART (priv->msg), parts); iter = tny_list_create_iterator (parts); diff --git a/src/widgets/modest-msg-edit-window.h b/src/widgets/modest-msg-edit-window.h index 29353de..bacb0b1 100644 --- a/src/widgets/modest-msg-edit-window.h +++ b/src/widgets/modest-msg-edit-window.h @@ -86,6 +86,7 @@ typedef enum { typedef struct { gchar *from, *to, *cc, *bcc, *subject, *plain_body, *html_body; GList *attachments; + GList *images; TnyHeaderFlags priority_flags; TnyMsg *draft_msg; gchar *account_name; -- 1.7.9.5