[evolution] Bug 788730 - Offer Edit Message/Open Outbox Folder when Send fails
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Bug 788730 - Offer Edit Message/Open Outbox Folder when Send fails
- Date: Tue, 10 Oct 2017 13:32:46 +0000 (UTC)
commit ebb63fb37912d547157da81c87277f5b195dde81
Author: Milan Crha <mcrha redhat com>
Date: Tue Oct 10 15:33:26 2017 +0200
Bug 788730 - Offer Edit Message/Open Outbox Folder when Send fails
src/libemail-engine/mail-ops.c | 23 +++++-
src/libemail-engine/mail-ops.h | 3 +-
src/mail/mail-send-recv.c | 176 +++++++++++++++++++++++++++++++++++-----
3 files changed, 176 insertions(+), 26 deletions(-)
---
diff --git a/src/libemail-engine/mail-ops.c b/src/libemail-engine/mail-ops.c
index 4237b39..04ea234 100644
--- a/src/libemail-engine/mail-ops.c
+++ b/src/libemail-engine/mail-ops.c
@@ -557,7 +557,9 @@ struct _send_queue_msg {
CamelFilterStatusFunc status;
gpointer status_data;
- void (*done)(gpointer data);
+ GPtrArray *failed_uids;
+
+ gboolean (* done)(gpointer data, const GError *error, const GPtrArray *failed_uids);
gpointer data;
};
@@ -1000,6 +1002,7 @@ send_queue_exec (struct _send_queue_msg *m,
mail_send_message (
m, m->queue, send_uids->pdata[i],
m->driver, cancellable, &local_error);
+
if (local_error != NULL) {
if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
/* merge exceptions into one */
@@ -1022,6 +1025,11 @@ send_queue_exec (struct _send_queue_msg *m,
local_error = NULL;
}
+ if (!m->failed_uids)
+ m->failed_uids = g_ptr_array_new_with_free_func ((GDestroyNotify)
camel_pstring_free);
+
+ g_ptr_array_add (m->failed_uids, (gpointer) camel_pstring_strdup
(send_uids->pdata[i]));
+
/* keep track of the number of failures */
j++;
} else {
@@ -1075,8 +1083,13 @@ send_queue_exec (struct _send_queue_msg *m,
static void
send_queue_done (struct _send_queue_msg *m)
{
- if (m->done)
- m->done (m->data);
+ if (m->done) {
+ if (g_error_matches (m->base.error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ m->done (m->data, NULL, NULL);
+ } else if (m->done (m->data, m->base.error, m->failed_uids)) {
+ g_clear_error (&m->base.error);
+ }
+ }
}
static gchar *
@@ -1094,6 +1107,8 @@ send_queue_free (struct _send_queue_msg *m)
g_object_unref (m->driver);
if (m->transport != NULL)
g_object_unref (m->transport);
+ if (m->failed_uids)
+ g_ptr_array_unref (m->failed_uids);
g_object_unref (m->queue);
}
@@ -1118,7 +1133,7 @@ mail_send_queue (EMailSession *session,
gpointer get_data,
CamelFilterStatusFunc status,
gpointer status_data,
- void (*done)(gpointer data),
+ gboolean (* done)(gpointer data, const GError *error, const GPtrArray *failed_uids),
gpointer data)
{
struct _send_queue_msg *m;
diff --git a/src/libemail-engine/mail-ops.h b/src/libemail-engine/mail-ops.h
index 35b971b..7d7c744 100644
--- a/src/libemail-engine/mail-ops.h
+++ b/src/libemail-engine/mail-ops.h
@@ -62,7 +62,8 @@ void mail_send_queue (EMailSession *session,
gpointer get_data,
CamelFilterStatusFunc status,
gpointer status_data,
- void (*done)(gpointer data),
+ /* Return %TRUE, when the error had been reported to the
user */
+ gboolean (* done)(gpointer data, const GError *error, const
GPtrArray *failed_uids),
gpointer data);
typedef void (*MailProviderFetchLockFunc) (const gchar *source);
diff --git a/src/mail/mail-send-recv.c b/src/mail/mail-send-recv.c
index 4ffe1f9..42adbc6 100644
--- a/src/mail/mail-send-recv.c
+++ b/src/mail/mail-send-recv.c
@@ -32,6 +32,7 @@
#include <e-util/e-util.h>
#include "e-mail-account-store.h"
+#include "e-mail-reader-utils.h"
#include "e-mail-ui-session.h"
#include "em-event.h"
#include "em-filter-rule.h"
@@ -124,7 +125,7 @@ static CamelFolder *
const gchar *uri,
gpointer data,
GError **error);
-static void send_done (gpointer data);
+static gboolean send_done (gpointer data, const GError *error, const GPtrArray *failed_uids);
static struct _send_data *send_data = NULL;
static GtkWidget *send_recv_dialog = NULL;
@@ -435,24 +436,11 @@ format_service_name (CamelService *service)
return pretty_url;
}
-struct ReportErrorToUIData
+static EShellView *
+mail_send_receive_get_mail_shell_view (void)
{
- gchar *display_name;
- gchar *error_ident;
- GError *error;
-};
-
-static gboolean
-report_error_to_ui_cb (gpointer user_data)
-{
- struct ReportErrorToUIData *data = user_data;
EShellView *shell_view = NULL;
- g_return_val_if_fail (data != NULL, FALSE);
- g_return_val_if_fail (data->display_name != NULL, FALSE);
- g_return_val_if_fail (data->error_ident != NULL, FALSE);
- g_return_val_if_fail (data->error != NULL, FALSE);
-
if (send_recv_dialog) {
GtkWidget *parent;
@@ -478,6 +466,97 @@ report_error_to_ui_cb (gpointer user_data)
}
}
+ return shell_view;
+}
+
+static void
+mail_send_recv_send_fail_alert_response_cb (EAlert *alert,
+ gint response_id,
+ gpointer user_data)
+{
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EShellSidebar *shell_sidebar;
+ EMFolderTree *folder_tree = NULL;
+ EMailSession *session;
+ CamelFolder *outbox;
+ GPtrArray *uids;
+
+ if (response_id != GTK_RESPONSE_APPLY && response_id != GTK_RESPONSE_REJECT)
+ return;
+
+ shell_view = mail_send_receive_get_mail_shell_view ();
+ if (!shell_view)
+ return;
+
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+
+ g_object_get (G_OBJECT (shell_sidebar), "folder-tree", &folder_tree, NULL);
+ g_return_if_fail (folder_tree != NULL);
+
+ session = em_folder_tree_get_session (folder_tree);
+ outbox = e_mail_session_get_local_folder (session, E_MAIL_LOCAL_FOLDER_OUTBOX);
+
+ uids = g_object_get_data (G_OBJECT (alert), "message-uids");
+
+ if (uids && response_id == GTK_RESPONSE_APPLY) {
+ e_mail_reader_edit_messages (E_MAIL_READER (shell_content), outbox, uids, TRUE, TRUE);
+ } else if (folder_tree) {
+ gchar *folder_uri;
+
+ folder_uri = e_mail_folder_uri_from_folder (outbox);
+ g_warn_if_fail (folder_uri != NULL);
+
+ if (folder_uri) {
+ CamelFolder *selected_folder;
+
+ em_folder_tree_set_selected (folder_tree, folder_uri, FALSE);
+
+ selected_folder = e_mail_reader_ref_folder (E_MAIL_READER (shell_content));
+
+ /* This makes sure the Outbox folder content is shown even
+ when the On This Computer account is disabled */
+ if (selected_folder != outbox) {
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
+ gtk_tree_selection_unselect_all (selection);
+
+ em_folder_tree_set_selected (folder_tree, folder_uri, FALSE);
+ e_mail_reader_set_folder (E_MAIL_READER (shell_content), outbox);
+ }
+
+ g_clear_object (&selected_folder);
+ }
+
+ g_free (folder_uri);
+ }
+
+ g_clear_object (&folder_tree);
+}
+
+struct ReportErrorToUIData
+{
+ gchar *display_name;
+ gchar *error_ident;
+ GError *error;
+ GPtrArray *send_failed_uids;
+};
+
+static gboolean
+report_error_to_ui_cb (gpointer user_data)
+{
+ struct ReportErrorToUIData *data = user_data;
+ EShellView *shell_view;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (data->display_name != NULL, FALSE);
+ g_return_val_if_fail (data->error_ident != NULL, FALSE);
+ g_return_val_if_fail (data->error != NULL, FALSE);
+
+ shell_view = mail_send_receive_get_mail_shell_view ();
+
if (shell_view) {
EShellContent *shell_content;
EAlertSink *alert_sink;
@@ -489,6 +568,29 @@ report_error_to_ui_cb (gpointer user_data)
alert = e_alert_new (data->error_ident, data->display_name,
data->error->message ? data->error->message : _("Unknown error"), NULL);
+ if (data->send_failed_uids) {
+ GtkAction *action;
+
+ if (data->send_failed_uids->len == 1) {
+ g_object_set_data_full (G_OBJECT (alert), "message-uids",
+ g_ptr_array_ref (data->send_failed_uids),
+ (GDestroyNotify) g_ptr_array_unref);
+ }
+
+ if (data->send_failed_uids->len == 1) {
+ action = gtk_action_new ("send-failed-edit-action", _("Edit Message"), NULL,
NULL);
+ e_alert_add_action (alert, action, GTK_RESPONSE_APPLY);
+ g_object_unref (action);
+ }
+
+ action = gtk_action_new ("send-failed-outbox-action", _("Open Outbox Folder"), NULL,
NULL);
+ e_alert_add_action (alert, action, GTK_RESPONSE_REJECT);
+ g_object_unref (action);
+
+ g_signal_connect (alert, "response",
+ G_CALLBACK (mail_send_recv_send_fail_alert_response_cb), NULL);
+ }
+
e_alert_sink_submit_alert (alert_sink, alert);
g_object_unref (alert);
@@ -500,6 +602,8 @@ report_error_to_ui_cb (gpointer user_data)
g_free (data->display_name);
g_free (data->error_ident);
g_error_free (data->error);
+ if (data->send_failed_uids)
+ g_ptr_array_unref (data->send_failed_uids);
g_free (data);
return FALSE;
@@ -508,7 +612,8 @@ report_error_to_ui_cb (gpointer user_data)
static void
report_error_to_ui (CamelService *service,
const gchar *folder_name,
- const GError *error)
+ const GError *error,
+ const GPtrArray *send_failed_uids)
{
gchar *tmp = NULL;
const gchar *display_name, *ident;
@@ -527,6 +632,9 @@ report_error_to_ui (CamelService *service,
folder_name);
display_name = tmp;
ident = "mail:no-refresh-folder";
+ } else if (send_failed_uids) {
+ display_name = _("Sending message");
+ ident = "mail:async-error";
} else {
display_name = camel_service_get_display_name (service);
ident = "mail:failed-connect";
@@ -537,6 +645,18 @@ report_error_to_ui (CamelService *service,
data->error_ident = g_strdup (ident);
data->error = g_error_copy (error);
+ if (send_failed_uids) {
+ gint ii;
+
+ data->send_failed_uids = g_ptr_array_new_full (send_failed_uids->len + 1, (GDestroyNotify)
camel_pstring_free);
+
+ for (ii = 0; ii < send_failed_uids->len; ii++) {
+ g_ptr_array_add (data->send_failed_uids, (gpointer) camel_pstring_strdup
(g_ptr_array_index (send_failed_uids, ii)));
+ }
+ } else {
+ data->send_failed_uids = NULL;
+ }
+
g_idle_add_full (G_PRIORITY_DEFAULT, report_error_to_ui_cb, data, NULL);
g_free (tmp);
@@ -1004,10 +1124,24 @@ receive_done (gpointer data)
free_send_info (info);
}
-static void
-send_done (gpointer data)
+static gboolean
+send_done (gpointer data,
+ const GError *error,
+ const GPtrArray *failed_uids)
{
+ gboolean res = FALSE;
+
+ if (error && failed_uids) {
+ struct _send_info *info = data;
+
+ res = TRUE;
+
+ report_error_to_ui (info->service, NULL, error, failed_uids);
+ }
+
receive_done (data);
+
+ return res;
}
/* although we dont do anythign smart here yet, there is no need for this interface to
* be available to anyone else.
@@ -1305,7 +1439,7 @@ refresh_folders_exec (struct _refresh_folders_msg *m,
full_name = (const gchar *) m->folders->pdata[i];
}
- report_error_to_ui (CAMEL_SERVICE (store), full_name, local_error);
+ report_error_to_ui (CAMEL_SERVICE (store), full_name, local_error, NULL);
/* To not report one error for multiple folders multiple times */
g_hash_table_insert (known_errors, g_strdup (error_message), GINT_TO_POINTER
(1));
@@ -1384,7 +1518,7 @@ receive_update_got_folderinfo (GObject *source_object,
/* XXX Need to hand this off to an EAlertSink. */
} else if (local_error != NULL) {
g_warn_if_fail (info == NULL);
- report_error_to_ui (send_info->service, NULL, local_error);
+ report_error_to_ui (send_info->service, NULL, local_error, NULL);
g_error_free (local_error);
receive_done (send_info);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]