[evolution] Bug 790020 - Use original location when composing new message in Search Folder
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Bug 790020 - Use original location when composing new message in Search Folder
- Date: Fri, 24 Nov 2017 11:26:26 +0000 (UTC)
commit a6a451ab876d491d7db593340e07a22f64db8965
Author: Milan Crha <mcrha redhat com>
Date: Fri Nov 24 12:25:54 2017 +0100
Bug 790020 - Use original location when composing new message in Search Folder
src/mail/e-mail-display.c | 7 +-
src/mail/e-mail-reader.c | 24 +++-
src/mail/em-composer-utils.c | 160 +++++++++++++++++++-
src/mail/em-composer-utils.h | 9 +
src/modules/mail/e-mail-shell-backend.c | 58 +++++---
.../mailing-list-actions/mailing-list-actions.c | 6 +-
6 files changed, 230 insertions(+), 34 deletions(-)
---
diff --git a/src/mail/e-mail-display.c b/src/mail/e-mail-display.c
index f9befc8..0e68e8d 100644
--- a/src/mail/e-mail-display.c
+++ b/src/mail/e-mail-display.c
@@ -322,14 +322,13 @@ mail_display_process_mailto (EWebView *web_view,
if (g_ascii_strncasecmp (mailto_uri, "mailto:", 7) == 0) {
EShell *shell;
EMailPartList *part_list;
- CamelFolder *folder;
part_list = E_MAIL_DISPLAY (web_view)->priv->part_list;
- folder = e_mail_part_list_get_folder (part_list);
shell = e_shell_get_default ();
- em_utils_compose_new_message_with_mailto (
- shell, mailto_uri, folder);
+ em_utils_compose_new_message_with_mailto_and_selection (shell, mailto_uri,
+ e_mail_part_list_get_folder (part_list),
+ e_mail_part_list_get_message_uid (part_list));
handled = TRUE;
}
diff --git a/src/mail/e-mail-reader.c b/src/mail/e-mail-reader.c
index 733d91a..2de0eb2 100644
--- a/src/mail/e-mail-reader.c
+++ b/src/mail/e-mail-reader.c
@@ -965,6 +965,7 @@ typedef struct _CreateComposerData {
EMailReader *reader;
CamelMimeMessage *message;
CamelFolder *folder;
+ const gchar *message_uid; /* In the Camel string pool */
gboolean is_redirect;
} CreateComposerData;
@@ -987,7 +988,7 @@ mail_reader_new_composer_created_cb (GObject *source_object,
if (ccd->is_redirect)
em_utils_redirect_message (composer, ccd->message);
else
- em_utils_compose_new_message (composer, ccd->folder);
+ em_utils_compose_new_message_with_selection (composer, ccd->folder, ccd->message_uid);
e_mail_reader_composer_created (ccd->reader, composer, ccd->message);
}
@@ -995,6 +996,7 @@ mail_reader_new_composer_created_cb (GObject *source_object,
g_clear_object (&ccd->reader);
g_clear_object (&ccd->message);
g_clear_object (&ccd->folder);
+ camel_pstring_free (ccd->message_uid);
g_free (ccd);
}
@@ -1007,19 +1009,37 @@ action_mail_message_new_cb (GtkAction *action,
EShellBackend *shell_backend;
CamelFolder *folder;
CreateComposerData *ccd;
+ GPtrArray *selected_uids = NULL;
+ const gchar *selected_uid = NULL;
folder = e_mail_reader_ref_folder (reader);
backend = e_mail_reader_get_backend (reader);
+ selected_uids = e_mail_reader_get_selected_uids (reader);
+ if (selected_uids && selected_uids->len > 0)
+ selected_uid = g_ptr_array_index (selected_uids, 0);
+
+ if (!selected_uid) {
+ GtkWidget *message_list;
+
+ message_list = e_mail_reader_get_message_list (reader);
+ if (message_list)
+ selected_uid = MESSAGE_LIST (message_list)->cursor_uid;
+ }
+
shell_backend = E_SHELL_BACKEND (backend);
shell = e_shell_backend_get_shell (shell_backend);
ccd = g_new0 (CreateComposerData, 1);
ccd->reader = g_object_ref (reader);
ccd->folder = folder;
+ ccd->message_uid = camel_pstring_strdup (selected_uid);
ccd->is_redirect = FALSE;
e_msg_composer_new (shell, mail_reader_new_composer_created_cb, ccd);
+
+ if (selected_uids)
+ g_ptr_array_unref (selected_uids);
}
static void
@@ -1255,6 +1275,7 @@ mail_reader_redirect_cb (CamelFolder *folder,
ccd = g_new0 (CreateComposerData, 1);
ccd->reader = g_object_ref (closure->reader);
ccd->message = message;
+ ccd->message_uid = camel_pstring_strdup (closure->message_uid);
ccd->is_redirect = TRUE;
e_msg_composer_new (shell, mail_reader_new_composer_created_cb, ccd);
@@ -1285,6 +1306,7 @@ action_mail_redirect_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);
diff --git a/src/mail/em-composer-utils.c b/src/mail/em-composer-utils.c
index d48eb55..0296976 100644
--- a/src/mail/em-composer-utils.c
+++ b/src/mail/em-composer-utils.c
@@ -1402,6 +1402,8 @@ sort_sources_by_ui (GList **psources,
/* Composing messages... */
+static CamelMimeMessage *em_utils_get_composer_recipients_as_message (EMsgComposer *composer);
+
static void
set_up_new_composer (EMsgComposer *composer,
const gchar *subject,
@@ -1425,15 +1427,107 @@ set_up_new_composer (EMsgComposer *composer,
GList *list;
if (message) {
+ g_object_ref (message);
+ } else if (message_uid) {
+ message = em_utils_get_composer_recipients_as_message (composer);
+ }
+
+ if (message) {
EShell *shell;
shell = e_msg_composer_get_shell (composer);
+
+ /* Check send account override for the passed-in folder */
source = em_utils_check_send_account_override (shell, message, folder,
&identity_name, &identity_address);
- if (!source)
+
+ /* If not set and it's a search folder, then check the original folder */
+ if (!source && message_uid && CAMEL_IS_VEE_FOLDER (folder)) {
+ CamelMessageInfo *mi = camel_folder_get_message_info (folder, message_uid);
+ if (mi) {
+ CamelFolder *location;
+
+ location = camel_vee_folder_get_location (CAMEL_VEE_FOLDER (folder),
(CamelVeeMessageInfo *) mi, NULL);
+ if (location)
+ source = em_utils_check_send_account_override (shell,
message, location, &identity_name, &identity_address);
+ g_clear_object (&mi);
+ }
+ }
+
+ /* If no send account override, then guess */
+ if (!source) {
source = em_utils_guess_mail_identity_with_recipients_and_sort (
registry, message, folder, message_uid, &identity_name,
&identity_address, sort_sources_by_ui, shell);
+ }
+ }
+
+ /* In case of search folder, try to guess the store from
+ the internal folders of it. If they are all from the same
+ store, then use that store. */
+ if (!source && CAMEL_IS_VEE_FOLDER (folder)) {
+ GHashTable *stores, *done_folders;
+ GSList *todo;
+
+ stores = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
+ done_folders = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ todo = g_slist_prepend (NULL, g_object_ref (folder));
+
+ while (todo) {
+ CamelVeeFolder *vfolder = todo->data;
+
+ todo = g_slist_remove (todo, vfolder);
+ if (!g_hash_table_contains (done_folders, vfolder)) {
+ GList *folders, *llink;
+
+ g_hash_table_insert (done_folders, vfolder, NULL);
+
+ folders = camel_vee_folder_ref_folders (vfolder);
+ for (llink = folders; llink; llink = g_list_next (llink)) {
+ CamelFolder *subfolder = llink->data;
+
+ if (!g_hash_table_contains (done_folders, subfolder)) {
+ if (CAMEL_IS_VEE_FOLDER (subfolder)) {
+ todo = g_slist_prepend (todo, g_object_ref
(subfolder));
+ } else {
+ CamelStore *store =
camel_folder_get_parent_store (subfolder);
+
+ g_hash_table_insert (done_folders, subfolder,
NULL);
+
+ if (store) {
+ g_hash_table_insert (stores,
g_object_ref (store), NULL);
+
+ if (g_hash_table_size (stores) > 1) {
+ g_slist_free_full (todo,
g_object_unref);
+ todo = NULL;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ g_list_free_full (folders, g_object_unref);
+ }
+
+ g_object_unref (vfolder);
+ }
+
+ if (g_hash_table_size (stores) == 1) {
+ GHashTableIter iter;
+ gpointer store;
+
+ g_hash_table_iter_init (&iter, stores);
+ if (g_hash_table_iter_next (&iter, &store, NULL) && store)
+ source = em_utils_ref_mail_identity_for_store (registry, store);
+ }
+
+ g_slist_free_full (todo, g_object_unref);
+ g_hash_table_destroy (done_folders);
+ g_hash_table_destroy (stores);
}
+ g_clear_object (&message);
+
if (!source) {
CamelStore *store;
@@ -1455,7 +1549,8 @@ set_up_new_composer (EMsgComposer *composer,
g_object_unref (source);
}
- e_composer_header_table_set_subject (table, subject);
+ if (subject)
+ e_composer_header_table_set_subject (table, subject);
e_composer_header_table_set_identity_uid (table, identity, identity_name, identity_address);
em_utils_apply_send_account_override_to_composer (composer, folder);
@@ -1475,18 +1570,40 @@ set_up_new_composer (EMsgComposer *composer,
*
* Sets up a new @composer window.
*
+ * See: em_utils_compose_new_message_with_selection()
+ *
* Since: 3.22
**/
void
em_utils_compose_new_message (EMsgComposer *composer,
CamelFolder *folder)
{
+ em_utils_compose_new_message_with_selection (composer, folder, NULL);
+}
+
+/**
+ * em_utils_compose_new_message_with_selection:
+ * @composer: an #EMsgComposer
+ * @folder: (nullable): a #CamelFolder, or %NULL
+ * @message_uid: (nullable): a UID of the selected message, or %NULL
+ *
+ * Sets up a new @composer window, similar to em_utils_compose_new_message(),
+ * but also tries to identify From account more precisely, when the @folder
+ * is a search folder.
+ *
+ * Since: 3.28
+ **/
+void
+em_utils_compose_new_message_with_selection (EMsgComposer *composer,
+ CamelFolder *folder,
+ const gchar *message_uid)
+{
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
- if (folder != NULL)
+ if (folder)
g_return_if_fail (CAMEL_IS_FOLDER (folder));
- set_up_new_composer (composer, "", folder, NULL, NULL);
+ set_up_new_composer (composer, "", folder, NULL, message_uid);
composer_set_no_change (composer);
gtk_widget_show (GTK_WIDGET (composer));
@@ -1570,8 +1687,9 @@ em_utils_get_composer_recipients_as_message (EMsgComposer *composer)
}
typedef struct _CreateComposerData {
- gchar *mailto;
CamelFolder *folder;
+ const gchar *message_uid; /* In the Camel string pool */
+ gchar *mailto;
} CreateComposerData;
static void
@@ -1581,6 +1699,7 @@ create_composer_data_free (gpointer ptr)
if (ccd) {
g_clear_object (&ccd->folder);
+ camel_pstring_free (ccd->message_uid);
g_free (ccd->mailto);
g_free (ccd);
}
@@ -1612,7 +1731,7 @@ msg_composer_created_with_mailto_cb (GObject *source_object,
if (ccd->mailto)
e_msg_composer_setup_from_url (composer, ccd->mailto);
- em_utils_apply_send_account_override_to_composer (composer, ccd->folder);
+ set_up_new_composer (composer, NULL, ccd->folder, NULL, ccd->message_uid);
table = e_msg_composer_get_header_table (composer);
@@ -1655,21 +1774,48 @@ msg_composer_created_with_mailto_cb (GObject *source_object,
* Opens a new composer window as a child window of @parent's toplevel
* window. If @mailto is non-NULL, the composer fields will be filled in
* according to the values in the mailto URL.
+ *
+ * See: em_utils_compose_new_message_with_mailto_and_selection()
**/
void
em_utils_compose_new_message_with_mailto (EShell *shell,
const gchar *mailto,
CamelFolder *folder)
{
+ em_utils_compose_new_message_with_mailto_and_selection (shell, mailto, folder, NULL);
+}
+
+/**
+ * em_utils_compose_new_message_with_mailto_and_selection:
+ * @shell: an #EShell
+ * @mailto: a mailto URL
+ * @folder: a #CamelFolder, or %NULL
+ * @message_uid: (nullable): a UID of the selected message, or %NULL
+ *
+ * similarly to em_utils_compose_new_message_with_mailto(), opens a new composer
+ * window as a child window of @parent's toplevel window. If @mailto is non-NULL,
+ * the composer fields will be filled in according to the values in the mailto URL.
+ * It also tries to identify From account more precisely, when the @folder
+ * is a search folder.
+ *
+ * Since: 3.28
+ **/
+void
+em_utils_compose_new_message_with_mailto_and_selection (EShell *shell,
+ const gchar *mailto,
+ CamelFolder *folder,
+ const gchar *message_uid)
+{
CreateComposerData *ccd;
g_return_if_fail (E_IS_SHELL (shell));
- if (folder != NULL)
+ if (folder)
g_return_if_fail (CAMEL_IS_FOLDER (folder));
ccd = g_new0 (CreateComposerData, 1);
ccd->folder = folder ? g_object_ref (folder) : NULL;
+ ccd->message_uid = camel_pstring_strdup (message_uid);
ccd->mailto = g_strdup (mailto);
e_msg_composer_new (shell, msg_composer_created_with_mailto_cb, ccd);
diff --git a/src/mail/em-composer-utils.h b/src/mail/em-composer-utils.h
index d9035ea..91471bc 100644
--- a/src/mail/em-composer-utils.h
+++ b/src/mail/em-composer-utils.h
@@ -35,10 +35,19 @@ G_BEGIN_DECLS
void em_utils_compose_new_message (EMsgComposer *composer,
CamelFolder *folder);
+void em_utils_compose_new_message_with_selection
+ (EMsgComposer *composer,
+ CamelFolder *folder,
+ const gchar *message_uid);
void em_utils_compose_new_message_with_mailto
(EShell *shell,
const gchar *mailto,
CamelFolder *folder);
+void em_utils_compose_new_message_with_mailto_and_selection
+ (EShell *shell,
+ const gchar *mailto,
+ CamelFolder *folder,
+ const gchar *message_uid);
void em_utils_edit_message (EMsgComposer *composer,
CamelFolder *folder,
CamelMimeMessage *message,
diff --git a/src/modules/mail/e-mail-shell-backend.c b/src/modules/mail/e-mail-shell-backend.c
index 0187868..99e5aae 100644
--- a/src/modules/mail/e-mail-shell-backend.c
+++ b/src/modules/mail/e-mail-shell-backend.c
@@ -40,6 +40,7 @@
#include <mail/mail-vfolder-ui.h>
#include <mail/importers/mail-importer.h>
#include <mail/e-mail-ui-session.h>
+#include <mail/message-list.h>
#include <em-format/e-mail-parser.h>
#include <em-format/e-mail-formatter.h>
@@ -298,46 +299,54 @@ action_mail_account_new_cb (GtkAction *action,
GTK_WINDOW (shell_window));
}
+typedef struct _NewComposerData
+{
+ CamelFolder *folder;
+ const gchar *message_uid; /* In the Camel string pool */
+} NewComposerData;
+
static void
action_mail_message_new_composer_created_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
- CamelFolder *folder = user_data;
+ NewComposerData *ncd = user_data;
EMsgComposer *composer;
GError *error = NULL;
- if (folder)
- g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ g_return_if_fail (ncd != NULL);
+
+ if (ncd->folder)
+ g_return_if_fail (CAMEL_IS_FOLDER (ncd->folder));
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_compose_new_message (composer, folder);
+ em_utils_compose_new_message_with_selection (composer, ncd->folder, ncd->message_uid);
}
- g_clear_object (&folder);
+ g_clear_object (&ncd->folder);
+ camel_pstring_free (ncd->message_uid);
+ g_free (ncd);
}
static void
action_mail_message_new_cb (GtkAction *action,
EShellWindow *shell_window)
{
- EMailShellSidebar *mail_shell_sidebar;
- EShellSidebar *shell_sidebar;
EShellView *shell_view;
EShell *shell;
ESourceRegistry *registry;
- EMFolderTree *folder_tree;
CamelFolder *folder = NULL;
- CamelStore *store;
GList *list;
const gchar *extension_name;
const gchar *view_name;
gboolean no_transport_defined;
- gchar *folder_name;
+ const gchar *message_uid = NULL;
+ GtkWidget *message_list;
+ NewComposerData *ncd;
shell = e_shell_window_get_shell (shell_window);
registry = e_shell_get_registry (shell);
@@ -356,24 +365,31 @@ action_mail_message_new_cb (GtkAction *action,
goto exit;
shell_view = e_shell_window_get_shell_view (shell_window, view_name);
- shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
- mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
- folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+ message_list = e_mail_reader_get_message_list (E_MAIL_READER (e_shell_view_get_shell_content
(shell_view)));
+ if (message_list) {
+ MessageList *ml = MESSAGE_LIST (message_list);
+ GPtrArray *selected_uids;
+
+ folder = message_list_ref_folder (ml);
- if (em_folder_tree_get_selected (folder_tree, &store, &folder_name)) {
+ selected_uids = message_list_get_selected (ml);
+ if (selected_uids && selected_uids->len > 0)
+ message_uid = camel_pstring_strdup (g_ptr_array_index (selected_uids, 0));
- /* FIXME This blocks and is not cancellable. */
- folder = camel_store_get_folder_sync (
- store, folder_name, 0, NULL, NULL);
+ if (!message_uid)
+ message_uid = camel_pstring_strdup (ml->cursor_uid);
- g_object_unref (store);
- g_free (folder_name);
+ if (selected_uids)
+ g_ptr_array_unref (selected_uids);
}
exit:
- e_msg_composer_new (shell, action_mail_message_new_composer_created_cb,
- folder ? g_object_ref (folder) : NULL);
+ ncd = g_new0 (NewComposerData, 1);
+ ncd->folder = folder;
+ ncd->message_uid = message_uid;
+
+ e_msg_composer_new (shell, action_mail_message_new_composer_created_cb, ncd);
}
static GtkActionEntry item_entries[] = {
diff --git a/src/plugins/mailing-list-actions/mailing-list-actions.c
b/src/plugins/mailing-list-actions/mailing-list-actions.c
index fcad750..c9be893 100644
--- a/src/plugins/mailing-list-actions/mailing-list-actions.c
+++ b/src/plugins/mailing-list-actions/mailing-list-actions.c
@@ -100,6 +100,7 @@ struct _AsyncContext {
EActivity *activity;
EMailReader *reader;
EmlaAction action;
+ const gchar *message_uid; /* In the Camel string pool */
};
static void
@@ -111,6 +112,8 @@ async_context_free (AsyncContext *context)
if (context->reader != NULL)
g_object_unref (context->reader);
+ camel_pstring_free (context->message_uid);
+
g_slice_free (AsyncContext, context);
}
@@ -283,7 +286,7 @@ emla_list_action_cb (CamelFolder *folder,
e_msg_composer_new (shell, send_message_composer_created_cb, smd);
} else if (send_message_response == GTK_RESPONSE_NO) {
/* show composer */
- em_utils_compose_new_message_with_mailto (shell, url, folder);
+ em_utils_compose_new_message_with_mailto_and_selection (shell, url, folder,
context->message_uid);
}
goto exit;
@@ -344,6 +347,7 @@ emla_list_action (EMailReader *reader,
context->activity = activity;
context->reader = g_object_ref (reader);
context->action = action;
+ context->message_uid = camel_pstring_strdup (message_uid);
folder = e_mail_reader_ref_folder (reader);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]