[gnome-initial-setup] goa: Adapt to new page design



commit ea07d53e9997cbb7dfb483f44acca2e61dfedfad
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Oct 22 10:45:15 2013 -0400

    goa: Adapt to new page design

 gnome-initial-setup/pages/goa/gis-goa-page.c  |  399 ++++++++++---------------
 gnome-initial-setup/pages/goa/gis-goa-page.ui |   19 +-
 2 files changed, 163 insertions(+), 255 deletions(-)
---
diff --git a/gnome-initial-setup/pages/goa/gis-goa-page.c b/gnome-initial-setup/pages/goa/gis-goa-page.c
index b3242d2..6b2f2d9 100644
--- a/gnome-initial-setup/pages/goa/gis-goa-page.c
+++ b/gnome-initial-setup/pages/goa/gis-goa-page.c
@@ -41,6 +41,7 @@
 
 struct _GisGoaPagePrivate {
   GoaClient *goa_client;
+  GHashTable *providers;
   gboolean accounts_exist;
 };
 typedef struct _GisGoaPagePrivate GisGoaPagePrivate;
@@ -50,281 +51,192 @@ G_DEFINE_TYPE_WITH_PRIVATE (GisGoaPage, gis_goa_page, GIS_TYPE_PAGE);
 #define OBJ(type,name) ((type)gtk_builder_get_object(GIS_PAGE(page)->builder,(name)))
 #define WID(name) OBJ(GtkWidget*,name)
 
-static void
-on_have_providers (GObject       *source,
-                   GAsyncResult  *res,
-                   gpointer       user_data)
-{
-  GisGoaPage *page = GIS_GOA_PAGE (user_data);
-  GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page);
-  GList *providers;
-  GList *l;
-  GtkWindow *parent;
-  GtkWidget *dialog;
-  GError *error = NULL;
-
-  if (!goa_provider_get_all_finish (&providers, res, &error))
-    goto out;
-
-  parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page)));
-
-  dialog = goa_panel_add_account_dialog_new (priv->goa_client);
-  gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
-
-  for (l = providers; l != NULL; l = l->next)
-    {
-      GoaProvider *provider;
-
-      provider = GOA_PROVIDER (l->data);
-      goa_panel_add_account_dialog_add_provider (GOA_PANEL_ADD_ACCOUNT_DIALOG (dialog), provider);
-    }
+struct _ProviderWidget {
+  GisGoaPage *page;
+  GoaProvider *provider;
+  GoaAccount *displayed_account;
 
-  goa_panel_add_account_dialog_run (GOA_PANEL_ADD_ACCOUNT_DIALOG (dialog));
-  goa_panel_add_account_dialog_get_account (GOA_PANEL_ADD_ACCOUNT_DIALOG (dialog), &error);
-  gtk_widget_destroy (dialog);
-
-  /* We might have an object even when error is set.
-   * eg., if we failed to store the credentials in the keyring.
-   */
-
-  if (error != NULL)
-    {
-      if (!(error->domain == GOA_ERROR && error->code == GOA_ERROR_DIALOG_DISMISSED))
-        {
-          dialog = gtk_message_dialog_new (parent,
-                                           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_all (dialog);
-          gtk_dialog_run (GTK_DIALOG (dialog));
-          gtk_widget_destroy (dialog);
-        }
-      g_error_free (error);
-    }
-
-  g_list_free_full (providers, g_object_unref);
-
- out:
-  if (error)
-    {
-      g_printerr ("Failed to list providers: %s\n", error->message);
-      g_error_free (error);
-    }
-}
+  GtkWidget *row;
+  GtkWidget *checkmark;
+  GtkWidget *account_label;
+};
+typedef struct _ProviderWidget ProviderWidget;
 
 static void
-show_online_account_dialog (GtkButton *button,
-                            gpointer   user_data)
+sync_provider_widget (ProviderWidget *provider_widget)
 {
-  GisGoaPage *page = GIS_GOA_PAGE (user_data);
-
-  goa_provider_get_all (on_have_providers, page);
+  gboolean has_account = (provider_widget->displayed_account != NULL);
+
+  gtk_widget_set_visible (provider_widget->checkmark, has_account);
+  gtk_widget_set_visible (provider_widget->account_label, has_account);
+  gtk_widget_set_sensitive (provider_widget->row, !has_account);
+
+  if (has_account) {
+    char *markup;
+    markup = g_strdup_printf ("<small><span foreground=\"#555555\">%s</span></small>",
+                              goa_account_get_presentation_identity (provider_widget->displayed_account));
+    gtk_label_set_markup (GTK_LABEL (provider_widget->account_label), markup);
+    g_free (markup);
+  }
 }
 
 static void
