[evolution] I#1311 - templates: Prefer message body selection as Reply does



commit b14d9ac54d8c4707c2fbd2d525eb7960e93c452e
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jan 14 17:11:36 2021 +0100

    I#1311 - templates: Prefer message body selection as Reply does
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/1311

 src/em-format/e-mail-part-list.c  |  41 +++
 src/em-format/e-mail-part-list.h  |   3 +
 src/mail/e-mail-reader-utils.c    | 718 ++++++++++++++++++--------------------
 src/mail/e-mail-reader-utils.h    |  17 +
 src/mail/e-mail-reader.c          |  50 +--
 src/mail/em-composer-utils.c      |  70 +++-
 src/mail/em-composer-utils.h      |  11 +-
 src/plugins/templates/templates.c |  29 +-
 8 files changed, 527 insertions(+), 412 deletions(-)
---
diff --git a/src/em-format/e-mail-part-list.c b/src/em-format/e-mail-part-list.c
index 42f29075c6..92ae1a1a7b 100644
--- a/src/em-format/e-mail-part-list.c
+++ b/src/em-format/e-mail-part-list.c
@@ -408,6 +408,47 @@ e_mail_part_list_is_empty (EMailPartList *part_list)
        return is_empty;
 }
 
+void
+e_mail_part_list_sum_validity (EMailPartList *part_list,
+                              EMailPartValidityFlags *out_validity_pgp_sum,
+                              EMailPartValidityFlags *out_validity_smime_sum)
+{
+       EMailPartValidityFlags validity_pgp_sum = 0;
+       EMailPartValidityFlags validity_smime_sum = 0;
+       GQueue queue = G_QUEUE_INIT;
+
+       g_return_if_fail (E_IS_MAIL_PART_LIST (part_list));
+
+       e_mail_part_list_queue_parts (part_list, NULL, &queue);
+
+       while (!g_queue_is_empty (&queue)) {
+               EMailPart *part = g_queue_pop_head (&queue);
+               GList *head, *link;
+
+               head = g_queue_peek_head_link (&part->validities);
+
+               for (link = head; link != NULL; link = g_list_next (link)) {
+                       EMailPartValidityPair *vpair = link->data;
+
+                       if (vpair == NULL)
+                               continue;
+
+                       if ((vpair->validity_type & E_MAIL_PART_VALIDITY_PGP) != 0)
+                               validity_pgp_sum |= vpair->validity_type;
+                       if ((vpair->validity_type & E_MAIL_PART_VALIDITY_SMIME) != 0)
+                               validity_smime_sum |= vpair->validity_type;
+               }
+
+               g_object_unref (part);
+       }
+
+       if (out_validity_pgp_sum)
+               *out_validity_pgp_sum = validity_pgp_sum;
+
+       if (out_validity_smime_sum)
+               *out_validity_smime_sum = validity_smime_sum;
+}
+
 /**
  * e_mail_part_list_get_registry:
  *
diff --git a/src/em-format/e-mail-part-list.h b/src/em-format/e-mail-part-list.h
index 1793bf16f3..db5c7c266b 100644
--- a/src/em-format/e-mail-part-list.h
+++ b/src/em-format/e-mail-part-list.h
@@ -72,6 +72,9 @@ guint         e_mail_part_list_queue_parts    (EMailPartList *part_list,
                                                 const gchar *part_id,
                                                 GQueue *result_queue);
 gboolean       e_mail_part_list_is_empty       (EMailPartList *part_list);
+void           e_mail_part_list_sum_validity   (EMailPartList *part_list,
+                                                EMailPartValidityFlags *out_validity_pgp_sum,
+                                                EMailPartValidityFlags *out_validity_smime_sum);
 
 CamelObjectBag *
                e_mail_part_list_get_registry   (void);
diff --git a/src/mail/e-mail-reader-utils.c b/src/mail/e-mail-reader-utils.c
index 90ac4d9d0d..ced107b7fd 100644
--- a/src/mail/e-mail-reader-utils.c
+++ b/src/mail/e-mail-reader-utils.c
@@ -1916,7 +1916,7 @@ typedef struct _CreateComposerData {
        EMailReader *reader;
        CamelFolder *folder;
        CamelMimeMessage *message;
-       gchar *message_uid;
+       const gchar *message_uid; /* Allocated on the string pool, use camel_pstring_strdup/free */
        gboolean keep_signature;
 
        EMailPartList *part_list;
@@ -1925,6 +1925,7 @@ typedef struct _CreateComposerData {
        CamelInternetAddress *address;
        EMailPartValidityFlags validity_pgp_sum;
        EMailPartValidityFlags validity_smime_sum;
+       gboolean is_selection;
 
        EMailForwardStyle forward_style;
 
@@ -1952,7 +1953,7 @@ create_composer_data_free (CreateComposerData *ccd)
                g_clear_object (&ccd->part_list);
                g_clear_object (&ccd->address);
                g_clear_object (&ccd->attached_part);
-               g_free (ccd->message_uid);
+               camel_pstring_free (ccd->message_uid);
                g_free (ccd->attached_subject);
                g_slice_free (CreateComposerData, ccd);
        }
@@ -2049,7 +2050,7 @@ mail_reader_edit_messages_cb (GObject *source_object,
                ccd->message = g_object_ref (CAMEL_MIME_MESSAGE (value));
 
                if (async_context->replace)
-                       ccd->message_uid = g_strdup ((const gchar *) key);
+                       ccd->message_uid = camel_pstring_strdup ((const gchar *) key);
 
                e_msg_composer_new (shell, mail_reader_edit_messages_composer_created_cb, ccd);
        }
@@ -2287,7 +2288,7 @@ mail_reader_forward_messages_cb (GObject *source_object,
                ccd->reader = g_object_ref (async_context->reader);
                ccd->folder = g_object_ref (folder);
                ccd->message = g_object_ref (message);
-               ccd->message_uid = g_strdup (message_uid);
+               ccd->message_uid = camel_pstring_strdup (message_uid);
                ccd->forward_style = async_context->forward_style;
 
                e_msg_composer_new (shell, mail_reader_forward_message_composer_created_cb, ccd);
@@ -2444,516 +2445,481 @@ maybe_mangle_plaintext_signature_delimiter (gchar **inout_text)
 }
 
 static void
