summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2011-10-21 14:29:42 -0400
committerRay Strode <rstrode@redhat.com>2012-04-13 17:05:10 -0400
commitfd99027595c084f63801cd7b021882d71e38646d (patch)
tree2a5508da85a80c86ea21a2273992331938d85cdb
parente81a0ae45c4c78a28dbcfbfb84e029db6fde650b (diff)
downloadgdm-fd99027595c084f63801cd7b021882d71e38646d.tar.gz
initial-setup: Implement the online accounts page
-rw-r--r--configure.ac2
-rw-r--r--gui/initial-setup/gdm-initial-setup.c371
-rw-r--r--gui/initial-setup/setup.ui25
3 files changed, 392 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac
index becf123f..976b3936 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 a3d84c41..e19e58a6 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 96c13513..2fcb8f7d 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>