-remove_account_cb (GoaAccount   *account,
-                   GAsyncResult *res,
-                   gpointer      user_data)
+add_account_to_provider (ProviderWidget *provider_widget)
 {
-  GisGoaPage *page = GIS_GOA_PAGE (user_data);
-  GError *error;
-
-  error = NULL;
-  if (!goa_account_call_remove_finish (account, res, &error))
-    {
-      GtkWidget *dialog;
-      dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))),
-                                       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);
-    }
-}
+  GisGoaPage *page = provider_widget->page;
+  GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page);
+  GtkWindow *parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page)));
+  GError *error = NULL;
+  GtkWidget *dialog;
 
+  dialog = gtk_dialog_new_with_buttons (_("Add Account"),
+                                        parent,
+                                        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        _("Cancel"),
+                                        GTK_RESPONSE_CANCEL,
+                                        NULL);
+
+  goa_provider_add_account (provider_widget->provider,
+                            priv->goa_client,
+                            GTK_DIALOG (dialog),
+                            GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+                            &error);
+
+  /* this will fire the `account-added` signal, which will do
+   * the syncing of displayed_account on its own */
+
+  if (error) {
+    if (!g_error_matches (error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED))
+      g_warning ("fart %s\n", error->message);
+    goto out;
+  }
 
-static void
-confirm_remove_account (GtkButton *button, gpointer user_data)
-{
-  GisGoaPage *page = GIS_GOA_PAGE (user_data);
-  GtkWidget *dialog;
-  GoaObject *object;
-  gint response;
-
-  object = g_object_get_data (G_OBJECT (button), "goa-object");
-
-  dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))),
-                                   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));
+ out:
   gtk_widget_destroy (dialog);
-
-  if (response == GTK_RESPONSE_OK)
-    {
-      goa_account_call_remove (goa_object_peek_account (object),
-                               NULL, /* GCancellable */
-                               (GAsyncReadyCallback) remove_account_cb,
-                               page);
-    }
 }
 
 static void
-update_visibility (GisGoaPage *page)
+add_provider_to_list (GisGoaPage *page, const char *provider_type)
 {
   GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page);
-  GList *accounts;
-
-  accounts = goa_client_get_accounts (priv->goa_client);
-  priv->accounts_exist = (accounts != NULL);
-  gtk_widget_set_visible (WID ("online-accounts-frame"), accounts != NULL);
-  g_list_free_full (accounts, (GDestroyNotify) g_object_unref);
-}
-
-static void
-add_account_to_list (GisGoaPage *page, GoaObject *object)
-{
   GtkWidget *list;
+  GtkWidget *row;
   GtkWidget *box;
   GtkWidget *image;
   GtkWidget *label;
-  GtkWidget *button;
-  GoaAccount *account;
+  GtkWidget *checkmark;
+  GtkWidget *account_label;
   GIcon *icon;
   gchar *markup;
+  GoaProvider *provider;
+  ProviderWidget *provider_widget;
 
-  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");
-  gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
+  provider = goa_provider_get_for_provider_type (provider_type);
+  if (provider == NULL)
+    return;
 
+  row = gtk_list_box_row_new ();
   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));
-
+  icon = goa_provider_get_provider_icon (provider, NULL);
   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 ();
-  gtk_button_set_image (GTK_BUTTON (button),
-                        gtk_image_new_from_icon_name ("list-remove-symbolic", GTK_ICON_SIZE_MENU));
-  gtk_widget_set_margin_left (button, 10);
-  gtk_widget_set_margin_right (button, 10);
-  gtk_widget_set_halign (button, GTK_ALIGN_END);
-  gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
+  markup = g_strdup_printf ("<b>%s</b>", goa_provider_get_provider_name (provider, NULL));
+  label = gtk_label_new (NULL);
+  gtk_label_set_markup (GTK_LABEL (label), markup);
+  g_free (markup);
 
-  g_object_set_data_full (G_OBJECT (button), "goa-object",
-                          g_object_ref (object), g_object_unref);
+  checkmark = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
 
-  g_signal_connect (button, "clicked",
-                    G_CALLBACK (confirm_remove_account), page);
+  account_label = gtk_label_new (NULL);
 
   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_box_pack_end (GTK_BOX (box), checkmark, FALSE, FALSE, 8);
+  gtk_box_pack_end (GTK_BOX (box), account_label, FALSE, FALSE, 0);
 
-  gtk_widget_show_all (box);
+  gtk_container_add (GTK_CONTAINER (row), box);
 
-  gtk_container_add (GTK_CONTAINER (list), box);
+  gtk_widget_show (label);
+  gtk_widget_show (image);
+  gtk_widget_show (box);
+  gtk_widget_show (row);
 