-mail_reader_reply_composer_created_cb (GObject *object,
-                                      GAsyncResult *result,
-                                      gpointer user_data)
+mail_reader_reply_to_message_composer_created_cb (GObject *source_object,
+                                                 GAsyncResult *result,
+                                                 gpointer user_data)
 {
-       AsyncContext *async_context = user_data;
+       CreateComposerData *ccd = user_data;
        EMsgComposer *composer;
        GError *error = NULL;
 
-       g_return_if_fail (async_context != NULL);
+       g_return_if_fail (ccd != NULL);
 
        composer = e_msg_composer_new_finish (result, &error);
        if (error) {
-               g_warning ("%s: Failed to create msg composer: %s", G_STRFUNC, error->message);
+               g_warning ("%s: failed to create msg composer: %s", G_STRFUNC, error->message);
                g_clear_error (&error);
        } else {
-               CamelMimeMessage *message;
+               em_utils_reply_to_message (
+                       composer, ccd->message, ccd->folder, ccd->message_uid,
+                       ccd->reply_type, ccd->reply_style, ccd->is_selection ? NULL : ccd->part_list, 
ccd->address, E_MAIL_REPLY_FLAG_NONE);
 
-               message = e_mail_part_list_get_message (async_context->part_list);
+               em_composer_utils_update_security (composer, ccd->validity_pgp_sum, ccd->validity_smime_sum);
 
-               em_utils_reply_to_message (
-                       composer, message,
-                       async_context->folder,
-                       async_context->message_uid,
-                       async_context->reply_type,
-                       async_context->reply_style,
-                       async_context->part_list,
-                       async_context->address,
-                       E_MAIL_REPLY_FLAG_NONE);
+               e_mail_reader_composer_created (ccd->reader, composer, ccd->message);
+       }
+
+       create_composer_data_free (ccd);
+}
 
-               e_mail_reader_composer_created (async_context->reader, composer, message);
+static CamelMimeMessage *
+e_mail_reader_utils_selection_as_message (CamelMimeMessage *src_message,
+                                         const gchar *selection,
+                                         gboolean selection_is_html)
+{
+       const CamelNameValueArray *headers;
+       CamelMimeMessage *new_message;
+       guint ii, len;
+       gint length;
+
+       if (!selection || !*selection)
+               return NULL;
+
+       length = strlen (selection);
+       if ((selection_is_html && !html_contains_nonwhitespace (selection, length)) ||
+           (!selection_is_html && !plaintext_contains_nonwhitespace (selection, length))) {
+               return NULL;
        }
 
-       async_context_free (async_context);
+       new_message = camel_mime_message_new ();
+
+       if (src_message) {
+               /* Filter out "content-*" headers. */
+               headers = camel_medium_get_headers (CAMEL_MEDIUM (src_message));
+               len = camel_name_value_array_get_length (headers);
+               for (ii = 0; ii < len; ii++) {
+                       const gchar *header_name = NULL, *header_value = NULL;
+
+                       if (camel_name_value_array_get (headers, ii, &header_name, &header_value) &&
+                           header_name &&
+                           g_ascii_strncasecmp (header_name, "content-", 8) != 0) {
+                               camel_medium_add_header (CAMEL_MEDIUM (new_message), header_name, 
header_value);
+                       }
+               }
+       }
+
+       camel_medium_add_header (
+               CAMEL_MEDIUM (new_message),
+               "X-Evolution-Content-Source", "selection");
+
+       camel_mime_part_set_encoding (
+               CAMEL_MIME_PART (new_message),
+               CAMEL_TRANSFER_ENCODING_8BIT);
+
+       camel_mime_part_set_content (
+               CAMEL_MIME_PART (new_message),
+               selection,
+               length,
+               selection_is_html ? "text/html; charset=utf-8" : "text/plain; charset=utf-8");
+
+       return new_message;
 }
 
+typedef struct _SelectionOrMessageData {
+       GTask *task; /* not referenced */
+       EActivity *activity;
+       CamelFolder *folder;
+       CamelMimeMessage *preloaded_message;
+       CamelMimeMessage *message;
+       EMailPartList *part_list;
+       EMailPartValidityFlags orig_validity_pgp_sum;
+       EMailPartValidityFlags orig_validity_smime_sum;
+       const gchar *message_uid; /* Allocated on the string pool, use camel_pstring_strdup/free */
+       gboolean is_selection;
+       gboolean selection_is_html;
+} SelectionOrMessageData;
+
 static void
-mail_reader_reply_message_parsed (GObject *object,
-                                  GAsyncResult *result,
-                                  gpointer user_data)
+selection_or_message_data_free (gpointer ptr)
 {
-       EShell *shell;
-       EMailBackend *backend;
-       EMailReader *reader = E_MAIL_READER (object);
-       AsyncContext *async_context;
-       GError *local_error = NULL;
+       SelectionOrMessageData *smd = ptr;
 
-       async_context = (AsyncContext *) user_data;
+       if (smd) {
+               g_clear_object (&smd->activity);
+               g_clear_object (&smd->folder);
+               g_clear_object (&smd->preloaded_message);
+               g_clear_object (&smd->message);
+               g_clear_object (&smd->part_list);
+               camel_pstring_free (smd->message_uid);
+               g_slice_free (SelectionOrMessageData, smd);
+       }
+}
 
-       async_context->part_list = e_mail_reader_parse_message_finish (reader, result, &local_error);
+static void
+selection_or_message_message_parsed_cb (GObject *object,
+                                       GAsyncResult *result,
+                                       gpointer user_data)
+{
+       SelectionOrMessageData *smd = user_data;
+       GError *local_error = NULL;
+
+       smd->part_list = e_mail_reader_parse_message_finish (E_MAIL_READER (object), result, &local_error);
 
        if (local_error) {
                g_warn_if_fail (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED));
+               g_task_return_error (smd->task, local_error);
+       } else {
+               if (!smd->orig_validity_pgp_sum && !smd->orig_validity_smime_sum)
+                       e_mail_part_list_sum_validity (smd->part_list, &smd->orig_validity_pgp_sum, 
&smd->orig_validity_smime_sum);
 
-               g_clear_error (&local_error);
-               async_context_free (async_context);
-
-               return;
+               g_task_return_boolean (smd->task, TRUE);
        }
 
-       backend = e_mail_reader_get_backend (async_context->reader);
-       shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend));
-
-       e_msg_composer_new (shell, mail_reader_reply_composer_created_cb, async_context);
+       g_clear_object (&smd->task);
 }
 
 static void
-mail_reader_get_message_ready_cb (GObject *source_object,
-                                  GAsyncResult *result,
-                                  gpointer user_data)
+selection_or_message_got_message_cb (GObject *source_object,
+                                    GAsyncResult *result,
+                                    gpointer user_data)
 {
+       SelectionOrMessageData *smd = user_data;
        EActivity *activity;
        EAlertSink *alert_sink;
        GCancellable *cancellable;
-       CamelMimeMessage *message;
-       AsyncContext *async_context;
        GError *local_error = NULL;
 
-       async_context = (AsyncContext *) user_data;
-
-       activity = async_context->activity;
+       activity = smd->activity;
        alert_sink = e_activity_get_alert_sink (activity);
        cancellable = e_activity_get_cancellable (activity);
 
-       message = camel_folder_get_message_finish (
-               CAMEL_FOLDER (source_object), result, &local_error);
+       g_warn_if_fail (smd->message == NULL);
+       smd->message = camel_folder_get_message_finish (CAMEL_FOLDER (source_object), result, &local_error);
 
        /* Sanity check. */
        g_return_if_fail (
-               ((message != NULL) && (local_error == NULL)) ||
-               ((message == NULL) && (local_error != NULL)));
+               ((smd->message != NULL) && (local_error == NULL)) ||
+               ((smd->message == NULL) && (local_error != NULL)));
 
        if (e_activity_handle_cancellation (activity, local_error)) {
-               async_context_free (async_context);
-               g_error_free (local_error);
+               g_task_return_error (smd->task, local_error);
+               g_clear_object (&smd->task);
                return;
 
        } else if (local_error != NULL) {
                e_alert_submit (
                        alert_sink, "mail:no-retrieve-message",
                        local_error->message, NULL);
-               async_context_free (async_context);
-               g_error_free (local_error);
+               g_task_return_error (smd->task, local_error);
+               g_clear_object (&smd->task);
                return;
        }
 
        e_mail_reader_parse_message (
-               async_context->reader,
-               async_context->folder,
-               async_context->message_uid,
-               message,
+               E_MAIL_READER (g_task_get_source_object (smd->task)),
+               smd->folder,
+               smd->message_uid,
+               smd->message,
                cancellable,
-               mail_reader_reply_message_parsed,
-               async_context);
-
-       g_object_unref (message);
+               selection_or_message_message_parsed_cb,
+               smd);
 }
 
 static void
