[gdm/wip/initial-setup2: 17/32] initial-setup: Implement the online accounts page



commit fd99027595c084f63801cd7b021882d71e38646d
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Oct 21 14:29:42 2011 -0400

    initial-setup: Implement the online accounts page

 configure.ac                          |    2 +
 gui/initial-setup/gdm-initial-setup.c |  371 ++++++++++++++++++++++++++++++++-
 gui/initial-setup/setup.ui            |   25 ++-
 3 files changed, 392 insertions(+), 6 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index becf123..976b393 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,6 +179,8 @@ PKG_CHECK_MODULES(INITIAL_SETUP,
                   libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION
                   accountsservice
                   gweather-3.0
+                  goa-1.0
+                  goa-backend-1.0
                   gtk+-3.0 >= $GTK_REQUIRED_VERSION
                   glib-2.0 >= $GLIB_REQUIRED_VERSION
                   gio-2.0 >= $GLIB_REQUIRED_VERSION
diff --git a/gui/initial-setup/gdm-initial-setup.c b/gui/initial-setup/gdm-initial-setup.c
index a3d84c4..e19e58a 100644
--- a/gui/initial-setup/gdm-initial-setup.c
+++ b/gui/initial-setup/gdm-initial-setup.c
@@ -23,8 +23,14 @@
 #define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
 #include <libgweather/location-entry.h>
 
+#define GOA_API_IS_SUBJECT_TO_CHANGE
+#include <goa/goa.h>
+#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE
+#include <goabackend/goabackend.h>
+
 #define DEFAULT_TZ "Europe/London"
 
+/* Setup data {{{1 */
 typedef struct {
         GtkBuilder *builder;
         GtkAssistant *assistant;
@@ -57,12 +63,15 @@ typedef struct {
         CcTimezoneMap *map;
         TzLocation *current_location;
         DateTimeMechanism *dtm;
+
+        /* online data */
+        GoaClient *goa_client;
 } SetupData;
 
 #define OBJ(type,name) ((type)gtk_builder_get_object(setup->builder,(name)))
 #define WID(name) OBJ(GtkWidget*,name)
 
-/* --- Welcome page --- */
+/* Welcome page {{{1 */
 
 static void
 prepare_welcome_page (SetupData *setup)
@@ -77,7 +86,7 @@ prepare_welcome_page (SetupData *setup)
         gtk_image_set_from_file (GTK_IMAGE (widget), filename);
 }
 
-/* --- Network page --- */
+/* Network page {{{1 */
 
 enum {
         PANEL_WIRELESS_COLUMN_ID,
@@ -772,7 +781,7 @@ prepare_network_page (SetupData *setup)
 out: ;
 }
 
-/* --- Account page --- */
+/* Account page {{{1 */
 
 static void
 update_account_page_status (SetupData *setup)
@@ -969,6 +978,7 @@ create_user (SetupData *setup)
         const gchar *fullname;
         GError *error;
 
+#if 0
         username = gtk_combo_box_text_get_active_text (OBJ(GtkComboBoxText*, "account-username-combo"));
         fullname = gtk_entry_get_text (OBJ(GtkEntry*, "account-fullname-entry"));
 
@@ -978,6 +988,7 @@ create_user (SetupData *setup)
                 g_warning ("Failed to create user: %s", error->message);
                 g_error_free (error);
         }
+#endif
 }
 
 static void save_account_data (SetupData *setup);
@@ -1117,7 +1128,7 @@ prepare_account_page (SetupData *setup)
         update_account_page_status (setup);
 }
 
-/* --- Location page --- */
+/* Location page {{{1 */
 
 
 static void
@@ -1320,7 +1331,353 @@ prepare_location_page (SetupData *setup)
                           G_CALLBACK (location_changed), setup);
 }
 
