From da3ae4fd5fa723abc4574d0459c761e76abba080 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 30 Sep 2009 17:18:36 -0400 Subject: Various composer autosave fixes. --- composer/e-composer-autosave.c | 142 +++++++++++++++++++++++------------------ composer/e-msg-composer.c | 20 +++++- 2 files changed, 98 insertions(+), 64 deletions(-) (limited to 'composer') diff --git a/composer/e-composer-autosave.c b/composer/e-composer-autosave.c index 5c5d7a5bce..1ed4e84ac3 100644 --- a/composer/e-composer-autosave.c +++ b/composer/e-composer-autosave.c @@ -115,6 +115,23 @@ composer_autosave_state_open (AutosaveState *state) return TRUE; } +static void +composer_autosave_finish_cb (EMsgComposer *composer, + GAsyncResult *result) +{ + GError *error = NULL; + + e_composer_autosave_snapshot_finish (composer, result, &error); + + if (error != NULL) { + e_error_run ( + GTK_WINDOW (composer), + "mail-composer:no-autosave", + "", error->message, NULL); + g_error_free (error); + } +} + static void composer_autosave_foreach (EMsgComposer *composer) { @@ -122,7 +139,9 @@ composer_autosave_foreach (EMsgComposer *composer) g_return_if_fail (E_IS_MSG_COMPOSER (composer)); if (e_composer_autosave_get_enabled (composer)) - e_composer_autosave_snapshot_async (composer, NULL, NULL); + e_composer_autosave_snapshot_async ( + composer, (GAsyncReadyCallback) + composer_autosave_finish_cb, NULL); } static gint @@ -248,8 +267,8 @@ e_composer_autosave_unregister (EMsgComposer *composer) } typedef struct { - GSimpleAsyncResult *result; EMsgComposer *composer; + GSimpleAsyncResult *simple; AutosaveState *state; /* Transient data */ @@ -260,18 +279,29 @@ static void autosave_data_free (AutosaveData *data) { g_object_unref (data->composer); + + 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) +autosave_snapshot_check_for_error (AutosaveData *data, + GError *error) { + GSimpleAsyncResult *simple; + if (error == NULL) return FALSE; - g_simple_async_result_set_from_error (data->result, error); - g_simple_async_result_set_op_res_gboolean (data->result, FALSE); - g_simple_async_result_complete (data->result); + /* Steal the result. */ + simple = data->simple; + data->simple = NULL; + + 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); @@ -280,16 +310,15 @@ autosave_snapshot_check_for_error (AutosaveData *data, GError *error) } static void -autosave_snapshot_splice_cb (GOutputStream *autosave_stream, - GSimpleAsyncResult *result, +autosave_snapshot_splice_cb (GOutputStream *output_stream, + GAsyncResult *result, AutosaveData *data) { - gssize length; + GSimpleAsyncResult *simple; GError *error = NULL; - length = g_output_stream_splice_finish ( - autosave_stream, G_ASYNC_RESULT (result), &error); - g_object_unref (data->input_stream); + g_output_stream_splice_finish (output_stream, result, &error); + if (autosave_snapshot_check_for_error (data, error)) return; @@ -298,13 +327,19 @@ autosave_snapshot_splice_cb (GOutputStream *autosave_stream, * which doesn't mean it's saved permanently */ e_composer_autosave_set_saved (data->composer, TRUE); - /* Tidy up */ + /* Steal the result. */ + simple = data->simple; + data->simple = NULL; + + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + autosave_data_free (data); } static void -autosave_snapshot_cb (GFile *autosave_file, - GSimpleAsyncResult *result, +autosave_snapshot_cb (GFile *file, + GAsyncResult *result, AutosaveData *data) { CamelMimeMessage *message; @@ -314,18 +349,23 @@ autosave_snapshot_cb (GFile *autosave_file, GByteArray *buffer; GError *error = NULL; - output_stream = g_file_replace_finish ( - autosave_file, G_ASYNC_RESULT (result), &error); + output_stream = g_file_replace_finish (file, result, &error); + if (autosave_snapshot_check_for_error (data, error)) return; /* Extract a MIME message from the composer. */ message = e_msg_composer_get_message_draft (data->composer); if (message == NULL) { - /* If we don't set an error, but return FALSE, the error message - * in this odd case (we don't have an error domain or code) - * will be set in the _finish() function. */ - g_simple_async_result_set_op_res_gboolean (result, FALSE); + GSimpleAsyncResult *simple; + + /* Steal the result. */ + simple = data->simple; + data->simple = NULL; + + /* FIXME Need to set a GError here. */ + g_simple_async_result_set_op_res_gboolean (simple, FALSE); + g_simple_async_result_complete (simple); g_object_unref (output_stream); autosave_data_free (data); return; @@ -333,8 +373,7 @@ autosave_snapshot_cb (GFile *autosave_file, /* Decode the MIME part to an in-memory buffer. We have to do * this because CamelStream is synchronous-only, and using threads - * (as we do with foo()) is dangerous because CamelDataWrapper - * is not reentrant. */ + * is dangerous because CamelDataWrapper is not reentrant. */ buffer = g_byte_array_new (); camel_stream = camel_stream_mem_new (); camel_stream_mem_set_byte_array ( @@ -362,6 +401,7 @@ autosave_snapshot_cb (GFile *autosave_file, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback) autosave_snapshot_splice_cb, data); + g_object_unref (output_stream); } @@ -372,18 +412,18 @@ e_composer_autosave_snapshot_async (EMsgComposer *composer, { AutosaveData *data; AutosaveState *state; - GSimpleAsyncResult *result; + GSimpleAsyncResult *simple; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - result = g_simple_async_result_new ( + 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 (result, TRUE); - g_simple_async_result_complete (result); + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); return; } @@ -394,18 +434,18 @@ e_composer_autosave_snapshot_async (EMsgComposer *composer, errno = 0; if (!composer_autosave_state_open (state)) { g_simple_async_result_set_error ( - result, G_FILE_ERROR, + simple, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); - g_simple_async_result_set_op_res_gboolean (result, FALSE); - g_simple_async_result_complete (result); + g_simple_async_result_set_op_res_gboolean (simple, FALSE); + g_simple_async_result_complete (simple); return; } /* Overwrite the file */ data = g_slice_new (AutosaveData); - data->composer = composer; - data->result = result; + data->composer = g_object_ref (composer); + data->simple = simple; data->state = state; g_file_replace_async ( @@ -416,42 +456,22 @@ e_composer_autosave_snapshot_async (EMsgComposer *composer, gboolean e_composer_autosave_snapshot_finish (EMsgComposer *composer, - GAsyncResult *async_result, + GAsyncResult *result, GError **error) { - GSimpleAsyncResult *result; + 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 (async_result), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - result = G_SIMPLE_ASYNC_RESULT (async_result); - g_warn_if_fail (g_simple_async_result_get_source_tag (result) == - e_composer_autosave_snapshot_async); - - if (g_simple_async_result_propagate_error (result, error) || - !g_simple_async_result_get_op_res_gboolean (result)) { - const gchar *errmsg; - gchar *filename; + simple = G_SIMPLE_ASYNC_RESULT (result); + success = g_simple_async_result_get_op_res_gboolean (simple); + g_simple_async_result_propagate_error (simple, error); + g_object_unref (simple); - /* Sort out the error message; use the GError message if - * possible. The only case where is isn't is where we couldn't - * get the message from the editor. */ - if (error && *error) - errmsg = (*error)->message; - else - errmsg = _("Unable to retrieve message from editor"); - - filename = e_composer_autosave_get_filename (composer); - e_error_run ( - GTK_WINDOW (composer), "mail-composer:no-autosave", - (filename != NULL) ? filename : "", errmsg, NULL); - g_free (filename); - - return FALSE; - } - - return TRUE; + return success; } gchar * diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index 2450212bd9..246a0906b9 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -1262,8 +1262,24 @@ autosave_load_draft_cb (EMsgComposer *composer, GAsyncResult *result, gchar *filename) { - if (e_composer_autosave_snapshot_finish (composer, result, NULL)) + GError *error = NULL; + + if (e_composer_autosave_snapshot_finish (composer, result, &error)) g_unlink (filename); + + else { + e_error_run ( + GTK_WINDOW (composer), + "mail-composer:no-autosave", + (filename != NULL) ? filename : "", + (error != NULL) ? error->message : + _("Unable to reconstruct message from autosave file"), + NULL); + + if (error != NULL) + g_error_free (error); + } + g_free (filename); } @@ -1276,8 +1292,6 @@ autosave_load_draft (const gchar *filename) g_return_val_if_fail (filename != NULL, NULL); - g_warning ("autosave load filename = \"%s\"", filename); - if (!(stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0))) return NULL; -- cgit v1.2.3