aboutsummaryrefslogtreecommitdiffstats
path: root/composer
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-08-31 02:23:33 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-08-31 02:26:00 +0800
commit035fbcd84177cf592a48e41ca0ca7689aaaa9d17 (patch)
treeff895767b9b3f55ae67fe0aa764102e526c85e41 /composer
parent680c58a7660020c614690421ff0e37ee55b2c9aa (diff)
downloadgsoc2013-evolution-035fbcd84177cf592a48e41ca0ca7689aaaa9d17.tar
gsoc2013-evolution-035fbcd84177cf592a48e41ca0ca7689aaaa9d17.tar.gz
gsoc2013-evolution-035fbcd84177cf592a48e41ca0ca7689aaaa9d17.tar.bz2
gsoc2013-evolution-035fbcd84177cf592a48e41ca0ca7689aaaa9d17.tar.lz
gsoc2013-evolution-035fbcd84177cf592a48e41ca0ca7689aaaa9d17.tar.xz
gsoc2013-evolution-035fbcd84177cf592a48e41ca0ca7689aaaa9d17.tar.zst
gsoc2013-evolution-035fbcd84177cf592a48e41ca0ca7689aaaa9d17.zip
Composer autosave cleanups.
This simplifies the async autosave logic and improves error handling. Hoping this will solve bug #616987 but I've yet to reproduce it myself.
Diffstat (limited to 'composer')
-rw-r--r--composer/e-composer-autosave.c133
-rw-r--r--composer/e-msg-composer.c34
-rw-r--r--composer/e-msg-composer.h6
3 files changed, 66 insertions, 107 deletions
diff --git a/composer/e-composer-autosave.c b/composer/e-composer-autosave.c
index 8863cf8d2a..82a44d570a 100644
--- a/composer/e-composer-autosave.c
+++ b/composer/e-composer-autosave.c
@@ -99,23 +99,30 @@ composer_autosave_state_free (AutosaveState *state)
}
static gboolean
-composer_autosave_state_open (AutosaveState *state)
+composer_autosave_state_open (AutosaveState *state,
+ GError **error)
{
+ const gchar *user_data_dir;
gchar *path;
gint fd;
if (state->file != NULL)
return TRUE;
- path = g_build_filename (
- e_get_user_data_dir (), AUTOSAVE_SEED, NULL);
+ user_data_dir = e_get_user_data_dir ();
+ path = g_build_filename (user_data_dir, AUTOSAVE_SEED, NULL);
/* Since GIO doesn't have support for creating temporary files
* from a template (and in a given directory), we have to use
* g_mkstemp(), which brings a small risk of overwriting another
* autosave file. The risk is, however, miniscule. */
+ errno = 0;
fd = g_mkstemp (path);
if (fd == -1) {
+ g_set_error (
+ error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s", g_strerror (errno));
g_free (path);
return FALSE;
}
@@ -317,72 +324,31 @@ e_composer_autosave_unregister (EMsgComposer *composer)
g_object_set_data (G_OBJECT (composer), "autosave", NULL);
}
-typedef struct {
- EMsgComposer *composer;
- GSimpleAsyncResult *simple;
- AutosaveState *state;
-
- /* Transient data */
- GInputStream *input_stream;
-} AutosaveData;
-
-static void
-autosave_data_free (AutosaveData *data)
-{
- g_object_unref (data->composer);
- g_object_unref (data->simple);
-
- if (data->input_stream != NULL)
- g_object_unref (data->input_stream);
-
- g_slice_free (AutosaveData, data);
-}
-
-static gboolean
-autosave_snapshot_check_for_error (AutosaveData *data,
- GError *error)
-{
- GSimpleAsyncResult *simple;
-
- if (error == NULL)
- return FALSE;
-
- simple = data->simple;
- g_simple_async_result_set_from_error (simple, error);
- g_simple_async_result_set_op_res_gboolean (simple, FALSE);
- g_simple_async_result_complete (simple);
- g_error_free (error);
-
- autosave_data_free (data);
-
- return TRUE;
-}
-
static void
autosave_snapshot_splice_cb (GOutputStream *output_stream,
GAsyncResult *result,
- AutosaveData *data)
+ GSimpleAsyncResult *simple)
{
- GSimpleAsyncResult *simple;
GError *error = NULL;
g_output_stream_splice_finish (output_stream, result, &error);
- if (autosave_snapshot_check_for_error (data, error))
- return;
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
- simple = data->simple;
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
-
- autosave_data_free (data);
+ g_object_unref (simple);
}
static void
autosave_snapshot_cb (GFile *file,
GAsyncResult *result,
- AutosaveData *data)
+ GSimpleAsyncResult *simple)
{
+ GObject *object;
+ EMsgComposer *composer;
CamelMimeMessage *message;
GFileOutputStream *output_stream;
GInputStream *input_stream;
@@ -390,22 +356,26 @@ autosave_snapshot_cb (GFile *file,
GByteArray *buffer;
GError *error = NULL;
+ object = g_async_result_get_source_object (G_ASYNC_RESULT (simple));
+
output_stream = g_file_replace_finish (file, result, &error);
- if (autosave_snapshot_check_for_error (data, error))
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ g_error_free (error);
return;
+ }
/* Extract a MIME message from the composer. */
- message = e_msg_composer_get_message_draft (data->composer);
- if (message == NULL) {
- GSimpleAsyncResult *simple;
-
- /* FIXME Need to set a GError here. */
- simple = data->simple;
- g_simple_async_result_set_op_res_gboolean (simple, FALSE);
+ composer = E_MSG_COMPOSER (object);
+ message = e_msg_composer_get_message_draft (composer, &error);
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (output_stream);
- autosave_data_free (data);
+ g_object_unref (simple);
return;
}
@@ -430,7 +400,6 @@ autosave_snapshot_cb (GFile *file,
buffer->data, (gssize) buffer->len,
(GDestroyNotify) g_free);
g_byte_array_free (buffer, FALSE);
- data->input_stream = input_stream;
/* Splice the input and output streams */
g_output_stream_splice_async (
@@ -438,9 +407,10 @@ autosave_snapshot_cb (GFile *file,
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback)
- autosave_snapshot_splice_cb, data);
+ autosave_snapshot_splice_cb, simple);
g_object_unref (output_stream);
+ g_object_unref (input_stream);
}
void
@@ -448,48 +418,39 @@ e_composer_autosave_snapshot_async (EMsgComposer *composer,
GAsyncReadyCallback callback,
gpointer user_data)
{
- AutosaveData *data;
AutosaveState *state;
GSimpleAsyncResult *simple;
+ GError *error = NULL;
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
+ state = g_object_get_data (G_OBJECT (composer), "autosave");
+ g_return_if_fail (state != NULL);
+
simple = g_simple_async_result_new (
G_OBJECT (composer), callback, user_data,
e_composer_autosave_snapshot_async);
/* If the contents are unchanged, exit early. */
if (!gtkhtml_editor_get_changed (GTKHTML_EDITOR (composer))) {
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
+ g_object_unref (simple);
return;
}
- state = g_object_get_data (G_OBJECT (composer), "autosave");
- g_return_if_fail (state != NULL);
-
/* Open the autosave file on-demand. */
- errno = 0;
- if (!composer_autosave_state_open (state)) {
- g_simple_async_result_set_error (
- simple, G_FILE_ERROR,
- g_file_error_from_errno (errno),
- "%s", g_strerror (errno));
- g_simple_async_result_set_op_res_gboolean (simple, FALSE);
+ if (!composer_autosave_state_open (state, &error)) {
+ g_simple_async_result_set_from_error (simple, error);
g_simple_async_result_complete (simple);
+ g_object_unref (simple);
return;
}
- /* Overwrite the file */
- data = g_slice_new (AutosaveData);
- data->composer = g_object_ref (composer);
- data->simple = simple;
- data->state = state;
-
+ /* Overwrite the file. */
g_file_replace_async (
state->file, NULL, FALSE, G_FILE_CREATE_PRIVATE,
G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback)
- autosave_snapshot_cb, data);
+ autosave_snapshot_cb, simple);
}
gboolean
@@ -498,17 +459,15 @@ e_composer_autosave_snapshot_finish (EMsgComposer *composer,
GError **error)
{
GSimpleAsyncResult *simple;
- gboolean success;
g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
simple = G_SIMPLE_ASYNC_RESULT (result);
- success = g_simple_async_result_get_op_res_gboolean (simple);
- g_simple_async_result_propagate_error (simple, error);
- return success;
+ /* Success is assumed in the absense of a GError. */
+ return !g_simple_async_result_propagate_error (simple, error);
}
gchar *
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 9c80a193b9..65523677e9 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -596,7 +596,8 @@ account_hash_algo_to_camel_hash (const gchar *hash_algo)
static CamelMimeMessage *
build_message (EMsgComposer *composer,
gboolean html_content,
- gboolean save_html_object_data)
+ gboolean save_html_object_data,
+ GError **error)
{
GtkhtmlEditor *editor;
EMsgComposerPrivate *p = composer->priv;
@@ -1149,20 +1150,14 @@ exception:
g_object_unref (new);
- if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- e_alert_run_dialog_for_args (
- (GtkWindow *) composer,
- "mail-composer:no-build-message",
- local_error->message, NULL);
-
- g_error_free (local_error);
-
if (recipients) {
for (i=0; i<recipients->len; i++)
g_free (recipients->pdata[i]);
g_ptr_array_free (recipients, TRUE);
}
+ g_propagate_error (error, local_error);
+
return NULL;
}
@@ -3781,7 +3776,8 @@ e_msg_composer_add_inline_image_from_mime_part (EMsgComposer *composer,
**/
CamelMimeMessage *
e_msg_composer_get_message (EMsgComposer *composer,
- gboolean save_html_object_data)
+ gboolean save_html_object_data,
+ GError **error)
{
EAttachmentView *view;
EAttachmentStore *store;
@@ -3803,7 +3799,9 @@ e_msg_composer_get_message (EMsgComposer *composer,
editor = GTKHTML_EDITOR (composer);
html_content = gtkhtml_editor_get_html_mode (editor);
- return build_message (composer, html_content, save_html_object_data);
+ return build_message (
+ composer, html_content,
+ save_html_object_data, error);
}
static gchar *
@@ -3859,7 +3857,8 @@ e_msg_composer_get_message_print (EMsgComposer *composer,
editor = GTKHTML_EDITOR (composer);
html_content = gtkhtml_editor_get_html_mode (editor);
- msg = build_message (composer, html_content, save_html_object_data);
+ msg = build_message (
+ composer, html_content, save_html_object_data, NULL);
if (msg == NULL)
return NULL;
@@ -3871,7 +3870,8 @@ e_msg_composer_get_message_print (EMsgComposer *composer,
flags = msg_composer_get_message_print_helper (
temp_composer, html_content);
- msg = build_message (temp_composer, TRUE, save_html_object_data);
+ msg = build_message (
+ temp_composer, TRUE, save_html_object_data, NULL);
if (msg != NULL)
camel_medium_set_header (
CAMEL_MEDIUM (msg), "X-Evolution-Format", flags);
@@ -3883,7 +3883,8 @@ e_msg_composer_get_message_print (EMsgComposer *composer,
}
CamelMimeMessage *
-e_msg_composer_get_message_draft (EMsgComposer *composer)
+e_msg_composer_get_message_draft (EMsgComposer *composer,
+ GError **error)
{
GtkhtmlEditor *editor;
EComposerHeaderTable *table;
@@ -3917,7 +3918,7 @@ e_msg_composer_get_message_draft (EMsgComposer *composer)
smime_encrypt = gtk_toggle_action_get_active (action);
gtk_toggle_action_set_active (action, FALSE);
- msg = build_message (composer, TRUE, TRUE);
+ msg = build_message (composer, TRUE, TRUE, error);
if (msg == NULL)
return NULL;
@@ -3933,9 +3934,6 @@ e_msg_composer_get_message_draft (EMsgComposer *composer)
action = GTK_TOGGLE_ACTION (ACTION (SMIME_ENCRYPT));
gtk_toggle_action_set_active (action, smime_encrypt);
- if (msg == NULL)
- return NULL;
-
/* Attach account info to the draft. */
account = e_composer_header_table_get_account (table);
if (account && account->name)
diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h
index 5b44e74ca2..4c51929f06 100644
--- a/composer/e-msg-composer.h
+++ b/composer/e-msg-composer.h
@@ -114,14 +114,16 @@ void e_msg_composer_add_inline_image_from_mime_part
CamelMimePart *part);
CamelMimeMessage *
e_msg_composer_get_message (EMsgComposer *composer,
- gboolean save_html_object_data);
+ gboolean save_html_object_data,
+ GError **error);
CamelMimeMessage *
e_msg_composer_get_message_print
(EMsgComposer *composer,
gboolean save_html_object_data);
CamelMimeMessage *
e_msg_composer_get_message_draft
- (EMsgComposer *composer);
+ (EMsgComposer *composer,
+ GError **error);
void e_msg_composer_show_sig_file (EMsgComposer *composer);
CamelInternetAddress *