-mail_reader_reply_to_message_composer_created_cb (GObject *source_object,
-                                                 GAsyncResult *result,
-                                                 gpointer user_data)
+selection_or_message_get_message (EMailReader *reader,
+                                 SelectionOrMessageData *smd)
 {
-       CreateComposerData *ccd = user_data;
-       EMsgComposer *composer;
-       GError *error = NULL;
-
-       g_return_if_fail (ccd != NULL);
+       CamelObjectBag *registry;
+       GCancellable *cancellable;
+       gchar *mail_uri;
 
-       composer = e_msg_composer_new_finish (result, &error);
-       if (error) {
-               g_warning ("%s: failed to create msg composer: %s", G_STRFUNC, error->message);
-               g_clear_error (&error);
-       } else {
-               em_utils_reply_to_message (
-                       composer, ccd->message, ccd->folder, ccd->message_uid,
-                       ccd->reply_type, ccd->reply_style, ccd->part_list, ccd->address, 
E_MAIL_REPLY_FLAG_NONE);
+       g_return_if_fail (E_IS_MAIL_READER (reader));
+       g_return_if_fail (smd != NULL);
 
-               if (ccd->validity_pgp_sum != 0 || ccd->validity_smime_sum != 0) {
-                       GtkToggleAction *action;
-                       GSettings *settings;
-                       gboolean sign_reply;
+       smd->is_selection = FALSE;
 
-                       settings = e_util_ref_settings ("org.gnome.evolution.mail");
-                       sign_reply = g_settings_get_boolean (settings, "composer-sign-reply-if-signed");
-                       g_object_unref (settings);
+       registry = e_mail_part_list_get_registry ();
+       mail_uri = e_mail_part_build_uri (smd->folder, smd->message_uid, NULL, NULL);
+       smd->part_list = camel_object_bag_get (registry, mail_uri);
+       g_free (mail_uri);
 
-                       if ((ccd->validity_pgp_sum & E_MAIL_PART_VALIDITY_PGP) != 0) {
-                               if (sign_reply && (ccd->validity_pgp_sum & E_MAIL_PART_VALIDITY_SIGNED) != 0) 
{
-                                       action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_PGP_SIGN (composer));
-                                       gtk_toggle_action_set_active (action, TRUE);
-                               }
+       if (smd->part_list) {
+               g_warn_if_fail (smd->message == NULL);
+               if (smd->preloaded_message)
+                       smd->message = smd->preloaded_message;
+               else
+                       smd->message = e_mail_part_list_get_message (smd->part_list);
 
-                               if ((ccd->validity_pgp_sum & E_MAIL_PART_VALIDITY_ENCRYPTED) != 0) {
-                                       action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_PGP_ENCRYPT (composer));
-                                       gtk_toggle_action_set_active (action, TRUE);
-                               }
-                       }
+               if (smd->message)
+                       g_object_ref (smd->message);
+               else
+                       g_clear_object (&smd->part_list);
 
-                       if ((ccd->validity_smime_sum & E_MAIL_PART_VALIDITY_SMIME) != 0) {
-                               if (sign_reply && (ccd->validity_smime_sum & E_MAIL_PART_VALIDITY_SIGNED) != 
0) {
-                                       action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_SMIME_SIGN (composer));
-                                       gtk_toggle_action_set_active (action, TRUE);
-                               }
+               if (smd->message) {
+                       e_mail_part_list_sum_validity (smd->part_list, &smd->orig_validity_pgp_sum, 
&smd->orig_validity_smime_sum);
 
-                               if ((ccd->validity_smime_sum & E_MAIL_PART_VALIDITY_ENCRYPTED) != 0) {
-                                       action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_SMIME_ENCRYPT 
(composer));
-                                       gtk_toggle_action_set_active (action, TRUE);
-                               }
-                       }
+                       g_task_return_boolean (smd->task, TRUE);
+                       g_clear_object (&smd->task);
+                       return;
                }
-
-               e_mail_reader_composer_created (ccd->reader, composer, ccd->message);
        }
 
-       create_composer_data_free (ccd);
+       cancellable = g_task_get_cancellable (smd->task);
+
+       smd->activity = e_mail_reader_new_activity (reader);
+       e_activity_set_cancellable (smd->activity, cancellable);
+
+       if (smd->preloaded_message) {
+               g_warn_if_fail (smd->message == NULL);
+               smd->message = g_object_ref (smd->preloaded_message);
+
+               e_mail_reader_parse_message (
+                       reader,
+                       smd->folder,
+                       smd->message_uid,
+                       smd->message,
+                       cancellable,
+                       selection_or_message_message_parsed_cb,
+                       smd);
+       } else {
+               camel_folder_get_message (
+                       smd->folder,
+                       smd->message_uid,
+                       G_PRIORITY_DEFAULT,
+                       cancellable,
+                       selection_or_message_got_message_cb,
+                       smd);
+       }
 }
 
 static void
