[gnome-online-accounts] telepathy: implement the add_account method
- From: Marco Barisione <mbari src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts] telepathy: implement the add_account method
- Date: Thu, 22 Aug 2013 14:20:10 +0000 (UTC)
commit 0683d960ea4a1c7e9edf01b6817008dac4302663
Author: Marco Barisione <marco barisione collabora co uk>
Date: Wed Jul 17 16:58:30 2013 +0100
telepathy: implement the add_account method
https://bugzilla.gnome.org/show_bug.cgi?id=696267
src/goabackend/goatelepathyprovider.c | 260 ++++++++++++++++++++++++++++++++-
1 files changed, 259 insertions(+), 1 deletions(-)
---
diff --git a/src/goabackend/goatelepathyprovider.c b/src/goabackend/goatelepathyprovider.c
index f4d197b..308494c 100644
--- a/src/goabackend/goatelepathyprovider.c
+++ b/src/goabackend/goatelepathyprovider.c
@@ -23,6 +23,7 @@
#include "config.h"
#include <glib/gi18n-lib.h>
+#include <tp-account-widgets/tpaw-account-widget.h>
#include <tp-account-widgets/tpaw-utils.h>
#include "goaprovider.h"
@@ -79,6 +80,32 @@ G_DEFINE_TYPE (GoaTelepathyProvider, goa_telepathy_provider, GOA_TYPE_PROVIDER);
/* ---------------------------------------------------------------------------------------------------- */
+/* Telepathy / telepathy-account widgets utility functions. */
+
+static void
+account_settings_ready_cb (TpawAccountSettings *settings,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GMainLoop *loop = user_data;
+
+ g_main_loop_quit (loop);
+}
+
+static void
+wait_for_account_settings_ready (TpawAccountSettings *settings,
+ GMainLoop *loop)
+{
+ if (!tpaw_account_settings_is_ready (settings))
+ {
+ g_signal_connect (settings, "notify::ready",
+ G_CALLBACK (account_settings_ready_cb), loop);
+ g_main_loop_run (loop);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static const gchar *
get_provider_type (GoaProvider *provider)
{
@@ -109,6 +136,137 @@ get_provider_features (GoaProvider *provider)
/* ---------------------------------------------------------------------------------------------------- */
+typedef struct
+{
+ GMainLoop *loop;
+ GCancellable *cancellable;
+ GoaObject *ret;
+ GError *error;
+
+ GoaTelepathyProvider *provider;
+ GtkDialog *dialog;
+ GtkBox *vbox;
+
+ TpAccount *tp_account;
+
+ GoaClient *goa_client;
+ guint goa_account_added_id;
+} AddAccountData;
+
+static gboolean
+check_goa_object_match (AddAccountData *data,
+ GoaObject *goa_object)
+{
+ GoaTelepathyProviderPrivate *priv = data->provider->priv;
+ GoaAccount *goa_account = NULL;
+ const gchar *provider_type = NULL;
+ const gchar *goa_id = NULL;
+ const gchar *tp_id = NULL;
+
+ if (data->tp_account == NULL)
+ {
+ /* Still waiting for the creation of the TpAccount */
+ return FALSE;
+ }
+
+ goa_account = goa_object_peek_account (goa_object);
+ provider_type = goa_account_get_provider_type (goa_account);
+ if (g_strcmp0 (provider_type, priv->provider_type) != 0)
+ return FALSE;
+
+ /* The backend-specific identity is set to the object path of the
+ * corresponding Telepathy account object. */
+ goa_id = goa_account_get_identity (goa_account);
+ tp_id = tp_proxy_get_object_path (TP_PROXY (data->tp_account));
+ if (g_strcmp0 (goa_id, tp_id) == 0)
+ {
+ /* Found it! */
+ data->ret = g_object_ref (goa_object);
+ g_main_loop_quit (data->loop);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+check_existing_goa_accounts (AddAccountData *data)
+{
+ GList *goa_accounts = NULL;
+ GList *l = NULL;
+ gboolean found = FALSE;
+
+ if (data->tp_account == NULL || data->goa_client == NULL)
+ return FALSE;
+
+ goa_accounts = goa_client_get_accounts (data->goa_client);
+ for (l = goa_accounts; l != NULL; l = l->next)
+ {
+ if (check_goa_object_match (data, l->data))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ g_list_free_full (goa_accounts, g_object_unref);
+
+ return found;
+}
+
+static void
+tp_account_created_cb (TpawAccountWidget *widget,
+ TpAccount *tp_account,
+ AddAccountData *data)
+{
+ g_assert (data->tp_account == NULL);
+ data->tp_account = g_object_ref (tp_account);
+
+ check_existing_goa_accounts (data);
+}
+
+static void
+goa_account_added_cb (GoaClient *client,
+ GoaObject *goa_object,
+ gpointer user_data)
+{
+ AddAccountData *data = user_data;
+
+ check_goa_object_match (data, goa_object);
+}
+
+static void
+goa_client_new_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ AddAccountData *data = user_data;
+
+ data->goa_client = goa_client_new_finish (result, &data->error);
+ if (data->goa_client == NULL)
+ {
+ g_set_error (&data->error,
+ GOA_ERROR,
+ GOA_ERROR_FAILED,
+ _("Failed to initialise a GOA client"));
+ g_main_loop_quit (data->loop);
+ return;
+ }
+
+ if (!check_existing_goa_accounts (data))
+ {
+ data->goa_account_added_id = g_signal_connect (data->goa_client,
+ "account-added", G_CALLBACK (goa_account_added_cb), data);
+ }
+}
+
+static void
+account_widget_close_cb (TpawAccountWidget *widget,
+ GtkResponseType response,
+ AddAccountData *data)
+{
+ gtk_dialog_response (data->dialog, response);
+}
+
static GoaObject *
add_account (GoaProvider *provider,
GoaClient *client,
@@ -116,7 +274,107 @@ add_account (GoaProvider *provider,
GtkBox *vbox,
GError **error)
{
- return NULL;
+ GoaTelepathyProviderPrivate *priv = GOA_TELEPATHY_PROVIDER (provider)->priv;
+ AddAccountData data;
+ TpawAccountSettings *settings = NULL;
+ GtkWidget *action_area = NULL;
+ GList *children = NULL;
+ GList *l = NULL;
+ TpawAccountWidget *account_widget = NULL;
+ GtkRequisition req;
+ gint response;
+
+ settings = tpaw_protocol_create_account_settings (priv->protocol);
+ if (settings == NULL)
+ {
+ g_set_error (&data.error,
+ GOA_ERROR,
+ GOA_ERROR_FAILED,
+ _("Failed to create a user interface for %s"),
+ priv->protocol != NULL ?
+ tpaw_protocol_get_protocol_name (priv->protocol) :
+ "(null)");
+ return NULL;
+ }
+
+ memset (&data, 0, sizeof (AddAccountData));
+ data.cancellable = g_cancellable_new ();
+ data.loop = g_main_loop_new (NULL, FALSE);
+ data.error = NULL;
+ data.provider = GOA_TELEPATHY_PROVIDER (provider);
+ data.dialog = dialog;
+ data.vbox = vbox;
+
+ goa_client_new (data.cancellable, goa_client_new_cb, &data);
+ wait_for_account_settings_ready (settings, data.loop);
+
+ action_area = gtk_dialog_get_action_area (dialog);
+ /* Remove the default button. */
+ children = gtk_container_get_children (GTK_CONTAINER (action_area));
+ for (l = children; l != NULL; l = l->next)
+ {
+ GtkWidget *child = l->data;
+ gtk_container_remove (GTK_CONTAINER (action_area), child);
+ }
+ g_list_free (children);
+
+ account_widget = tpaw_account_widget_new_for_protocol (settings,
+ GTK_BOX (action_area), FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (account_widget), FALSE, FALSE, 0);
+ gtk_widget_show (GTK_WIDGET (account_widget));
+ g_signal_connect (account_widget, "account-created",
+ G_CALLBACK (tp_account_created_cb), &data);
+ g_signal_connect (account_widget, "close",
+ G_CALLBACK (account_widget_close_cb), &data);
+
+ /* The dialog now contains a lot of empty space between the account widget
+ * and the buttons. We force it's vertical size to be just right to fit the
+ * widget. */
+ gtk_widget_get_preferred_size (GTK_WIDGET (dialog), NULL, &req);
+ gtk_widget_set_size_request (GTK_WIDGET (dialog), req.width, 1);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_APPLY)
+ {
+ g_set_error (&data.error,
+ GOA_ERROR,
+ GOA_ERROR_DIALOG_DISMISSED,
+ _("Dialog was dismissed"));
+ goto out;
+ }
+
+ if (data.error != NULL)
+ {
+ /* An error could have been set by a callback */
+ goto out;
+ }
+
+ if (data.ret == NULL && !g_cancellable_is_cancelled (data.cancellable))
+ {
+ /* We wait for the account to be created */
+ g_main_loop_run (data.loop);
+ }
+
+out:
+ if (data.error != NULL)
+ g_propagate_error (error, data.error);
+ else
+ g_assert (data.ret != NULL);
+
+ if (data.cancellable != NULL)
+ {
+ g_cancellable_cancel (data.cancellable);
+ g_object_unref (data.cancellable);
+ }
+
+ if (data.goa_account_added_id)
+ g_signal_handler_disconnect (data.goa_client, data.goa_account_added_id);
+
+ g_clear_pointer (&data.loop, g_main_loop_unref);
+ g_clear_object (&data.goa_client);
+ g_clear_object (&data.tp_account);
+
+ return data.ret;
}
/* ---------------------------------------------------------------------------------------------------- */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]