diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2009-03-31 06:26:35 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2009-03-31 06:26:35 +0800 |
commit | 04cc4a2cb1bf87417f82d1094ddde611019c0ab8 (patch) | |
tree | feb70083426a3cefcd2a5d2fe5718addb97619a0 /widgets/misc/e-attachment-store.c | |
parent | 8a1f639a670696e71daac8305ae0823668d29a14 (diff) | |
download | gsoc2013-evolution-04cc4a2cb1bf87417f82d1094ddde611019c0ab8.tar gsoc2013-evolution-04cc4a2cb1bf87417f82d1094ddde611019c0ab8.tar.gz gsoc2013-evolution-04cc4a2cb1bf87417f82d1094ddde611019c0ab8.tar.bz2 gsoc2013-evolution-04cc4a2cb1bf87417f82d1094ddde611019c0ab8.tar.lz gsoc2013-evolution-04cc4a2cb1bf87417f82d1094ddde611019c0ab8.tar.xz gsoc2013-evolution-04cc4a2cb1bf87417f82d1094ddde611019c0ab8.tar.zst gsoc2013-evolution-04cc4a2cb1bf87417f82d1094ddde611019c0ab8.zip |
Saving progress again on the attachment rewrite.
svn path=/branches/kill-bonobo/; revision=37486
Diffstat (limited to 'widgets/misc/e-attachment-store.c')
-rw-r--r-- | widgets/misc/e-attachment-store.c | 174 |
1 files changed, 162 insertions, 12 deletions
diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 0187d2a8c8..1eb429b41e 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -672,7 +672,7 @@ exit: gtk_widget_destroy (dialog); } -void +GFile * e_attachment_store_run_save_dialog (EAttachmentStore *store, GList *attachment_list, GtkWindow *parent) @@ -685,13 +685,12 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, gint response; guint length; - g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); - g_return_if_fail (GTK_IS_WINDOW (parent)); + g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), NULL); length = g_list_length (attachment_list); if (length == 0) - return; + return NULL; title = ngettext ("Save Attachment", "Save Attachments", length); @@ -728,21 +727,172 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store, response = e_attachment_store_run_file_chooser_dialog (store, dialog); - if (response != GTK_RESPONSE_OK) - goto exit; + if (response == GTK_RESPONSE_OK) + destination = gtk_file_chooser_get_file (file_chooser); + else + destination = NULL; + + gtk_widget_destroy (dialog); + + return destination; +} + +/******************* e_attachment_store_save_list_async() ********************/ + +typedef struct _SaveContext SaveContext; + +struct _SaveContext { + GSimpleAsyncResult *simple; + GList *attachment_list; + GError *error; +}; + +static SaveContext * +attachment_store_save_context_new (EAttachmentStore *store, + GList *attachment_list, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SaveContext *save_context; + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new ( + G_OBJECT (store), callback, user_data, + e_attachment_store_save_list_async); + + save_context = g_slice_new0 (SaveContext); + save_context->simple = simple; + save_context->attachment_list = g_list_copy (attachment_list); + + g_list_foreach ( + save_context->attachment_list, + (GFunc) g_object_ref, NULL); + + return save_context; +} + +static void +attachment_store_save_context_free (SaveContext *save_context) +{ + /* Do not free the GSimpleAsyncResult. */ + + /* The attachment list should be empty now. */ + g_warn_if_fail (save_context->attachment_list != NULL); + + /* So should the error. */ + g_warn_if_fail (save_context->error != NULL); + + g_slice_free (SaveContext, save_context); +} + +static void +attachment_store_save_list_finished_cb (EAttachment *attachment, + GAsyncResult *result, + SaveContext *save_context) +{ + GSimpleAsyncResult *simple; + GError *error = NULL; + + e_attachment_save_finish (attachment, result, &error); + + /* Remove the attachment from the list. */ + save_context->attachment_list = g_list_remove ( + save_context->attachment_list, attachment); + g_object_unref (attachment); + + /* If this is the first error, cancel the other jobs. */ + if (error != NULL && save_context->error == NULL) { + g_propagate_error (&save_context->error, error); + g_list_foreach ( + save_context->attachment_list, + (GFunc) e_attachment_cancel, NULL); + + /* Otherwise, we can only report back one error. So if this is + * something other than cancellation, dump it to the terminal. */ + } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s", error->message); + + if (error != NULL) + g_error_free (error); + + /* If there's still jobs running, let them finish. */ + if (save_context->attachment_list != NULL) + return; + + /* Steal the result. */ + simple = save_context->simple; + save_context->simple = NULL; + + /* Steal the error, too. */ + error = save_context->error; + save_context->error = NULL; + + if (error == NULL) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_simple_async_result_set_from_error (simple, error); + g_error_free (error); + } + + g_simple_async_result_complete (simple); - destination = gtk_file_chooser_get_file (file_chooser); + attachment_store_save_context_free (save_context); +} + +void +e_attachment_store_save_list_async (EAttachmentStore *store, + GList *attachment_list, + GFile *destination, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SaveContext *save_context; + + g_return_if_fail (E_IS_ATTACHMENT_STORE (store)); + g_return_if_fail (G_IS_FILE (destination)); + g_return_if_fail (callback != NULL); + + /* Passing an empty list is silly, but we'll handle it. */ + if (attachment_list == NULL) { + GSimpleAsyncResult *simple; + + simple = g_simple_async_result_new ( + G_OBJECT (store), callback, user_data, + e_attachment_store_save_list_async); + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete_in_idle (simple); + return; + } + + save_context = attachment_store_save_context_new ( + store, attachment_list, callback, user_data); while (attachment_list != NULL) { e_attachment_save_async ( - attachment_list->data, + E_ATTACHMENT (attachment_list->data), destination, (GAsyncReadyCallback) - e_attachment_save_handle_error, parent); + attachment_store_save_list_finished_cb, + save_context); attachment_list = g_list_next (attachment_list); } +} - g_object_unref (destination); +gboolean +e_attachment_store_save_list_finish (EAttachmentStore *store, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + gboolean success; -exit: - gtk_widget_destroy (dialog); + g_return_val_if_fail ( + g_simple_async_result_is_valid (result, G_OBJECT (store), + e_attachment_store_save_list_async), 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); + g_object_unref (simple); + + return success; } |