-e_mail_reader_reply_to_message_with_selection (EMailReader *reader,
-                                              CamelMimeMessage *src_message,
-                                              EMailReplyType reply_type,
-                                              const gchar *selection,
-                                              gboolean selection_is_html)
+selection_or_message_got_selection_jsc_cb (GObject *source_object,
+                                          GAsyncResult *result,
+                                          gpointer user_data)
 {
-       EShell *shell;
-       EMailBackend *backend;
-       EShellBackend *shell_backend;
-       EMailDisplay *display;
-       EMailPartList *part_list = NULL;
-       GtkWidget *message_list;
+       SelectionOrMessageData *smd = user_data;
        CamelMimeMessage *new_message;
-       CamelInternetAddress *address = NULL;
-       CamelFolder *folder;
-       EMailReplyStyle reply_style;
-       EWebView *web_view;
-       const CamelNameValueArray *headers;
-       guint ii, len;
-       const gchar *uid;
-       gint length;
-       gchar *mail_uri;
-       CamelObjectBag *registry;
-       CreateComposerData *ccd;
-       EMailPartValidityFlags validity_pgp_sum = 0;
-       EMailPartValidityFlags validity_smime_sum = 0;
-
-       /* This handles quoting only selected text in the reply.  If
-        * nothing is selected or only whitespace is selected, fall
-        * back to the normal em_utils_reply_to_message(). */
-
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       backend = e_mail_reader_get_backend (reader);
-       display = e_mail_reader_get_mail_display (reader);
-       message_list = e_mail_reader_get_message_list (reader);
-       reply_style = e_mail_reader_get_reply_style (reader);
-
-       shell_backend = E_SHELL_BACKEND (backend);
-       shell = e_shell_backend_get_shell (shell_backend);
-
-       web_view = E_WEB_VIEW (display);
-
-       if (reply_type == E_MAIL_REPLY_TO_RECIPIENT) {
-               const gchar *uri;
+       gchar *selection;
+       GSList *texts = NULL;
+       GError *error = NULL;
 
-               uri = e_web_view_get_selected_uri (web_view);
+       g_return_if_fail (smd != NULL);
+       g_return_if_fail (E_IS_WEB_VIEW (source_object));
 
-               if (uri) {
-                       CamelURL *curl;
+       if (!e_web_view_jsc_get_selection_finish (WEBKIT_WEB_VIEW (source_object), result, &texts, &error)) {
+               texts = NULL;
+               g_warning ("%s: Failed to get view selection: %s", G_STRFUNC, error ? error->message : 
"Unknown error");
+       }
 
-                       curl = camel_url_new (uri, NULL);
+       g_clear_error (&error);
 
-                       if (curl && curl->path && *curl->path) {
-                               address = camel_internet_address_new ();
-                               if (camel_address_decode (
-                                               CAMEL_ADDRESS (address),
-                                               curl->path) < 0) {
-                                       g_object_unref (address);
-                                       address = NULL;
-                               }
-                       }
+       selection = texts ? texts->data : NULL;
 
-                       if (curl)
-                               camel_url_free (curl);
-               }
+       if (selection && !smd->selection_is_html) {
+               maybe_mangle_plaintext_signature_delimiter (&selection);
+               texts->data = selection;
        }
 
-       uid = MESSAGE_LIST (message_list)->cursor_uid;
-       g_return_if_fail (uid != NULL);
+       new_message = e_mail_reader_utils_selection_as_message (smd->message, selection, 
smd->selection_is_html);
 
-       folder = e_mail_reader_ref_folder (reader);
+       smd->is_selection = new_message != NULL;
 
-       if (!gtk_widget_get_visible (GTK_WIDGET (web_view)))
-               goto whole_message;
+       if (new_message) {
+               g_clear_object (&smd->message);
+               smd->message = new_message;
+       }
 
-       registry = e_mail_part_list_get_registry ();
-       mail_uri = e_mail_part_build_uri (folder, uid, NULL, NULL);
-       part_list = camel_object_bag_get (registry, mail_uri);
-       g_free (mail_uri);
+       g_task_return_boolean (smd->task, TRUE);
+       g_clear_object (&smd->task);
 
-       if (!part_list) {
-               goto whole_message;
-       } else {
-               GQueue queue = G_QUEUE_INIT;
+       g_slist_free_full (texts, g_free);
+}
 
-               e_mail_part_list_queue_parts (part_list, NULL, &queue);
+void
+e_mail_reader_utils_get_selection_or_message (EMailReader *reader,
+                                             CamelMimeMessage *preloaded_message,
+                                             GCancellable *cancellable,
+                                             GAsyncReadyCallback callback,
+                                             gpointer user_data)
+{
+       SelectionOrMessageData *smd;
+       EMailDisplay *display;
+       EWebView *web_view;
+       GtkWidget *message_list;
+       const gchar *uid;
 
-               while (!g_queue_is_empty (&queue)) {
-                       EMailPart *part = g_queue_pop_head (&queue);
-                       GList *head, *link;
+       message_list = e_mail_reader_get_message_list (reader);
 
-                       head = g_queue_peek_head_link (&part->validities);
+       uid = MESSAGE_LIST (message_list)->cursor_uid;
+       g_return_if_fail (uid != NULL);
 
-                       for (link = head; link != NULL; link = g_list_next (link)) {
-                               EMailPartValidityPair *vpair = link->data;
+       smd = g_slice_new0 (SelectionOrMessageData);
+       smd->task = g_task_new (reader, cancellable, callback, user_data);
+       g_task_set_source_tag (smd->task, e_mail_reader_utils_get_selection_or_message);
+       g_task_set_task_data (smd->task, smd, selection_or_message_data_free);
 
-                               if (vpair == NULL)
-                                       continue;
+       display = e_mail_reader_get_mail_display (reader);
+       web_view = E_WEB_VIEW (display);
 
-                               if ((vpair->validity_type & E_MAIL_PART_VALIDITY_PGP) != 0)
-                                       validity_pgp_sum |= vpair->validity_type;
-                               if ((vpair->validity_type & E_MAIL_PART_VALIDITY_SMIME) != 0)
-                                       validity_smime_sum |= vpair->validity_type;
-                       }
+       smd->message_uid = camel_pstring_strdup (uid);
+       smd->folder = e_mail_reader_ref_folder (reader);
 
-                       g_object_unref (part);
-               }
-       }
+       if (preloaded_message)
+               smd->preloaded_message = g_object_ref (preloaded_message);
 
-       if (src_message == NULL) {
-               src_message = e_mail_part_list_get_message (part_list);
-               g_return_if_fail (src_message != NULL);
-       }
+       if (gtk_widget_get_visible (GTK_WIDGET (web_view)) &&
+           e_web_view_has_selection (web_view)) {
+               EMailPartList *part_list;
+               CamelMimeMessage *message = NULL;
 
-       g_clear_object (&part_list);
+               part_list = e_mail_display_get_part_list (display);
+               if (part_list)
+                       message = e_mail_part_list_get_message (part_list);
 
-       if (!e_web_view_has_selection (web_view))
-               goto whole_message;
+               if (message) {
+                       CamelContentType *ct;
 
-       if (selection == NULL || *selection == '\0')
-               goto whole_message;
+                       e_mail_part_list_sum_validity (part_list, &smd->orig_validity_pgp_sum, 
&smd->orig_validity_smime_sum);
 
-       length = strlen (selection);
-       if ((selection_is_html && !html_contains_nonwhitespace (selection, length)) ||
-           (!selection_is_html && !plaintext_contains_nonwhitespace (selection, length)))
-               goto whole_message;
+                       smd->message = g_object_ref (message);
+                       smd->part_list = g_object_ref (part_list);
 
-       new_message = camel_mime_message_new ();
+                       ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (message));
 
-       /* Filter out "content-*" headers. */
-       headers = camel_medium_get_headers (CAMEL_MEDIUM (src_message));
-       len = camel_name_value_array_get_length (headers);
-       for (ii = 0; ii < len; ii++) {
-               const gchar *header_name = NULL, *header_value = NULL;
+                       if (camel_content_type_is (ct, "text", "plain")) {
+                               smd->selection_is_html = FALSE;
+                               e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (web_view), 
E_TEXT_FORMAT_PLAIN, NULL,
+                                       selection_or_message_got_selection_jsc_cb, smd);
+                       } else {
+                               smd->selection_is_html = TRUE;
+                               e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (web_view), E_TEXT_FORMAT_HTML, 
NULL,
+                                       selection_or_message_got_selection_jsc_cb, smd);
+                       }
 
-               if (camel_name_value_array_get (headers, ii, &header_name, &header_value) &&
-                   header_name &&
-                   g_ascii_strncasecmp (header_name, "content-", 8) != 0) {
-                       camel_medium_add_header (CAMEL_MEDIUM (new_message), header_name, header_value);
+                       return;
                }
        }
 
-       camel_medium_add_header (
-               CAMEL_MEDIUM (new_message),
-               "X-Evolution-Content-Source", "selection");
+       selection_or_message_get_message (reader, smd);
+}
 
