[evolution] EMailConfigPage: Add submit() asynchronous method.



commit ae3305a74b82cc31f9472ef87b4abcce65d0bc43
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Jul 18 13:21:56 2012 -0400

    EMailConfigPage: Add submit() asynchronous method.
    
    This method is meant for pages that show server-side settings instead of
    client-side settings stored in key files.  It's called after all scratch
    sources have been successfully submitted to the D-Bus service.
    
    The driving use case for this is evolution-ews's "Out of Office" page,
    which is only shown by EMailConfigNotebook and so that's currently the
    only place where submit() is invoked for all pages.
    
    Should a need arise for EMailConfigAssistant to also invoke submit()
    for all pages, then EMailConfigNotebook can be used as a reference.

 mail/e-mail-config-notebook.c |  104 ++++++++++++++++++++++------
 mail/e-mail-config-page.c     |  151 +++++++++++++++++++++++++++++++++++------
 mail/e-mail-config-page.h     |   28 +++++++-
 3 files changed, 239 insertions(+), 44 deletions(-)
---
diff --git a/mail/e-mail-config-notebook.c b/mail/e-mail-config-notebook.c
index 8c437e4..4c8cbc9 100644
--- a/mail/e-mail-config-notebook.c
+++ b/mail/e-mail-config-notebook.c
@@ -44,6 +44,7 @@ struct _EMailConfigNotebookPrivate {
 struct _AsyncContext {
 	ESourceRegistry *registry;
 	GCancellable *cancellable;
+	GQueue *page_queue;
 	GQueue *source_queue;
 };
 
@@ -74,6 +75,10 @@ async_context_free (AsyncContext *async_context)
 		g_object_unref (async_context->cancellable);
 
 	g_queue_free_full (
+		async_context->page_queue,
+		(GDestroyNotify) g_object_unref);
+
+	g_queue_free_full (
 		async_context->source_queue,
 		(GDestroyNotify) g_object_unref);
 
@@ -672,20 +677,20 @@ e_mail_config_notebook_check_complete (EMailConfigNotebook *notebook)
 /********************** e_mail_config_notebook_commit() **********************/
 
 static void
-mail_config_notebook_commit_cb (GObject *object,
-                                GAsyncResult *result,
-                                gpointer user_data)
+mail_config_notebook_page_submit_cb (GObject *source_object,
+                                     GAsyncResult *result,
+                                     gpointer user_data)
 {
 	GSimpleAsyncResult *simple;
 	AsyncContext *async_context;
-	ESource *next_source;
+	EMailConfigPage *next_page;
 	GError *error = NULL;
 
 	simple = G_SIMPLE_ASYNC_RESULT (user_data);
 	async_context = g_simple_async_result_get_op_res_gpointer (simple);
 
-	e_source_registry_commit_source_finish (
-		E_SOURCE_REGISTRY (object), result, &error);
+	e_mail_config_page_submit_finish (
+		E_MAIL_CONFIG_PAGE (source_object), result, &error);
 
 	if (error != NULL) {
 		g_simple_async_result_take_error (simple, error);
@@ -694,20 +699,71 @@ mail_config_notebook_commit_cb (GObject *object,
 		return;
 	}
 
-	next_source = g_queue_pop_head (async_context->source_queue);
+	next_page = g_queue_pop_head (async_context->page_queue);
+
+	/* Submit the next EMailConfigPage. */
+	if (next_page != NULL) {
+		e_mail_config_page_submit (
+			next_page, async_context->cancellable,
+			mail_config_notebook_page_submit_cb, simple);
+
+		g_object_unref (next_page);
 
-	if (next_source == NULL) {
+	/* All done! */
+	} else {
+		g_simple_async_result_complete (simple);
+		g_object_unref (simple);
+	}
+}
+
+static void
+mail_config_notebook_source_commit_cb (GObject *source_object,
+                                       GAsyncResult *result,
+                                       gpointer user_data)
+{
+	GSimpleAsyncResult *simple;
+	AsyncContext *async_context;
+	ESource *next_source;
+	GError *error = NULL;
+
+	simple = G_SIMPLE_ASYNC_RESULT (user_data);
+	async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+	e_source_registry_commit_source_finish (
+		E_SOURCE_REGISTRY (source_object), result, &error);
+
+	if (error != NULL) {
+		g_simple_async_result_take_error (simple, error);
 		g_simple_async_result_complete (simple);
 		g_object_unref (simple);
 		return;
 	}
 
-	e_source_registry_commit_source (
-		async_context->registry, next_source,
-		async_context->cancellable,
-		mail_config_notebook_commit_cb, simple);
+	next_source = g_queue_pop_head (async_context->source_queue);
+
+	/* Commit the next ESources. */
+	if (next_source != NULL) {
+		e_source_registry_commit_source (
+			async_context->registry, next_source,
+			async_context->cancellable,
+			mail_config_notebook_source_commit_cb, simple);
+
+		g_object_unref (next_source);
+
+	/* ESources done, start on the EMailConfigPages. */
+	} else {
+		EMailConfigPage *page;
 
-	g_object_unref (next_source);
+		/* There should be at least one page,
+		 * so we can skip the NULL check here. */
+		page = g_queue_pop_head (async_context->page_queue);
+
+		e_mail_config_page_submit (
+			page, async_context->cancellable,
+			mail_config_notebook_page_submit_cb, simple);
+
+		g_object_unref (page);
+	}
 }
 
 void
@@ -722,30 +778,32 @@ e_mail_config_notebook_commit (EMailConfigNotebook *notebook,
 	EMailSession *session;
 	ESource *source;
 	GList *list, *link;
-	GQueue *queue;
+	GQueue *page_queue;
+	GQueue *source_queue;
 
 	g_return_if_fail (E_IS_MAIL_CONFIG_NOTEBOOK (notebook));
 
 	session = e_mail_config_notebook_get_session (notebook);
 	registry = e_mail_session_get_registry (session);
 
-	queue = g_queue_new ();
+	page_queue = g_queue_new ();
+	source_queue = g_queue_new ();
 
 	/* Queue the collection data source if one is defined. */
 	source = e_mail_config_notebook_get_collection_source (notebook);
 	if (source != NULL)
-		g_queue_push_tail (queue, g_object_ref (source));
+		g_queue_push_tail (source_queue, g_object_ref (source));
 
 	/* Queue the mail-related data sources for the account. */
 	source = e_mail_config_notebook_get_account_source (notebook);
 	if (source != NULL)
-		g_queue_push_tail (queue, g_object_ref (source));
+		g_queue_push_tail (source_queue, g_object_ref (source));
 	source = e_mail_config_notebook_get_identity_source (notebook);
 	if (source != NULL)
-		g_queue_push_tail (queue, g_object_ref (source));
+		g_queue_push_tail (source_queue, g_object_ref (source));
 	source = e_mail_config_notebook_get_transport_source (notebook);
 	if (source != NULL)
-		g_queue_push_tail (queue, g_object_ref (source));
+		g_queue_push_tail (source_queue, g_object_ref (source));
 
 	list = gtk_container_get_children (GTK_CONTAINER (notebook));
 
@@ -757,7 +815,8 @@ e_mail_config_notebook_commit (EMailConfigNotebook *notebook,
 		if (E_IS_MAIL_CONFIG_PAGE (link->data)) {
 			EMailConfigPage *page;
 			page = E_MAIL_CONFIG_PAGE (link->data);
-			e_mail_config_page_commit_changes (page, queue);
+			g_queue_push_tail (page_queue, g_object_ref (page));
+			e_mail_config_page_commit_changes (page, source_queue);
 		}
 	}
 
@@ -765,7 +824,8 @@ e_mail_config_notebook_commit (EMailConfigNotebook *notebook,
 
 	async_context = g_slice_new0 (AsyncContext);
 	async_context->registry = g_object_ref (registry);
-	async_context->source_queue = queue;  /* takes ownership */
+	async_context->page_queue = page_queue;      /* takes ownership */
+	async_context->source_queue = source_queue;  /* takes ownership */
 
 	if (G_IS_CANCELLABLE (cancellable))
 		async_context->cancellable = g_object_ref (cancellable);
@@ -783,7 +843,7 @@ e_mail_config_notebook_commit (EMailConfigNotebook *notebook,
 	e_source_registry_commit_source (
 		async_context->registry, source,
 		async_context->cancellable,
-		mail_config_notebook_commit_cb, simple);
+		mail_config_notebook_source_commit_cb, simple);
 
 	g_object_unref (source);
 }
diff --git a/mail/e-mail-config-page.c b/mail/e-mail-config-page.c
index 29d18e8..54c71b1 100644
--- a/mail/e-mail-config-page.c
+++ b/mail/e-mail-config-page.c
@@ -21,6 +21,8 @@
 #include <config.h>
 #include <glib/gi18n-lib.h>
 
+#include <libedataserver/libedataserver.h>
+
 #include <e-util/e-marshal.h>
 
 enum {
@@ -45,6 +47,65 @@ mail_config_page_check_complete (EMailConfigPage *page)
 }
 
 static gboolean
+mail_config_page_submit_sync (EMailConfigPage *page,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+	EAsyncClosure *closure;
+	GAsyncResult *result;
+	gboolean success;
+
+	closure = e_async_closure_new ();
+
+	e_mail_config_page_submit (
+		page, cancellable, e_async_closure_callback, closure);
+
+	result = e_async_closure_wait (closure);
+
+	success = e_mail_config_page_submit_finish (page, result, error);
+
+	e_async_closure_free (closure);
+
+	return success;
+}
+
+static void
+mail_config_page_submit (EMailConfigPage *page,
+                         GCancellable *cancellable,
+                         GAsyncReadyCallback callback,
+                         gpointer user_data)
+{
+	GSimpleAsyncResult *simple;
+
+	simple = g_simple_async_result_new (
+		G_OBJECT (page), callback,
+		user_data, mail_config_page_submit);
+
+	g_simple_async_result_set_check_cancellable (simple, cancellable);
+
+	g_simple_async_result_complete_in_idle (simple);
+
+	g_object_unref (simple);
+}
+
+static gboolean
+mail_config_page_submit_finish (EMailConfigPage *page,
+                                GAsyncResult *result,
+                                GError **error)
+{
+	GSimpleAsyncResult *simple;
+
+	g_return_val_if_fail (
+		g_simple_async_result_is_valid (
+		result, G_OBJECT (page), mail_config_page_submit), FALSE);
+
+	simple = G_SIMPLE_ASYNC_RESULT (result);
+
+	/* Assume success unless a GError is set. */
+	return !g_simple_async_result_propagate_error (simple, error);
+}
+
+static gboolean
 mail_config_page_check_complete_accumulator (GSignalInvocationHint *ihint,
                                              GValue *return_accu,
                                              const GValue *handler_return,
@@ -66,6 +127,9 @@ e_mail_config_page_default_init (EMailConfigPageInterface *interface)
 	interface->page_type = GTK_ASSISTANT_PAGE_CONTENT;
 
 	interface->check_complete = mail_config_page_check_complete;
+	interface->submit_sync = mail_config_page_submit_sync;
+	interface->submit = mail_config_page_submit;
+	interface->submit_finish = mail_config_page_submit_finish;
 
 	signals[CHANGED] = g_signal_new (
 		"changed",
@@ -105,6 +169,37 @@ e_mail_config_page_default_init (EMailConfigPageInterface *interface)
 		G_TYPE_POINTER);
 }
 
+gint
+e_mail_config_page_compare (GtkWidget *page_a,
+                            GtkWidget *page_b)
+{
+	EMailConfigPageInterface *interface_a = NULL;
+	EMailConfigPageInterface *interface_b = NULL;
+
+	if (E_IS_MAIL_CONFIG_PAGE (page_a))
+		interface_a = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page_a);
+
+	if (E_IS_MAIL_CONFIG_PAGE (page_b))
+		interface_b = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page_b);
+
+	if (interface_a == interface_b)
+		return 0;
+
+	if (interface_a != NULL && interface_b == NULL)
+		return -1;
+
+	if (interface_a == NULL && interface_b != NULL)
+		return 1;
+
+	if (interface_a->sort_order < interface_b->sort_order)
+		return -1;
+
+	if (interface_a->sort_order > interface_b->sort_order)
+		return 1;
+
+	return 0;
+}
+
 void
 e_mail_config_page_changed (EMailConfigPage *page)
 {
@@ -143,34 +238,50 @@ e_mail_config_page_commit_changes (EMailConfigPage *page,
 	g_signal_emit (page, signals[COMMIT_CHANGES], 0, source_queue);
 }
 
-gint
-e_mail_config_page_compare (GtkWidget *page_a,
-                            GtkWidget *page_b)
+gboolean
+e_mail_config_page_submit_sync (EMailConfigPage *page,
+                                GCancellable *cancellable,
+                                GError **error)
 {
-	EMailConfigPageInterface *interface_a = NULL;
-	EMailConfigPageInterface *interface_b = NULL;
+	EMailConfigPageInterface *interface;
 
-	if (E_IS_MAIL_CONFIG_PAGE (page_a))
-		interface_a = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page_a);
+	g_return_val_if_fail (E_IS_MAIL_CONFIG_PAGE (page), FALSE);
 
-	if (E_IS_MAIL_CONFIG_PAGE (page_b))
-		interface_b = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page_b);
+	interface = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page);
+	g_return_val_if_fail (interface->submit_sync != NULL, FALSE);
 
-	if (interface_a == interface_b)
-		return 0;
+	return interface->submit_sync (page, cancellable, error);
+}
 