-/* --- Other setup --- */
+/* Online accounts {{{1 */
+
+static GtkWidget *
+create_provider_button (const gchar *type, const gchar *name, GIcon *icon)
+{
+  GtkWidget *button;
+  GtkWidget *box;
+  GtkWidget *image;
+  GtkWidget *label;
+
+  button = gtk_button_new ();
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
+  gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
+  gtk_container_add (GTK_CONTAINER (button), box);
+
+  image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_BUTTON);
+  gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
+
+  label = gtk_label_new (name);
+  gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+
+  gtk_widget_show (box);
+  gtk_widget_show (image);
+  gtk_widget_show (label);
+
+  g_object_set_data (G_OBJECT (button), "provider-type", (gpointer)type);
+
+  return button;
+}
+
+static void
+add_account (GtkButton *button, gpointer data)
+{
+  SetupData *setup = data;
+  GtkWidget *dialog;
+  GtkWidget *goa_dialog;
+  GtkWidget *vbox;
+  const gchar *provider_type;
+  GoaProvider *provider;
+  GError *error;
+
+  dialog = WID("online-accounts-dialog");
+  gtk_widget_hide (dialog);
+
+  provider_type = g_object_get_data (G_OBJECT (button), "provider-type");
+
+  g_debug ("Adding online account: %s", provider_type);
+
+  provider = goa_provider_get_for_provider_type (provider_type);
+
+  goa_dialog = gtk_dialog_new ();
+
+  gtk_container_set_border_width (GTK_CONTAINER (goa_dialog), 12);
+  gtk_window_set_modal (GTK_WINDOW (goa_dialog), TRUE);
+  gtk_window_set_resizable (GTK_WINDOW (goa_dialog), TRUE);
+  gtk_window_set_transient_for (GTK_WINDOW (goa_dialog), GTK_WINDOW (setup->assistant));
+  /* translators: This is the title of the "Add Account" dialogue.
+   * The title is not visible when using GNOME Shell
+   */
+  gtk_window_set_title (GTK_WINDOW (goa_dialog), _("Add Account"));
+  gtk_dialog_add_button (GTK_DIALOG (goa_dialog),
+                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+
+  vbox = gtk_dialog_get_content_area (GTK_DIALOG (goa_dialog));
+  gtk_widget_set_vexpand (vbox, TRUE);
+
+  gtk_widget_show_all (goa_dialog);
+  gtk_window_present (GTK_WINDOW (goa_dialog));
+
+  error = NULL;
+  goa_provider_add_account (provider,
+                            setup->goa_client,
+                            GTK_DIALOG (goa_dialog),
+                            GTK_BOX (vbox),
+                            &error);
+  gtk_widget_destroy (goa_dialog);
+
+  if (error &&
+      !(error->domain == GOA_ERROR && error->code == GOA_ERROR_DIALOG_DISMISSED))
+        {
+          dialog = gtk_message_dialog_new (GTK_WINDOW (setup->assistant),
+                                           GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_CLOSE,
+                                           _("Error creating account"));
+          gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                                    "%s",
+                                                    error->message);
+          gtk_widget_show (dialog);
+          gtk_dialog_run (GTK_DIALOG (dialog));
+          gtk_widget_destroy (dialog);
+    }
+}
+
+static void
+populate_online_account_dialog (SetupData *setup)
+{
+  GtkWidget *dialog;
+  GtkWidget *content_area;
+  GList *providers, *l;
+  GoaProvider *provider;
+  gchar *provider_name;
+  const gchar *provider_type;
+  GIcon *provider_icon;
+  GtkWidget *button;
+
+
+  dialog = WID("online-accounts-dialog");
+  content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+  providers = goa_provider_get_all ();
+  for (l = providers; l; l = l->next)
+    {
+      provider = GOA_PROVIDER (l->data);
+      provider_type = goa_provider_get_provider_type (provider);
+      provider_name = goa_provider_get_provider_name (provider, NULL);
+      provider_icon = goa_provider_get_provider_icon (provider, NULL);
+      button = create_provider_button (provider_type, provider_name, provider_icon);
+      gtk_container_add (GTK_CONTAINER (content_area), button);
+      gtk_widget_show (button);
+      g_free (provider_name);
+
+      g_signal_connect (button, "clicked", G_CALLBACK (add_account), setup);
+    }
+
+  g_signal_connect (dialog, "delete-event",
+                    G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+}
+
+static void
+show_online_account_dialog (GtkButton *button, gpointer data)
+{
+  SetupData *setup = data;
+  GtkWidget *dialog;
+
+  dialog = WID("online-accounts-dialog");
+
+  gtk_window_present (GTK_WINDOW (dialog));
+}
+
+static void
+remove_account_cb (GoaAccount   *account,
+                   GAsyncResult *res,
+                   gpointer      user_data)
+{
+  SetupData *setup = user_data;
+  GError *error;
+
+  error = NULL;
+  if (!goa_account_call_remove_finish (account, res, &error))
+    {
+      GtkWidget *dialog;
+      dialog = gtk_message_dialog_new (GTK_WINDOW (setup->assistant),
+                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                       GTK_MESSAGE_ERROR,
+                                       GTK_BUTTONS_CLOSE,
+                                       _("Error removing account"));
+      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                                "%s",
+                                                error->message);
+      gtk_widget_show_all (dialog);
+      gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+      g_error_free (error);
+    }
+}
+
+
+static void
+confirm_remove_account (GtkButton *button, gpointer data)
+{
+  SetupData *setup = data;
+  GtkWidget *dialog;
+  GoaObject *object;
+  gint response;
+
+  object = g_object_get_data (G_OBJECT (button), "goa-object");
+
+  dialog = gtk_message_dialog_new (GTK_WINDOW (setup->assistant),
+                                   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                   GTK_MESSAGE_QUESTION,
+                                   GTK_BUTTONS_CANCEL,
+                                   _("Are you sure you want to remove the account?"));
+  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                            _("This will not remove the account on the server."));
+  gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Remove"), GTK_RESPONSE_OK);
+  gtk_widget_show_all (dialog);
+  response = gtk_dialog_run (GTK_DIALOG (dialog));
+  gtk_widget_destroy (dialog);
+
+  if (response == GTK_RESPONSE_OK)
+    {
+      goa_account_call_remove (goa_object_peek_account (object),
+                               NULL, /* GCancellable */
+                               (GAsyncReadyCallback) remove_account_cb,
+                               setup);
+    }
+}
+
+
+static void
+add_account_to_list (SetupData *setup, GoaObject *object)
+{
+  GtkWidget *list;
+  GtkWidget *box;
+  GtkWidget *image;
+  GtkWidget *label;
+  GtkWidget *button;
+  GoaAccount *account;
+  GIcon *icon;
+  gchar *markup;
+
+  account = goa_object_peek_account (object);
+
+  icon = g_icon_new_for_string (goa_account_get_provider_icon (account), NULL);
+  markup = g_strdup_printf ("<b>%s</b>\n"
+                            "<small><span foreground=\"#555555\">%s</span></small>",
+                            goa_account_get_provider_name (account),
+                            goa_account_get_presentation_identity (account));
+
+  list = WID ("online-accounts-list");
+
+  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+  gtk_widget_set_hexpand (box, TRUE);
+
+  g_object_set_data (G_OBJECT (box), "account-id",
+                     (gpointer)goa_account_get_id (account));
+
+  image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG);
+  label = gtk_label_new (markup);
+  gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+  button = gtk_button_new_with_label (_("Remove"));
+  gtk_widget_set_halign (button, GTK_ALIGN_END);
+  gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
+
+  g_object_set_data_full (G_OBJECT (button), "goa-object",
+                          g_object_ref (object), g_object_unref);
+
+  g_signal_connect (button, "clicked",
+                    G_CALLBACK (confirm_remove_account), setup);
+
+  gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 0);
+
+  gtk_widget_show_all (box);
+
+  gtk_container_add (GTK_CONTAINER (list), box);
+}
+
+static void
+remove_account_from_list (SetupData *setup, GoaObject *object)
+{
+  GtkWidget *list;
+  GList *children, *l;
+  GtkWidget *child;
+  GoaAccount *account;
+  const gchar *account_id, *id;
+
+  account = goa_object_peek_account (object);
+
+  account_id = goa_account_get_id (account);
+
+  list = WID ("online-accounts-list");
+
+  children = gtk_container_get_children (GTK_CONTAINER (list));
+  for (l = children; l; l = l->next)
+    {
+      child = GTK_WIDGET (l->data);
+
+      id = (const gchar *)g_object_get_data (G_OBJECT (child), "account-id");
+
+      if (g_strcmp0 (id, account_id) == 0)
+        {
+          gtk_widget_destroy (child);
+          break;
+        }
+    }
+  g_list_free (children);
+}
+
+static void
+populate_account_list (SetupData *setup)
+{
+  GList *accounts, *l;
+  GoaObject *object;
+
+  accounts = goa_client_get_accounts (setup->goa_client);
+  for (l = accounts; l; l = l->next)
+    {
+      object = GOA_OBJECT (l->data);
+      add_account_to_list (setup, object);
+    }
+
+  g_list_free_full (accounts, (GDestroyNotify) g_object_unref);
+}
+
+static void
+goa_account_added (GoaClient *client, GoaObject *object, gpointer data)
+{
+  SetupData *setup = data;
+
+  g_debug ("Online account added");
+
+  add_account_to_list (setup, object);
+}
+
+static void
+goa_account_removed (GoaClient *client, GoaObject *object, gpointer data)
+{
+  SetupData *setup = data;
+
+  g_debug ("Online account removed");
+
+  remove_account_from_list (setup, object);
+}
+
+static void
+prepare_online_page (SetupData *setup)
+{
+  GtkWidget *button;
+  GError *error = NULL;
+
+  setup->goa_client = goa_client_new_sync (NULL, &error);
+  if (setup->goa_client == NULL)
+    {
+       g_error ("Failed to get a GoaClient: %s", error->message);
+       g_error_free (error);
+       return;
+    }
+
+  populate_online_account_dialog (setup);
+  populate_account_list (setup);
+
+  button = WID("online-add-button");
+  g_signal_connect (button, "clicked",
+                    G_CALLBACK (show_online_account_dialog), setup);
+
+  g_signal_connect (setup->goa_client, "account-added",
+                    G_CALLBACK (goa_account_added), setup);
+  g_signal_connect (setup->goa_client, "account-removed",
+                    G_CALLBACK (goa_account_removed), setup);
+}
+
+/* Other setup {{{1 */
 
 static void
 copy_account_data (SetupData *setup)