-       camel_mime_part_set_encoding (
-               CAMEL_MIME_PART (new_message),
-               CAMEL_TRANSFER_ENCODING_8BIT);
+CamelMimeMessage *
+e_mail_reader_utils_get_selection_or_message_finish (EMailReader *reader,
+                                                    GAsyncResult *result,
+                                                    gboolean *out_is_selection,
+                                                    CamelFolder **out_folder,
+                                                    const gchar **out_message_uid, /* free with 
camel_pstring_free() */
+                                                    EMailPartList **out_part_list,
+                                                    EMailPartValidityFlags *out_orig_validity_pgp_sum,
+                                                    EMailPartValidityFlags *out_orig_validity_smime_sum,
+                                                    GError **error)
+{
+       SelectionOrMessageData *smd;
+       CamelMimeMessage *message;
+       GTask *task;
 
-       camel_mime_part_set_content (
-               CAMEL_MIME_PART (new_message),
-               selection,
-               length,
-               selection_is_html ? "text/html; charset=utf-8" : "text/plain; charset=utf-8");
+       g_return_val_if_fail (E_IS_MAIL_READER (reader), NULL);
+       g_return_val_if_fail (g_task_is_valid (result, reader), NULL);
+       g_return_val_if_fail (g_async_result_is_tagged (result, 
e_mail_reader_utils_get_selection_or_message), NULL);
 
-       ccd = create_composer_data_new ();
-       ccd->reader = g_object_ref (reader);
-       ccd->folder = g_object_ref (folder);
-       ccd->message_uid = g_strdup (uid);
-       ccd->message = new_message;
-       ccd->reply_type = reply_type;
-       ccd->reply_style = reply_style;
-       ccd->address = address ? g_object_ref (address) : NULL;
-       ccd->validity_pgp_sum = validity_pgp_sum;
-       ccd->validity_smime_sum = validity_smime_sum;
+       task = G_TASK (result);
 
-       e_msg_composer_new (shell, mail_reader_reply_to_message_composer_created_cb, ccd);
+       smd = g_task_get_task_data (task);
+       g_return_val_if_fail (smd != NULL, NULL);
 
-       goto exit;
+       if (g_task_propagate_boolean (task, error)) {
+               message = g_steal_pointer (&smd->message);
 
-whole_message:
-       if (src_message == NULL) {
-               EActivity *activity;
-               GCancellable *cancellable;
-               AsyncContext *async_context;
+               if (out_is_selection)
+                       *out_is_selection = smd->is_selection;
 
-               activity = e_mail_reader_new_activity (reader);
-               cancellable = e_activity_get_cancellable (activity);
+               if (out_folder)
+                       *out_folder = g_steal_pointer (&smd->folder);
 
-               async_context = g_slice_new0 (AsyncContext);
-               async_context->activity = g_object_ref (activity);
-               async_context->folder = g_object_ref (folder);
-               async_context->reader = g_object_ref (reader);
-               async_context->message_uid = g_strdup (uid);
-               async_context->reply_type = reply_type;
-               async_context->reply_style = reply_style;
+               if (out_message_uid)
+                       *out_message_uid = g_steal_pointer (&smd->message_uid);
 
-               if (address != NULL)
-                       async_context->address = g_object_ref (address);
+               if (out_part_list)
+                       *out_part_list = g_steal_pointer (&smd->part_list);
 
-               camel_folder_get_message (
-                       async_context->folder,
-                       async_context->message_uid,
-                       G_PRIORITY_DEFAULT,
-                       cancellable,
-                       mail_reader_get_message_ready_cb,
-                       async_context);
-
-               g_object_unref (activity);
+               if (out_orig_validity_pgp_sum)
+                       *out_orig_validity_pgp_sum = smd->orig_validity_pgp_sum;
 
+               if (out_orig_validity_smime_sum)
+                       *out_orig_validity_smime_sum = smd->orig_validity_smime_sum;
        } else {
-               ccd = create_composer_data_new ();
-               ccd->reader = g_object_ref (reader);
-               ccd->folder = g_object_ref (folder);
-               ccd->message_uid = g_strdup (uid);
-               ccd->message = g_object_ref (src_message);
-               ccd->reply_type = reply_type;
-               ccd->reply_style = reply_style;
-               ccd->part_list = part_list ? g_object_ref (part_list) : NULL;
-               ccd->address = address ? g_object_ref (address) : NULL;
-               ccd->validity_pgp_sum = validity_pgp_sum;
-               ccd->validity_smime_sum = validity_smime_sum;
-
-               e_msg_composer_new (shell, mail_reader_reply_to_message_composer_created_cb, ccd);
+               message = NULL;
        }
 
-exit:
-       g_clear_object (&address);
-       g_clear_object (&folder);
+       return message;
 }
 
-typedef struct _GetSelectionData {
-       EMailReader *reader;
-       CamelMimeMessage *src_message;
-       EMailReplyType reply_type;
-       gboolean selection_is_html;
-} GetSelectionData;
-
 static void
-reply_got_message_selection_jsc_cb (GObject *source_object,
-                                   GAsyncResult *result,
-                                   gpointer user_data)
+reply_to_message_got_message_cb (GObject *source_object,
+                                GAsyncResult *result,
+                                gpointer user_data)
 {
-       GetSelectionData *gsd = user_data;
-       gchar *selection;
-       GSList *texts = NULL;
+       EMailReplyType reply_type = GPOINTER_TO_INT (user_data);
+       EMailReader *reader = E_MAIL_READER (source_object);
+       EShell *shell;
+       CreateComposerData *ccd;
        GError *error = NULL;
 
-       g_return_if_fail (gsd != NULL);
-       g_return_if_fail (E_IS_WEB_VIEW (source_object));
-
-       if (!e_web_view_jsc_get_selection_finish (WEBKIT_WEB_VIEW (source_object), result, &texts, &error)) {
-               texts = NULL;
-               g_warning ("%s: Failed to get view selection: %s", G_STRFUNC, error ? error->message : 
"Unknown error");
-       }
-
-       selection = texts ? texts->data : NULL;
-
-       if (selection && !gsd->selection_is_html) {
-               maybe_mangle_plaintext_signature_delimiter (&selection);
-               texts->data = selection;
-       }
-
-       e_mail_reader_reply_to_message_with_selection (gsd->reader, gsd->src_message, gsd->reply_type, 
selection, gsd->selection_is_html);
-
-       g_slist_free_full (texts, g_free);
-       g_clear_error (&error);
-       g_clear_object (&gsd->reader);
-       g_clear_object (&gsd->src_message);
-       g_slice_free (GetSelectionData, gsd);
-}
-
-void
-e_mail_reader_reply_to_message (EMailReader *reader,
-                                CamelMimeMessage *src_message,
-                                EMailReplyType reply_type)
-{
-       CamelContentType *ct;
-       GetSelectionData *gsd;
-       EMailDisplay *mail_display;
-       EMailPartList *part_list = NULL;
-       EWebView *web_view;
-
-       g_return_if_fail (E_IS_MAIL_READER (reader));
-
-       mail_display = e_mail_reader_get_mail_display (reader);
-       g_return_if_fail (E_IS_MAIL_DISPLAY (mail_display));
+       ccd = create_composer_data_new ();
+       ccd->reader = g_object_ref (reader);
+       ccd->reply_type = reply_type;
+       ccd->reply_style = e_mail_reader_get_reply_style (reader);
 
-       web_view = E_WEB_VIEW (mail_display);
+       ccd->message = e_mail_reader_utils_get_selection_or_message_finish (reader, result,
+                       &ccd->is_selection, &ccd->folder, &ccd->message_uid, &ccd->part_list,
+                       &ccd->validity_pgp_sum, &ccd->validity_smime_sum, &error);
 
-       if (!gtk_widget_get_visible (GTK_WIDGET (web_view)) ||
-           !e_web_view_has_selection (web_view)) {
-               e_mail_reader_reply_to_message_with_selection (reader, src_message, reply_type, NULL, FALSE);
+       if (!ccd->message) {
+               if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+                       g_warning ("%s: Failed to get message: %s", G_STRFUNC, error ? error->message : 
"Unknown error");
+               g_clear_error (&error);
+               create_composer_data_free (ccd);
                return;
        }
 
-       if (!src_message) {
-               CamelFolder *folder;
-               GtkWidget *message_list;
-               const gchar *uid;
-               gchar *mail_uri;
+       if (reply_type == E_MAIL_REPLY_TO_RECIPIENT) {
+               EMailDisplay *display;
+               const gchar *uri;
 
-               message_list = e_mail_reader_get_message_list (reader);
+               display = e_mail_reader_get_mail_display (reader);
+               uri = e_web_view_get_selected_uri (E_WEB_VIEW (display));
 
-               uid = MESSAGE_LIST (message_list)->cursor_uid;
-               g_return_if_fail (uid != NULL);
+               if (uri) {
+                       CamelURL *curl;
 
-               folder = e_mail_reader_ref_folder (reader);
-               mail_uri = e_mail_part_build_uri (folder, uid, NULL, NULL);
-               part_list = camel_object_bag_get (e_mail_part_list_get_registry (), mail_uri);
-               g_clear_object (&folder);
-               g_free (mail_uri);
+                       curl = camel_url_new (uri, NULL);
 
-               src_message = part_list ? e_mail_part_list_get_message (part_list) : NULL;
+                       if (curl && curl->path && *curl->path) {
+                               ccd->address = camel_internet_address_new ();
+                               if (camel_address_decode (CAMEL_ADDRESS (ccd->address), curl->path) < 0) {
+                                       g_clear_object (&ccd->address);
+                               }
+                       }
 
-               if (!src_message) {
-                       e_mail_reader_reply_to_message_with_selection (reader, src_message, reply_type, NULL, 
FALSE);
-                       g_clear_object (&part_list);
-                       return;
+                       if (curl)
+                               camel_url_free (curl);
                }
        }
 
-       gsd = g_slice_new0 (GetSelectionData);
-       gsd->reader = g_object_ref (reader);
-       gsd->src_message = src_message ? g_object_ref (src_message) : NULL;
-       gsd->reply_type = reply_type;
+       shell = e_shell_backend_get_shell (E_SHELL_BACKEND (e_mail_reader_get_backend (reader)));
 
-       ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (src_message));
+       e_msg_composer_new (shell, mail_reader_reply_to_message_composer_created_cb, ccd);
+}
 
-       if (camel_content_type_is (ct, "text", "plain")) {
-               gsd->selection_is_html = FALSE;
-               e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (web_view), E_TEXT_FORMAT_PLAIN, NULL,
-                       reply_got_message_selection_jsc_cb, gsd);
-       } else {
-               gsd->selection_is_html = TRUE;
-               e_web_view_jsc_get_selection (WEBKIT_WEB_VIEW (web_view), E_TEXT_FORMAT_HTML, NULL,
-                       reply_got_message_selection_jsc_cb, gsd);
-       }
+void
+e_mail_reader_reply_to_message (EMailReader *reader,
+                                CamelMimeMessage *src_message,
+                                EMailReplyType reply_type)
+{
+       g_return_if_fail (E_IS_MAIL_READER (reader));
 
-       g_clear_object (&part_list);
+       e_mail_reader_utils_get_selection_or_message (reader, src_message, NULL,
+               reply_to_message_got_message_cb, GINT_TO_POINTER (reply_type));
 }
 
 static void
diff --git a/src/mail/e-mail-reader-utils.h b/src/mail/e-mail-reader-utils.h
index 829195fd47..2250711efa 100644
--- a/src/mail/e-mail-reader-utils.h
+++ b/src/mail/e-mail-reader-utils.h
@@ -115,6 +115,23 @@ EMailPartList *    e_mail_reader_parse_message_finish
 gboolean       e_mail_reader_utils_get_mark_seen_setting
                                                (EMailReader *reader,
                                                 gint *out_timeout_interval);
+void           e_mail_reader_utils_get_selection_or_message
+                                               (EMailReader *reader,
+                                                CamelMimeMessage *preloaded_message,
+                                                GCancellable *cancellable,
+                                                GAsyncReadyCallback callback,
+                                                gpointer user_data);
+CamelMimeMessage *
+               e_mail_reader_utils_get_selection_or_message_finish
+                                               (EMailReader *reader,
+                                                GAsyncResult *result,
+                                                gboolean *out_is_selection,
+                                                CamelFolder **out_folder,
+                                                const gchar **out_message_uid, /* free with 
camel_pstring_free() */
+                                                EMailPartList **out_part_list,
+                                                EMailPartValidityFlags *out_orig_validity_pgp_sum,
+                                                EMailPartValidityFlags *out_orig_validity_smime_sum,
+                                                GError **error);
 
 G_END_DECLS
 
diff --git a/src/mail/e-mail-reader.c b/src/mail/e-mail-reader.c
index e44b4659c1..5acb1c98a8 100644
--- a/src/mail/e-mail-reader.c
+++ b/src/mail/e-mail-reader.c
@@ -69,7 +69,10 @@ typedef struct _EMailReaderPrivate EMailReaderPrivate;
 struct _EMailReaderClosure {
        EMailReader *reader;
        EActivity *activity;
+       CamelMimeMessage *message;
+       CamelFolder *folder;
        gchar *message_uid;
+       gboolean selection_is_html;
 };
 
 struct _EMailReaderPrivate {
@@ -137,12 +140,10 @@ mail_reader_set_display_formatter_for_message (EMailReader *reader,
 static void
 mail_reader_closure_free (EMailReaderClosure *closure)
 {
-       if (closure->reader != NULL)
-               g_object_unref (closure->reader);
-
-       if (closure->activity != NULL)
-               g_object_unref (closure->activity);
-
+       g_clear_object (&closure->reader);
+       g_clear_object (&closure->activity);
+       g_clear_object (&closure->folder);
+       g_clear_object (&closure->message);
        g_free (closure->message_uid);
 
        g_slice_free (EMailReaderClosure, closure);
@@ -1708,18 +1709,25 @@ action_mail_reply_all_cb (GtkAction *action,
 }
 
 static void
-action_mail_reply_alternative_got_message (CamelFolder *folder,
+action_mail_reply_alternative_got_message (GObject *source_object,
                                           GAsyncResult *result,
-                                          EMailReaderClosure *closure)
+                                          gpointer user_data)
 {
+       EMailReaderClosure *closure = user_data;
        EAlertSink *alert_sink;
-       EMailDisplay *mail_display;
        CamelMimeMessage *message;
+       gboolean is_selection;
+       CamelFolder *folder = NULL;
+       const gchar *message_uid = NULL;
+       EMailPartList *part_list = NULL;
+       EMailPartValidityFlags validity_pgp_sum = 0;
+       EMailPartValidityFlags validity_smime_sum = 0;
        GError *error = NULL;
 
        alert_sink = e_activity_get_alert_sink (closure->activity);
 
-       message = camel_folder_get_message_finish (folder, result, &error);
+       message = e_mail_reader_utils_get_selection_or_message_finish (E_MAIL_READER (source_object), result,
+                       &is_selection, &folder, &message_uid, &part_list, &validity_pgp_sum, 
&validity_smime_sum, &error);
 
        if (e_activity_handle_cancellation (closure->activity, error)) {
                g_warn_if_fail (message == NULL);
@@ -1741,16 +1749,18 @@ action_mail_reply_alternative_got_message (CamelFolder *folder,
 
        g_clear_object (&closure->activity);
 
-       mail_display = e_mail_reader_get_mail_display (closure->reader);
-
        em_utils_reply_alternative (e_mail_reader_get_window (closure->reader),
                e_shell_backend_get_shell (E_SHELL_BACKEND (e_mail_reader_get_backend (closure->reader))),
-               alert_sink, message, folder, closure->message_uid,
+               alert_sink, message, folder, message_uid,
                e_mail_reader_get_reply_style (closure->reader),
-               mail_display ? e_mail_display_get_part_list (mail_display) : NULL);
+               is_selection ? NULL : part_list, validity_pgp_sum, validity_smime_sum);
 
-       g_object_unref (message);
        mail_reader_closure_free (closure);
+       camel_pstring_free (message_uid);
+       g_clear_object (&message);
+       g_clear_object (&folder);
+       g_clear_object (&part_list);
+       g_clear_error (&error);
 }
 
 static void
@@ -1760,7 +1770,6 @@ action_mail_reply_alternative_cb (GtkAction *action,
        EActivity *activity;
        GCancellable *cancellable;
        EMailReaderClosure *closure;
-       CamelFolder *folder;
        GtkWidget *message_list;
        const gchar *message_uid;
 
@@ -1774,16 +1783,9 @@ action_mail_reply_alternative_cb (GtkAction *action,
        closure = g_slice_new0 (EMailReaderClosure);
        closure->activity = activity;
        closure->reader = g_object_ref (reader);
-       closure->message_uid = g_strdup (message_uid);
-
-       folder = e_mail_reader_ref_folder (reader);
 
-       camel_folder_get_message (
-               folder, message_uid, G_PRIORITY_DEFAULT,
-               cancellable, (GAsyncReadyCallback)
+       e_mail_reader_utils_get_selection_or_message (reader, NULL, cancellable,
                action_mail_reply_alternative_got_message, closure);
-
-       g_clear_object (&folder);
 }
 
 static void
diff --git a/src/mail/em-composer-utils.c b/src/mail/em-composer-utils.c
index 9a2cc6684a..944347064a 100644
--- a/src/mail/em-composer-utils.c
+++ b/src/mail/em-composer-utils.c
@@ -3701,6 +3701,8 @@ typedef struct _AltReplyContext {
        EMailReplyStyle style;
        guint32 flags;
        gboolean template_preserve_subject;
+       EMailPartValidityFlags validity_pgp_sum;
+       EMailPartValidityFlags validity_smime_sum;
 } AltReplyContext;
 
 static void
@@ -3811,6 +3813,8 @@ alt_reply_composer_created_cb (GObject *source_object,
                                context->folder, context->message_uid, context->type, context->style,
                                context->source, NULL, context->flags | E_MAIL_REPLY_FLAG_FORCE_SENDER_REPLY);
                }
+
+               em_composer_utils_update_security (composer, context->validity_pgp_sum, 
context->validity_smime_sum);
        } else {
                e_alert_submit (context->alert_sink, "mail-composer:failed-create-composer",
                        error ? error->message : _("Unknown error"), NULL);
@@ -3977,6 +3981,8 @@ emcu_create_templates_combo (EShell *shell,
  * @message_uid: (nullable): the UID of @message, or %NULL
  * @style: the reply style to use
  * @source: (nullable): source to inherit view settings from
+ * @validity_pgp_sum: a bit-or of #EMailPartValidityFlags for PGP from original message part list
+ * @validity_smime_sum: a bit-or of #EMailPartValidityFlags for S/MIME from original message part list
  *
  * This is similar to em_utils_reply_to_message(), except it asks user to
  * change some settings before sending. It calls em_utils_reply_to_message()
@@ -3992,7 +3998,9 @@ em_utils_reply_alternative (GtkWindow *parent,
                            CamelFolder *folder,
                            const gchar *message_uid,
                            EMailReplyStyle default_style,
-                           EMailPartList *source)
+                           EMailPartList *source,
+                           EMailPartValidityFlags validity_pgp_sum,
+                           EMailPartValidityFlags validity_smime_sum)
 {
        GtkWidget *dialog, *widget, *style_label;
        GtkBox *hbox, *vbox;
@@ -4336,6 +4344,8 @@ em_utils_reply_alternative (GtkWindow *parent,
                context->message_uid = g_strdup (message_uid);
                context->style = E_MAIL_REPLY_STYLE_UNKNOWN;
                context->flags = E_MAIL_REPLY_FLAG_FORCE_STYLE;
+               context->validity_pgp_sum = validity_pgp_sum;
+               context->validity_smime_sum = validity_smime_sum;
 
                if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (style_quote)))
                        context->style = E_MAIL_REPLY_STYLE_QUOTED;
@@ -4921,3 +4931,61 @@ em_utils_add_installed_languages (GtkComboBoxText *combo)
        if (n_langs > 10)
                gtk_combo_box_set_wrap_width (GTK_COMBO_BOX (combo), 5);
 }
+
+void
+em_composer_utils_update_security (EMsgComposer *composer,
+                                  EMailPartValidityFlags validity_pgp_sum,
+                                  EMailPartValidityFlags validity_smime_sum)
+{
+       g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+       if (validity_pgp_sum != 0 || validity_smime_sum != 0) {
+               GtkToggleAction *action;
+               GSettings *settings;
+               gboolean sign_reply;
+
+               settings = e_util_ref_settings ("org.gnome.evolution.mail");
+               sign_reply = g_settings_get_boolean (settings, "composer-sign-reply-if-signed");
+               g_object_unref (settings);
+
+               if ((validity_pgp_sum & E_MAIL_PART_VALIDITY_PGP) != 0) {
+                       if (sign_reply && (validity_pgp_sum & E_MAIL_PART_VALIDITY_SIGNED) != 0) {
+                               action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_PGP_SIGN (composer));
+                               gtk_toggle_action_set_active (action, TRUE);
+                       }
+
+                       if ((validity_pgp_sum & E_MAIL_PART_VALIDITY_ENCRYPTED) != 0) {
+                               action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_PGP_ENCRYPT (composer));
+                               gtk_toggle_action_set_active (action, TRUE);
+                       }
+               }
+
+               if ((validity_smime_sum & E_MAIL_PART_VALIDITY_SMIME) != 0) {
+                       if (sign_reply && (validity_smime_sum & E_MAIL_PART_VALIDITY_SIGNED) != 0) {
+                               action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_SMIME_SIGN (composer));
+                               gtk_toggle_action_set_active (action, TRUE);
+                       }
+
+                       if ((validity_smime_sum & E_MAIL_PART_VALIDITY_ENCRYPTED) != 0) {
+                               action = GTK_TOGGLE_ACTION (E_COMPOSER_ACTION_SMIME_ENCRYPT (composer));
+                               gtk_toggle_action_set_active (action, TRUE);
+                       }
+               }
+       }
+}
+
+void
+em_composer_utils_update_security_from_part_list (EMsgComposer *composer,
+                                                 EMailPartList *part_list)
+{
+       EMailPartValidityFlags validity_pgp_sum = 0;
+       EMailPartValidityFlags validity_smime_sum = 0;
+
+       g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+
+       if (!part_list)
+               return;
+
+       e_mail_part_list_sum_validity (part_list, &validity_pgp_sum, &validity_smime_sum);
+       em_composer_utils_update_security (composer, validity_pgp_sum, validity_smime_sum);
+}
diff --git a/src/mail/em-composer-utils.h b/src/mail/em-composer-utils.h
index 252660fb59..f00887e96a 100644
--- a/src/mail/em-composer-utils.h
+++ b/src/mail/em-composer-utils.h
@@ -90,7 +90,9 @@ void          em_utils_reply_alternative      (GtkWindow *parent,
                                                 CamelFolder *folder,
                                                 const gchar *message_uid,
                                                 EMailReplyStyle default_style,
-                                                EMailPartList *source);
+                                                EMailPartList *source,
+                                                EMailPartValidityFlags validity_pgp_sum,
+                                                EMailPartValidityFlags validity_smime_sum);
 EDestination **        em_utils_camel_address_to_destination
                                                (CamelInternetAddress *iaddr);
 void           em_configure_new_composer       (EMsgComposer *composer,
@@ -124,6 +126,13 @@ ESource *  em_composer_utils_guess_identity_source
                                                 const gchar *message_uid,
                                                 gchar **out_identity_name,
                                                 gchar **out_identity_address);
+void           em_composer_utils_update_security
+                                               (EMsgComposer *composer,
+                                                EMailPartValidityFlags validity_pgp_sum,
+                                                EMailPartValidityFlags validity_smime_sum);
+void           em_composer_utils_update_security_from_part_list
+                                               (EMsgComposer *composer,
+                                                EMailPartList *part_list);
 
 G_END_DECLS
 
diff --git a/src/plugins/templates/templates.c b/src/plugins/templates/templates.c
index bfac8a87a7..7b93fa7ee4 100644
--- a/src/plugins/templates/templates.c
+++ b/src/plugins/templates/templates.c
@@ -31,6 +31,7 @@
 #include "shell/e-shell-view.h"
 
 #include "mail/e-mail-reader.h"
+#include "mail/e-mail-reader-utils.h"
 #include "mail/e-mail-ui-session.h"
 #include "mail/e-mail-templates.h"
 #include "mail/e-mail-templates-store.h"
@@ -50,10 +51,14 @@ struct _AsyncContext {
        CamelMimeMessage *source_message;
        CamelMimeMessage *new_message;
        CamelFolder *template_folder;
+       CamelFolder *source_folder;
        gchar *source_folder_uri;
        gchar *source_message_uid;
        gchar *orig_source_message_uid;
        gchar *template_message_uid;
+       gboolean selection_is_html;
+       EMailPartValidityFlags validity_pgp_sum;
+       EMailPartValidityFlags validity_smime_sum;
 };
 
 typedef struct {
@@ -126,6 +131,7 @@ async_context_free (AsyncContext *context)
        g_clear_object (&context->reader);
        g_clear_object (&context->source_message);
        g_clear_object (&context->new_message);
+       g_clear_object (&context->source_folder);
        g_clear_object (&context->template_folder);
 
        g_free (context->source_folder_uri);
@@ -589,7 +595,10 @@ create_new_message_composer_created_cb (GObject *source_object,
 
        /* Create the composer */
        em_utils_edit_message (composer, context->template_folder, context->new_message, 
context->source_message_uid, TRUE);
-       if (composer && context->source_folder_uri && context->source_message_uid)
+
+       em_composer_utils_update_security (composer, context->validity_pgp_sum, context->validity_smime_sum);
+
+       if (context->source_folder_uri && context->source_message_uid)
                e_msg_composer_set_source_headers (
                        composer, context->source_folder_uri,
                        context->source_message_uid, CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN);
@@ -639,17 +648,20 @@ templates_template_applied_cb (GObject *source_object,
 }
 
 static void
-template_got_source_message (CamelFolder *folder,
-                             GAsyncResult *result,
-                             AsyncContext *context)
+template_got_message_cb (GObject *source_object,
+                        GAsyncResult *result,
+                        gpointer user_data)
 {
+       AsyncContext *context = user_data;
        EAlertSink *alert_sink;
+       CamelFolder *folder = NULL;
        CamelMimeMessage *message;
        GError *error = NULL;
 
        alert_sink = e_activity_get_alert_sink (context->activity);
 
-       message = camel_folder_get_message_finish (folder, result, &error);
+       message = e_mail_reader_utils_get_selection_or_message_finish (E_MAIL_READER (source_object), result,
+                       NULL, &folder, NULL, NULL, &context->validity_pgp_sum, &context->validity_smime_sum, 
&error);
 
        if (e_activity_handle_cancellation (context->activity, error)) {
                g_warn_if_fail (message == NULL);
@@ -719,13 +731,10 @@ action_reply_with_template_cb (EMailTemplatesStore *templates_store,
        if (context->source_message_uid == NULL)
                context->source_message_uid = g_strdup (message_uid);
 
-       camel_folder_get_message (
-               folder, message_uid, G_PRIORITY_DEFAULT,
-               cancellable, (GAsyncReadyCallback)
-               template_got_source_message, context);
+       e_mail_reader_utils_get_selection_or_message (reader, NULL, cancellable,
+               template_got_message_cb, context);
 
        g_clear_object (&folder);
-
        g_ptr_array_unref (uids);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]