-  update_visibility (page);
-}
-
-static void
-remove_account_from_list (GisGoaPage *page, GoaObject *object)
-{
-  GtkWidget *list;
-  GList *children, *l;
-  GtkWidget *child;
-  GoaAccount *account;
-  const gchar *account_id, *id;
+  provider_widget = g_new0 (ProviderWidget, 1);
+  provider_widget->page = page;
+  provider_widget->provider = provider;
+  provider_widget->row = row;
+  provider_widget->checkmark = checkmark;
+  provider_widget->account_label = account_label;
 
-  account = goa_object_peek_account (object);
+  g_object_set_data_full (G_OBJECT (row), "widget", provider_widget, g_free);
 
-  account_id = goa_account_get_id (account);
+  g_hash_table_insert (priv->providers, (char *) provider_type, provider_widget);
 
   list = WID ("online-accounts-list");
+  gtk_container_add (GTK_CONTAINER (list), row);
+}
 
-  children = gtk_container_get_children (GTK_CONTAINER (list));
-  for (l = children; l; l = l->next)
-    {
-      child = GTK_WIDGET (l->data);
+static void
+populate_provider_list (GisGoaPage *page)
+{
+  add_provider_to_list (page, "google");
+  add_provider_to_list (page, "owncloud");
+  add_provider_to_list (page, "windows_live");
+  add_provider_to_list (page, "facebook");
+}
 
-      id = (const gchar *)g_object_get_data (G_OBJECT (child), "account-id");
+static void
+sync_visibility (GisGoaPage *page)
+{
+  GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page);
+  GisAssistant *assistant = gis_driver_get_assistant (GIS_PAGE (page)->driver);
+  GNetworkMonitor *network_monitor = g_network_monitor_get_default ();
+  gboolean visible;
 
-      if (g_strcmp0 (id, account_id) == 0)
-        {
-          gtk_widget_destroy (child);
-          break;
-        }
-    }
-  g_list_free (children);
+  if (gis_assistant_get_current_page (assistant) == GIS_PAGE (page))
+    return;
 
-  update_visibility (page);
+  visible = (priv->accounts_exist || g_network_monitor_get_network_available (network_monitor));
+  gtk_widget_set_visible (GTK_WIDGET (page), visible);
 }
 
 static void
-populate_account_list (GisGoaPage *page)
+sync_accounts (GisGoaPage *page)
 {
   GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page);
   GList *accounts, *l;
-  GoaObject *object;
 
   accounts = goa_client_get_accounts (priv->goa_client);
+  priv->accounts_exist = (accounts != NULL);
 
-  for (l = accounts; l; l = l->next)
-    {
-      object = GOA_OBJECT (l->data);
-      add_account_to_list (page, object);
-    }
+  for (l = accounts; l != NULL; l = l->next) {
+    GoaObject *object = GOA_OBJECT (l->data);
+    GoaAccount *account = goa_object_get_account (object);
+    const char *account_type = goa_account_get_provider_type (account);
+    ProviderWidget *provider_widget;
 
-  g_list_free_full (accounts, (GDestroyNotify) g_object_unref);
+    provider_widget = g_hash_table_lookup (priv->providers, account_type);
+    if (!provider_widget)
+      continue;
+    if (provider_widget->displayed_account)
+      continue;
 
-  update_visibility (page);
-}
-
-static void
-goa_account_added (GoaClient *client, GoaObject *object, gpointer user_data)
-{
-  GisGoaPage *page = GIS_GOA_PAGE (user_data);
+    provider_widget->displayed_account = account;
+    sync_provider_widget (provider_widget);
+  }
 
-  g_debug ("Online account added");
+  g_list_free_full (accounts, (GDestroyNotify) g_object_unref);
 
-  add_account_to_list (page, object);
+  sync_visibility (page);
 }
 
 static void
-goa_account_removed (GoaClient *client, GoaObject *object, gpointer user_data)
+accounts_changed (GoaClient *client, GoaObject *object, gpointer user_data)
 {
   GisGoaPage *page = GIS_GOA_PAGE (user_data);
-
-  g_debug ("Online account removed");
-
-  remove_account_from_list (page, object);
+  sync_accounts (page);
 }
 
 static void
@@ -333,18 +245,7 @@ network_status_changed (GNetworkMonitor *monitor,
                         gpointer         user_data)
 {
   GisGoaPage *page = GIS_GOA_PAGE (user_data);
-  GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page);
-  GisAssistant *assistant = gis_driver_get_assistant (GIS_PAGE (page)->driver);
-
-  /* Ignore the network change if we're the current page or if an account
-   * has been configured.
-   */
-
-  if (gis_assistant_get_current_page (assistant) == GIS_PAGE (page))
-    return;
-
-  available = (available || priv->accounts_exist);
-  gtk_widget_set_visible (GTK_WIDGET (page), available);
+  sync_visibility (page);
 }
 
 static void
