I#1471 - Composer: Lost attachments in reply/forward of an encrypted message

Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1471
This commit is contained in:
Milan Crha
2021-04-26 11:50:10 +02:00
parent d719488622
commit 29c564a64f
5 changed files with 154 additions and 32 deletions

View File

@ -3255,6 +3255,70 @@ e_msg_composer_add_message_attachments (EMsgComposer *composer,
composer, (CamelMultipart *) wrapper, just_inlines, 0);
}
/**
* e_msg_composer_add_attachments_from_part_list:
* @composer: the composer to add the attachments to
* @part_list: an #EMailPartList with parts used to format the message
* @just_inlines: whether to attach all attachments or just add inline images
*
* Walk through all the parts in @part_list and add them to the @composer.
*
* Since: 3.42
*/
void
e_msg_composer_add_attachments_from_part_list (EMsgComposer *composer,
EMailPartList *part_list,
gboolean just_inlines)
{
EHTMLEditor *editor;
GQueue queue = G_QUEUE_INIT;
GList *link;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
if (!part_list)
return;
editor = e_msg_composer_get_editor (composer);
e_mail_part_list_queue_parts (part_list, NULL, &queue);
for (link = g_queue_peek_head_link (&queue); link; link = g_list_next (link)) {
EMailPart *part = link->data;
CamelMimePart *mime_part;
CamelContentType *content_type;
if (!e_mail_part_get_is_attachment (part))
continue;
mime_part = e_mail_part_ref_mime_part (part);
if (!mime_part)
continue;
content_type = camel_mime_part_get_content_type (mime_part);
if (!content_type)
continue;
if (!just_inlines &&
camel_content_type_is (content_type, "text", "*") &&
camel_mime_part_get_filename (mime_part) == NULL) {
/* Do nothing if this is a text/anything without a
* filename, otherwise attach it too. */
} else if (camel_content_type_is (content_type, "image", "*") && (
camel_mime_part_get_content_id (mime_part) ||
camel_mime_part_get_content_location (mime_part))) {
e_html_editor_add_cid_part (editor, mime_part);
} else if (!just_inlines) {
e_msg_composer_attach (composer, mime_part);
}
g_object_unref (mime_part);
}
while (!g_queue_is_empty (&queue))
g_object_unref (g_queue_pop_head (&queue));
}
static void
handle_multipart_signed (EMsgComposer *composer,
CamelMultipart *multipart,

View File

@ -29,6 +29,7 @@
#include <shell/e-shell.h>
#include <composer/e-composer-header-table.h>
#include <em-format/e-mail-part-list.h>
/* Standard GObject macros */
#define E_TYPE_MSG_COMPOSER \
@ -186,6 +187,11 @@ void e_msg_composer_add_message_attachments
(EMsgComposer *composer,
CamelMimeMessage *message,
gboolean just_inlines);
void e_msg_composer_add_attachments_from_part_list
(EMsgComposer *composer,
EMailPartList *part_list,
gboolean just_inlines);
void e_msg_composer_request_close (EMsgComposer *composer);
gboolean e_msg_composer_can_close (EMsgComposer *composer,

View File

@ -2486,6 +2486,7 @@ forward_non_attached (EMsgComposer *composer,
EMailForwardStyle style)
{
CamelSession *session;
EMailPartList *part_list = NULL;
gchar *text, *forward, *subject;
guint32 validity_found = 0;
guint32 flags;
@ -2508,17 +2509,11 @@ forward_non_attached (EMsgComposer *composer,
g_free (subject);
forward = quoting_text (QUOTING_FORWARD, composer);
text = em_utils_message_to_html (session, message, forward, flags, NULL, NULL, NULL, &validity_found);
text = em_utils_message_to_html_ex (session, message, forward, flags, NULL, NULL, NULL, &validity_found, &part_list);
e_msg_composer_add_attachments_from_part_list (composer, part_list, FALSE);
if (text != NULL) {
CamelDataWrapper *content;
content = camel_medium_get_content (CAMEL_MEDIUM (message));
if (CAMEL_IS_MULTIPART (content))
e_msg_composer_add_message_attachments (
composer, message, FALSE);
e_msg_composer_set_body_text (composer, text, TRUE);
emu_add_composer_references_from_message (composer, message);
@ -2533,6 +2528,7 @@ forward_non_attached (EMsgComposer *composer,
}
g_clear_object (&session);
g_clear_object (&part_list);
g_free (forward);
}
@ -3597,7 +3593,8 @@ static void
composer_set_body (EMsgComposer *composer,
CamelMimeMessage *message,
EMailReplyStyle style,
EMailPartList *parts_list)
EMailPartList *parts_list,
EMailPartList **out_used_part_list)
{
gchar *text, *credits, *original;
ESource *identity_source;
@ -3625,9 +3622,9 @@ composer_set_body (EMsgComposer *composer,
break;
case E_MAIL_REPLY_STYLE_OUTLOOK:
original = quoting_text (QUOTING_ORIGINAL, composer);
text = em_utils_message_to_html (
text = em_utils_message_to_html_ex (
session, message, original, E_MAIL_FORMATTER_QUOTE_FLAG_HEADERS | keep_sig_flag,
parts_list, NULL, NULL, &validity_found);
parts_list, NULL, NULL, &validity_found, out_used_part_list);
e_msg_composer_set_body_text (composer, text, TRUE);
g_free (text);
g_free (original);
@ -3643,9 +3640,9 @@ composer_set_body (EMsgComposer *composer,
g_clear_object (&identity_source);
text = em_utils_message_to_html (
text = em_utils_message_to_html_ex (
session, message, credits, E_MAIL_FORMATTER_QUOTE_FLAG_CITE | keep_sig_flag,
parts_list, NULL, NULL, &validity_found);
parts_list, NULL, NULL, &validity_found, out_used_part_list);
g_free (credits);
e_msg_composer_set_body_text (composer, text, TRUE);
g_free (text);
@ -4484,6 +4481,7 @@ em_utils_reply_to_message (EMsgComposer *composer,
EShell *shell;
ESourceMailCompositionReplyStyle prefer_reply_style = E_SOURCE_MAIL_COMPOSITION_REPLY_STYLE_DEFAULT;
ESource *source;
EMailPartList *used_part_list = NULL;
EContentEditor *cnt_editor;
gchar *identity_uid = NULL, *identity_name = NULL, *identity_address = NULL;
guint32 flags;
@ -4566,7 +4564,6 @@ em_utils_reply_to_message (EMsgComposer *composer,
}
reply_setup_composer (composer, message, identity_uid, identity_name, identity_address, to, cc, folder, message_uid, postto);
e_msg_composer_add_message_attachments (composer, message, TRUE);
if (postto)
g_object_unref (postto);
@ -4617,7 +4614,10 @@ em_utils_reply_to_message (EMsgComposer *composer,
break;
}
composer_set_body (composer, message, style, parts_list);
composer_set_body (composer, message, style, parts_list, &used_part_list);
e_msg_composer_add_attachments_from_part_list (composer, used_part_list, TRUE);
g_clear_object (&used_part_list);
if (folder)
emu_set_source_headers (composer, folder, message_uid, flags);

View File

@ -1223,12 +1223,13 @@ is_only_text_part_in_this_level (GList *parts,
/**
* em_utils_message_to_html:
* @session: a #CamelSession
* @message:
* @credits:
* @flags: EMFormatQuote flags
* @source:
* @append: Text to append, can be NULL.
* @validity_found: if not NULL, then here will be set what validities
* @message: a #CamelMimeMessage
* @credits: (nullable): credits attribution string when quoting, or %NULL
* @flags: the %EMFormatQuote flags
* @part_list: (nullable): an #EMailPartList
* @prepend: (nulalble): text to prepend, or %NULL
* @append: (nullable): text to append, or %NULL
* @validity_found: (nullable): if not %NULL, then here will be set what validities
* had been found during message conversion. Value is a bit OR
* of EM_FORMAT_VALIDITY_FOUND_* constants.
*
@ -1236,16 +1237,55 @@ is_only_text_part_in_this_level (GList *parts,
* string is given.
*
* Return value: The html version as a NULL terminated string.
*
* See: em_utils_message_to_html_ex
**/
gchar *
em_utils_message_to_html (CamelSession *session,
CamelMimeMessage *message,
const gchar *credits,
guint32 flags,
EMailPartList *parts_list,
EMailPartList *part_list,
const gchar *prepend,
const gchar *append,
EMailPartValidityFlags *validity_found)
{
return em_utils_message_to_html_ex (session, message, credits, flags, part_list, prepend, append, validity_found, NULL);
}
/**
* em_utils_message_to_html_ex:
* @session: a #CamelSession
* @message: a #CamelMimeMessage
* @credits: (nullable): credits attribution string when quoting, or %NULL
* @flags: the %EMFormatQuote flags
* @part_list: (nullable): an #EMailPartList
* @prepend: (nulalble): text to prepend, or %NULL
* @append: (nullable): text to append, or %NULL
* @validity_found: (nullable): if not %NULL, then here will be set what validities
* had been found during message conversion. Value is a bit OR
* of EM_FORMAT_VALIDITY_FOUND_* constants.
* @out_part_list: (nullable): if not %NULL, sets it to the part list being
* used to generate the body. Unref it with g_object_unref(),
* when no longer needed.
*
* Convert a message to html, quoting if the @credits attribution
* string is given.
*
* Return value: The html version as a NULL terminated string.
*
* Since: 3.42
**/
gchar *
em_utils_message_to_html_ex (CamelSession *session,
CamelMimeMessage *message,
const gchar *credits,
guint32 flags,
EMailPartList *part_list,
const gchar *prepend,
const gchar *append,
EMailPartValidityFlags *validity_found,
EMailPartList **out_part_list)
{
EMailFormatter *formatter;
EMailParser *parser = NULL;
@ -1271,7 +1311,7 @@ em_utils_message_to_html (CamelSession *session,
e_mail_formatter_update_style (formatter,
gtk_widget_get_state_flags (GTK_WIDGET (window)));
if (parts_list == NULL) {
if (part_list == NULL) {
GSettings *settings;
gchar *charset;
@ -1285,13 +1325,13 @@ em_utils_message_to_html (CamelSession *session,
g_free (charset);
parser = e_mail_parser_new (session);
parts_list = e_mail_parser_parse_sync (parser, NULL, NULL, message, NULL);
part_list = e_mail_parser_parse_sync (parser, NULL, NULL, message, NULL);
} else {
g_object_ref (parts_list);
g_object_ref (part_list);
}
/* Return all found validities and possibly show hidden prefer-plain part */
e_mail_part_list_queue_parts (parts_list, NULL, &queue);
e_mail_part_list_queue_parts (part_list, NULL, &queue);
head = g_queue_peek_head_link (&queue);
for (link = head; link != NULL; link = g_list_next (link)) {
@ -1332,16 +1372,19 @@ em_utils_message_to_html (CamelSession *session,
stream, prepend, strlen (prepend), NULL, NULL, NULL);
e_mail_formatter_format_sync (
formatter, parts_list, stream, 0,
formatter, part_list, stream, 0,
E_MAIL_FORMATTER_MODE_PRINTING, NULL);
g_object_unref (formatter);
if (hidden_text_html_part != NULL)
hidden_text_html_part->is_hidden = TRUE;
g_object_unref (parts_list);
if (parser != NULL)
g_object_unref (parser);
if (out_part_list)
*out_part_list = part_list;
else
g_object_unref (part_list);
g_clear_object (&parser);
if (append != NULL && *append != '\0')
g_output_stream_write_all (

View File

@ -76,10 +76,19 @@ gchar * em_utils_message_to_html (CamelSession *session,
CamelMimeMessage *msg,
const gchar *credits,
guint32 flags,
struct _EMailPartList *parts_list,
struct _EMailPartList *part_list,
const gchar *prepend,
const gchar *append,
EMailPartValidityFlags *validity_found);
gchar * em_utils_message_to_html_ex (CamelSession *session,
CamelMimeMessage *message,
const gchar *credits,
guint32 flags,
EMailPartList *part_list,
const gchar *prepend,
const gchar *append,
EMailPartValidityFlags *validity_found,
EMailPartList **out_part_list);
void em_utils_empty_trash (GtkWidget *parent,
EMailSession *session);