@@ -1464,6 +1821,7 @@ prepare_assistant (SetupData *setup)
         prepare_network_page (setup);
         prepare_account_page (setup);
         prepare_location_page (setup);
+        prepare_online_page (setup);
 }
 
 int
@@ -1502,3 +1860,6 @@ main (int argc, char *argv[])
 
         return 0;
 }
+
+/* Epilogue {{{1 */
+/* vim: set foldmethod=marker: */
diff --git a/gui/initial-setup/setup.ui b/gui/initial-setup/setup.ui
index 96c1351..2fcb8f7 100644
--- a/gui/initial-setup/setup.ui
+++ b/gui/initial-setup/setup.ui
@@ -19,6 +19,17 @@
       <column type="gchararray"/>
     </columns>
   </object>
+  <object class="GtkDialog" id="online-accounts-dialog">
+    <property name="title"></property>
+    <property name="transient-for">gnome-setup-assistant</property>
+    <property name="modal">True</property>
+    <property name="resizable">False</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="online-accounts-dialog-content-area">
+        <property name="margin">12</property>
+      </object>
+    </child>
+  </object>
   <object class="GtkAssistant" id="gnome-setup-assistant">
     <!-- interface-naming-policy toplevel-contextual -->
     <property name="border-width">12</property>
@@ -572,6 +583,18 @@
           </packing>
         </child>
         <child>
+          <object class="GtkBox" id="online-accounts-list">
+            <property name="orientation">vertical</property>
+            <property name="visible">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
           <object class="GtkButton" id="online-add-button">
             <property name="visible">True</property>
             <property name="label">_Add Account</property>
@@ -582,7 +605,7 @@
           </object>
           <packing>
             <property name="left_attach">0</property>
-            <property name="top_attach">2</property>
+            <property name="top_attach">3</property>
             <property name="width">1</property>
             <property name="height">1</property>
           </packing>



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