-	if (interface_a != NULL && interface_b == NULL)
-		return -1;
+void
+e_mail_config_page_submit (EMailConfigPage *page,
+                           GCancellable *cancellable,
+                           GAsyncReadyCallback callback,
+                           gpointer user_data)
+{
+	EMailConfigPageInterface *interface;
 
-	if (interface_a == NULL && interface_b != NULL)
-		return 1;
+	g_return_if_fail (E_IS_MAIL_CONFIG_PAGE (page));
 
-	if (interface_a->sort_order < interface_b->sort_order)
-		return -1;
+	interface = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page);
+	g_return_if_fail (interface->submit != NULL);
 
-	if (interface_a->sort_order > interface_b->sort_order)
-		return 1;
+	return interface->submit (page, cancellable, callback, user_data);
+}
 
-	return 0;
+gboolean
+e_mail_config_page_submit_finish (EMailConfigPage *page,
+                                  GAsyncResult *result,
+                                  GError **error)
+{
+	EMailConfigPageInterface *interface;
+
+	g_return_val_if_fail (E_IS_MAIL_CONFIG_PAGE (page), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+	interface = E_MAIL_CONFIG_PAGE_GET_INTERFACE (page);
+	g_return_val_if_fail (interface->submit_finish != NULL, FALSE);
+
+	return interface->submit_finish (page, result, error);
 }
 
diff --git a/mail/e-mail-config-page.h b/mail/e-mail-config-page.h
index 40a949a..6561780e 100644
--- a/mail/e-mail-config-page.h
+++ b/mail/e-mail-config-page.h
@@ -52,9 +52,24 @@ struct _EMailConfigPageInterface {
 	gboolean	(*check_complete)	(EMailConfigPage *page);
 	void		(*commit_changes)	(EMailConfigPage *page,
 						 GQueue *source_queue);
+
+	/* Intended for pages with server-side settings.
+	 * Called after client-side settings are written. */
+	gboolean	(*submit_sync)		(EMailConfigPage *page,
+						 GCancellable *cancellable,
+						 GError **error);
+	void		(*submit)		(EMailConfigPage *page,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+	gboolean	(*submit_finish)	(EMailConfigPage *page,
+						 GAsyncResult *result,
+						 GError **error);
 };
 
 GType		e_mail_config_page_get_type	(void) G_GNUC_CONST;
+gint		e_mail_config_page_compare	(GtkWidget *page_a,
+						 GtkWidget *page_b);
 void		e_mail_config_page_changed	(EMailConfigPage *page);
 void		e_mail_config_page_setup_defaults
 						(EMailConfigPage *page);
@@ -63,8 +78,17 @@ gboolean	e_mail_config_page_check_complete
 void		e_mail_config_page_commit_changes
 						(EMailConfigPage *page,
 						 GQueue *source_queue);
-gint		e_mail_config_page_compare	(GtkWidget *page_a,
-						 GtkWidget *page_b);
+gboolean	e_mail_config_page_submit_sync	(EMailConfigPage *page,
+						 GCancellable *cancellable,
+						 GError **error);
+void		e_mail_config_page_submit	(EMailConfigPage *page,
+						 GCancellable *cancellable,
+						 GAsyncReadyCallback callback,
+						 gpointer user_data);
+gboolean	e_mail_config_page_submit_finish
+						(EMailConfigPage *page,
+						 GAsyncResult *result,
+						 GError **error);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]