@@ -363,14 +264,28 @@ update_header_func (GtkListBoxRow *child,
 }
 
 static void
+row_activated (GtkListBox    *box,
+               GtkListBoxRow *row,
+               GisGoaPage    *page)
+{
+  ProviderWidget *provider_widget;
+
+  if (row == NULL)
+    return;
+
+  provider_widget = g_object_get_data (G_OBJECT (row), "widget");
+  g_assert (provider_widget != NULL);
+  g_assert (provider_widget->displayed_account == NULL);
+  add_account_to_provider (provider_widget);
+}
+
+static void
 gis_goa_page_constructed (GObject *object)
 {
   GisGoaPage *page = GIS_GOA_PAGE (object);
   GisGoaPagePrivate *priv = gis_goa_page_get_instance_private (page);
-  GtkWidget *button;
   GError *error = NULL;
   GNetworkMonitor *network_monitor = g_network_monitor_get_default ();
-  gboolean available;
   GtkWidget *list;
 
   G_OBJECT_CLASS (gis_goa_page_parent_class)->constructed (object);
@@ -379,36 +294,30 @@ gis_goa_page_constructed (GObject *object)
 
   priv->goa_client = goa_client_new_sync (NULL, &error);
 
-  if (priv->goa_client == NULL)
-    {
-       g_error ("Failed to get a GoaClient: %s", error->message);
-       g_error_free (error);
-       return;
-    }
-
-  populate_account_list (page);
+  if (priv->goa_client == NULL) {
+    g_error ("Failed to get a GoaClient: %s", error->message);
+    g_error_free (error);
+    return;
+  }
 
-  button = WID("online-add-button");
-  g_signal_connect (button, "clicked",
-                    G_CALLBACK (show_online_account_dialog), page);
+  priv->providers = g_hash_table_new (g_str_hash, g_str_equal);
 
   g_signal_connect (priv->goa_client, "account-added",
-                    G_CALLBACK (goa_account_added), page);
+                    G_CALLBACK (accounts_changed), page);
   g_signal_connect (priv->goa_client, "account-removed",
-                    G_CALLBACK (goa_account_removed), page);
-
+                    G_CALLBACK (accounts_changed), page);
   g_signal_connect (network_monitor, "network-changed",
                     G_CALLBACK (network_status_changed), page);
 
-  available = g_network_monitor_get_network_available (network_monitor);
-  network_status_changed (network_monitor,
-                          available,
-                          page);
-
   list = WID ("online-accounts-list");
   gtk_list_box_set_header_func (GTK_LIST_BOX (list),
                                 update_header_func,
                                 NULL, NULL);
+  g_signal_connect (list, "row-activated",
+                    G_CALLBACK (row_activated), page);
+
+  populate_provider_list (page);
+  sync_accounts (page);
 
   gis_page_set_complete (GIS_PAGE (page), TRUE);
 }
diff --git a/gnome-initial-setup/pages/goa/gis-goa-page.ui b/gnome-initial-setup/pages/goa/gis-goa-page.ui
index 473d4c0..6fc7e2d 100644
--- a/gnome-initial-setup/pages/goa/gis-goa-page.ui
+++ b/gnome-initial-setup/pages/goa/gis-goa-page.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.0 on Wed Oct 16 17:29:50 2013 -->
+<!-- Generated with glade 3.16.0 on Tue Oct 22 13:25:26 2013 -->
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkGrid" id="goa-page">
@@ -32,7 +32,7 @@
         <property name="label" translatable="yes">Connect Your Online Accounts</property>
         <attributes>
           <attribute name="weight" value="bold"/>
-          <attribute name="scale" value="1.6"/>
+          <attribute name="scale" value="1.6000000000000001"/>
         </attributes>
       </object>
       <packing>
@@ -64,6 +64,7 @@
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
         <property name="label_xalign">0</property>
         <property name="shadow_type">in</property>
         <child>
@@ -71,6 +72,7 @@
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="hexpand">True</property>
+            <property name="selection_mode">none</property>
           </object>
         </child>
       </object>
@@ -82,15 +84,12 @@
       </packing>
     </child>
     <child>
-      <object class="GtkButton" id="online-add-button">
-        <property name="label" translatable="yes">_Add Account</property>
+      <object class="GtkLabel" id="footer-label">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">False</property>
-        <property name="halign">start</property>
-        <property name="valign">start</property>
-        <property name="margin_top">24</property>
-        <property name="use_underline">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">You can review your online accounts (and add others) after 
setup.</property>
+        <property name="justify">center</property>
+        <property name="wrap">True</property>
       </object>
       <packing>
         <property name="left_attach">0</property>


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