[gnome-initial-setup] account: Split out "local accounts" section into a separate file



commit b13d4a3869f8bb40b740df0a6a614c1c4bc879a6
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Oct 31 17:42:35 2013 -0400

    account: Split out "local accounts" section into a separate file
    
    This will pave the way for the rewrite of the accounts page flow.

 gnome-initial-setup/pages/account/Makefile.am      |   13 +-
 .../pages/account/account.gresource.xml            |    1 +
 .../pages/account/gis-account-page-local.c         |  383 ++++++++++++++++++++
 .../pages/account/gis-account-page-local.h         |   58 +++
 .../pages/account/gis-account-page-local.ui        |  273 ++++++++++++++
 .../pages/account/gis-account-page.c               |  334 ++---------------
 .../pages/account/gis-account-page.ui              |  286 +---------------
 7 files changed, 762 insertions(+), 586 deletions(-)
---
diff --git a/gnome-initial-setup/pages/account/Makefile.am b/gnome-initial-setup/pages/account/Makefile.am
index aaa9f40..9a6af50 100644
--- a/gnome-initial-setup/pages/account/Makefile.am
+++ b/gnome-initial-setup/pages/account/Makefile.am
@@ -22,12 +22,13 @@ account-resources.h: account.gresource.xml $(resource_files)
        $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --generate-header $<
 BUILT_SOURCES += account-resources.c account-resources.h
 
-libgisaccount_la_SOURCES =                             \
-       $(BUILT_SOURCES)                                \
-       gis-account-page.c gis-account-page.h           \
-       um-realm-manager.c um-realm-manager.h           \
-       um-utils.c um-utils.h                           \
-       pw-utils.c pw-utils.h                           \
+libgisaccount_la_SOURCES =                                     \
+       $(BUILT_SOURCES)                                        \
+       gis-account-page.c gis-account-page.h                   \
+       gis-account-page-local.c gis-account-page-local.h       \
+       um-realm-manager.c um-realm-manager.h                   \
+       um-utils.c um-utils.h                                   \
+       pw-utils.c pw-utils.h                                   \
        $(NULL)
 
 libgisaccount_la_CFLAGS = $(INITIAL_SETUP_CFLAGS) -I "$(srcdir)/../.."
diff --git a/gnome-initial-setup/pages/account/account.gresource.xml 
b/gnome-initial-setup/pages/account/account.gresource.xml
index 8941e24..7965408 100644
--- a/gnome-initial-setup/pages/account/account.gresource.xml
+++ b/gnome-initial-setup/pages/account/account.gresource.xml
@@ -2,5 +2,6 @@
 <gresources>
   <gresource prefix="/org/gnome/initial-setup">
     <file preprocess="xml-stripblanks" alias="gis-account-page.ui">gis-account-page.ui</file>
+    <file preprocess="xml-stripblanks" alias="gis-account-page-local.ui">gis-account-page-local.ui</file>
   </gresource>
 </gresources>
diff --git a/gnome-initial-setup/pages/account/gis-account-page-local.c 
b/gnome-initial-setup/pages/account/gis-account-page-local.c
new file mode 100644
index 0000000..f408c5f
--- /dev/null
+++ b/gnome-initial-setup/pages/account/gis-account-page-local.c
@@ -0,0 +1,383 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ *     Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#include "config.h"
+
+#include "gis-account-page-local.h"
+#include "gnome-initial-setup.h"
+
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+
+#include <string.h>
+#include <act/act-user-manager.h>
+#include "pw-utils.h"
+#include "um-utils.h"
+
+struct _GisAccountPageLocalPrivate
+{
+  GtkWidget *fullname_entry;
+  GtkWidget *username_combo;
+  GtkWidget *password_entry;
+  GtkWidget *confirm_entry;
+  GtkWidget *password_strength;
+  GtkWidget *password_strength_label;
+
+  ActUser *act_user;
+  ActUserManager *act_client;
+
+  gboolean valid_name;
+  gboolean valid_username;
+  gboolean valid_confirm;
+  const gchar *password_reason;
+  guint reason_timeout;
+  ActUserAccountType account_type;
+};
+typedef struct _GisAccountPageLocalPrivate GisAccountPageLocalPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GisAccountPageLocal, gis_account_page_local, GTK_TYPE_BIN);
+
+enum {
+  VALIDATION_CHANGED,
+  USER_CREATED,
+  LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+validation_changed (GisAccountPageLocal *page)
+{
+  g_signal_emit (page, signals[VALIDATION_CHANGED], 0);
+}
+
+static void
+clear_account_page (GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+
+  priv->valid_name = FALSE;
+  priv->valid_username = FALSE;
+  priv->valid_confirm = FALSE;
+
+  /* FIXME: change this for a large deployment scenario; maybe through a GSetting? */
+  priv->account_type = ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR;
+
+  gtk_entry_set_text (GTK_ENTRY (priv->fullname_entry), "");
+  gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (priv->username_combo))));
+  gtk_entry_set_text (GTK_ENTRY (priv->password_entry), "");
+  gtk_entry_set_text (GTK_ENTRY (priv->confirm_entry), "");
+}
+
+static void
+update_valid_confirm (GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  const gchar *password, *verify;
+
+  password = gtk_entry_get_text (GTK_ENTRY (priv->password_entry));
+  verify = gtk_entry_get_text (GTK_ENTRY (priv->confirm_entry));
+
+  priv->valid_confirm = strcmp (password, verify) == 0;
+}
+
+static void
+fullname_changed (GtkWidget      *w,
+                  GParamSpec     *pspec,
+                  GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  GtkWidget *entry;
+  GtkTreeModel *model;
+  const char *name;
+
+  name = gtk_entry_get_text (GTK_ENTRY (w));
+
+  entry = gtk_bin_get_child (GTK_BIN (priv->username_combo));
+  model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->username_combo));
+
+  gtk_list_store_clear (GTK_LIST_STORE (model));
+
+  priv->valid_name = is_valid_name (name);
+
+  if (!priv->valid_name) {
+    gtk_entry_set_text (GTK_ENTRY (entry), "");
+    return;
+  }
+
+  generate_username_choices (name, GTK_LIST_STORE (model));
+
+  gtk_combo_box_set_active (GTK_COMBO_BOX (priv->username_combo), 0);
+
+  validation_changed (page);
+}
+
+static void
+username_changed (GtkComboBoxText     *combo,
+                  GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  const gchar *username;
+  gchar *tip;
+  GtkWidget *entry;
+
+  username = gtk_combo_box_text_get_active_text (combo);
+
+  priv->valid_username = is_valid_username (username, &tip);
+
+  entry = gtk_bin_get_child (GTK_BIN (combo));
+
+  if (tip) {
+    set_entry_validation_error (GTK_ENTRY (entry), tip);
+    g_free (tip);
+  }
+  else {
+    clear_entry_validation_error (GTK_ENTRY (entry));
+    /* We hit this the first time when there has been no change to password but
+     * the two empty passwords are valid for no password.
+     */
+    update_valid_confirm (page);
+  }
+
+  validation_changed (page);
+}
+
+static gboolean
+reason_timeout_cb (gpointer data)
+{
+  GisAccountPageLocal *page = GIS_ACCOUNT_PAGE_LOCAL (data);
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  const gchar *password;
+  const gchar *verify;
+
+  password = gtk_entry_get_text (GTK_ENTRY (priv->password_entry));
+  verify = gtk_entry_get_text (GTK_ENTRY (priv->confirm_entry));
+
+  if (strlen (password) == 0)
+    set_entry_validation_error (GTK_ENTRY (priv->password_entry), _("No password"));
+  else
+    set_entry_validation_error (GTK_ENTRY (priv->password_entry), priv->password_reason);
+
+  if (strlen (verify) > 0 && !priv->valid_confirm)
+    set_entry_validation_error (GTK_ENTRY (priv->confirm_entry), _("Passwords do not match"));
+
+  priv->reason_timeout = 0;
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+refresh_reason_timeout (GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+
+  if (priv->reason_timeout != 0)
+    g_source_remove (priv->reason_timeout);
+
+  priv->reason_timeout = g_timeout_add (600, reason_timeout_cb, page);
+}
+
+static void
+update_password_entries (GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  const gchar *password;
+  const gchar *username;
+  gdouble strength;
+  gint strength_level;
+  const gchar *hint;
+  const gchar *long_hint = NULL;
+  gchar *strength_hint;
+
+  password = gtk_entry_get_text (GTK_ENTRY (priv->password_entry));
+  username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->username_combo));
+
+  strength = pw_strength (password, NULL, username, &hint, &long_hint, &strength_level);
+  gtk_level_bar_set_value (GTK_LEVEL_BAR (priv->password_strength), strength_level);
+
+  if (strlen (password) == 0)
+    strength_hint = g_strdup ("");
+  else
+    strength_hint = g_strdup_printf (_("Strength: %s"), hint);
+  gtk_label_set_label (GTK_LABEL (priv->password_strength_label), strength_hint);
+  g_free (strength_hint);
+
+  if (strength == 0.0) {
+    priv->password_reason = long_hint ? long_hint : hint;
+  }
+
+  update_valid_confirm (page);
+
+  if (priv->valid_confirm)
+    clear_entry_validation_error (GTK_ENTRY (priv->password_entry));
+
+  gtk_widget_set_sensitive (priv->confirm_entry, TRUE);
+
+  refresh_reason_timeout (page);
+}
+
+static void
+password_changed (GtkWidget      *w,
+                  GParamSpec     *pspec,
+                  GisAccountPageLocal *page)
+{
+  clear_entry_validation_error (GTK_ENTRY (w));
+  update_password_entries (page);
+  validation_changed (page);
+}
+
+static gboolean
+password_entry_focus_out (GtkWidget      *widget,
+                          GdkEventFocus  *event,
+                          GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+
+  if (priv->reason_timeout != 0)
+    g_source_remove (priv->reason_timeout);
+
+  return FALSE;
+}
+
+static gboolean
+confirm_entry_focus_out (GtkWidget      *widget,
+                         GdkEventFocus  *event,
+                         GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  GtkEntry *entry = GTK_ENTRY (widget);
+  const gchar *verify;
+
+  verify = gtk_entry_get_text (entry);
+
+  if (strlen (verify) > 0 && !priv->valid_confirm)
+    set_entry_validation_error (entry, _("Passwords do not match"));
+  else
+    clear_entry_validation_error (entry);
+
+  return FALSE;
+}
+
+static void
+gis_account_page_local_constructed (GObject *object)
+{
+  GisAccountPageLocal *page = GIS_ACCOUNT_PAGE_LOCAL (object);
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+
+  G_OBJECT_CLASS (gis_account_page_local_parent_class)->constructed (object);
+
+  priv->act_client = act_user_manager_get_default ();
+
+  g_signal_connect (priv->fullname_entry, "notify::text",
+                    G_CALLBACK (fullname_changed), page);
+  g_signal_connect (priv->username_combo, "changed",
+                    G_CALLBACK (username_changed), page);
+  g_signal_connect (priv->password_entry, "notify::text",
+                    G_CALLBACK (password_changed), page);
+  g_signal_connect (priv->confirm_entry, "notify::text",
+                    G_CALLBACK (password_changed), page);
+  g_signal_connect_after (priv->password_entry, "focus-out-event",
+                          G_CALLBACK (password_entry_focus_out), page);
+  g_signal_connect_after (priv->confirm_entry, "focus-out-event",
+                          G_CALLBACK (confirm_entry_focus_out), page);
+
+  clear_account_page (page);
+}
+
+static void
+local_create_user (GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  const gchar *username;
+  const gchar *password;
+  const gchar *fullname;
+  GError *error = NULL;
+
+  username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->username_combo));
+  fullname = gtk_entry_get_text (GTK_ENTRY (priv->fullname_entry));
+  password = gtk_entry_get_text (GTK_ENTRY (priv->password_entry));
+
+  priv->act_user = act_user_manager_create_user (priv->act_client, username, fullname, priv->account_type, 
&error);
+  if (error != NULL) {
+    g_warning ("Failed to create user: %s", error->message);
+    g_error_free (error);
+    return;
+  }
+
+  act_user_set_user_name (priv->act_user, username);
+  act_user_set_account_type (priv->act_user, priv->account_type);
+  if (strlen (password) == 0)
+    act_user_set_password_mode (priv->act_user, ACT_USER_PASSWORD_MODE_NONE);
+  else
+    act_user_set_password (priv->act_user, password, "");
+
+  g_signal_emit (page, signals[USER_CREATED], 0,
+                 priv->act_user, password);
+}
+
+static void
+gis_account_page_local_class_init (GisAccountPageLocalClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), 
"/org/gnome/initial-setup/gis-account-page-local.ui");
+
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
fullname_entry);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
username_combo);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
password_entry);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
confirm_entry);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
password_strength);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
password_strength_label);
+
+  object_class->constructed = gis_account_page_local_constructed;
+
+  signals[VALIDATION_CHANGED] = g_signal_new ("validation-changed", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
+                                              G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+                                              G_TYPE_NONE, 0);
+
+  signals[USER_CREATED] = g_signal_new ("user-created", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
+                                        G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+                                        G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING);
+}
+
+static void
+gis_account_page_local_init (GisAccountPageLocal *page)
+{
+  gtk_widget_init_template (GTK_WIDGET (page));
+}
+
+gboolean
+gis_account_page_local_validate (GisAccountPageLocal *page)
+{
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+
+  return priv->valid_name &&
+         priv->valid_username &&
+         priv->valid_confirm;
+}
+
+void
+gis_account_page_local_create_user (GisAccountPageLocal *page)
+{
+  local_create_user (page);
+}
diff --git a/gnome-initial-setup/pages/account/gis-account-page-local.h 
b/gnome-initial-setup/pages/account/gis-account-page-local.h
new file mode 100644
index 0000000..ed00485
--- /dev/null
+++ b/gnome-initial-setup/pages/account/gis-account-page-local.h
@@ -0,0 +1,58 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by:
+ *     Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#ifndef __GIS_ACCOUNT_PAGE_LOCAL_H__
+#define __GIS_ACCOUNT_PAGE_LOCAL_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GIS_TYPE_ACCOUNT_PAGE_LOCAL               (gis_account_page_local_get_type ())
+#define GIS_ACCOUNT_PAGE_LOCAL(obj)                           (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GIS_TYPE_ACCOUNT_PAGE_LOCAL, GisAccountPageLocal))
+#define GIS_ACCOUNT_PAGE_LOCAL_CLASS(klass)                   (G_TYPE_CHECK_CLASS_CAST ((klass),  
GIS_TYPE_ACCOUNT_PAGE_LOCAL, GisAccountPageLocalClass))
+#define GIS_IS_ACCOUNT_PAGE_LOCAL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GIS_TYPE_ACCOUNT_PAGE_LOCAL))
+#define GIS_IS_ACCOUNT_PAGE_LOCAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
GIS_TYPE_ACCOUNT_PAGE_LOCAL))
+#define GIS_ACCOUNT_PAGE_LOCAL_GET_CLASS(obj)                 (G_TYPE_INSTANCE_GET_CLASS ((obj),  
GIS_TYPE_ACCOUNT_PAGE_LOCAL, GisAccountPageLocalClass))
+
+typedef struct _GisAccountPageLocal        GisAccountPageLocal;
+typedef struct _GisAccountPageLocalClass   GisAccountPageLocalClass;
+
+struct _GisAccountPageLocal
+{
+    GtkBin parent;
+};
+
+struct _GisAccountPageLocalClass
+{
+    GtkBinClass parent_class;
+};
+
+GType gis_account_page_local_get_type (void);
+
+gboolean gis_account_page_local_validate (GisAccountPageLocal *local);
+void gis_account_page_local_create_user (GisAccountPageLocal *local);
+
+G_END_DECLS
+
+#endif /* __GIS_ACCOUNT_PAGE_LOCAL_H__ */
diff --git a/gnome-initial-setup/pages/account/gis-account-page-local.ui 
b/gnome-initial-setup/pages/account/gis-account-page-local.ui
new file mode 100644
index 0000000..2de07ff
--- /dev/null
+++ b/gnome-initial-setup/pages/account/gis-account-page-local.ui
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <template class="GisAccountPageLocal" parent="GtkBin">
+    <child>
+      <object class="GtkGrid" id="area">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="row_spacing">6</property>
+        <property name="column_spacing">12</property>
+        <child>
+          <object class="GtkLabel" id="title">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="valign">start</property>
+            <property name="margin_bottom">8</property>
+            <property name="hexpand">True</property>
+            <property name="label" translatable="yes">Create a Local Account</property>
+            <attributes>
+              <attribute name="weight" value="bold"/>
+              <attribute name="scale" value="1.2"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">2</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="fullname_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">end</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Full Name</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">fullname_entry</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="fullname_entry">
+            <property name="max_length">255</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="invisible_char">●</property>
+            <property name="invisible_char_set">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="username_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">end</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Username</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">username_combo</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="GtkComboBoxText" id="username_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="has_entry">True</property>
+            <property name="entry_text_column">0</property>
+            <property name="id_column">1</property>
+            <child internal-child="entry">
+              <object class="GtkEntry" id="comboboxtext-entry">
+                <property name="can_focus">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">2</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="username_explanation">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="margin_bottom">12</property>
+            <property name="label" translatable="yes">This will be used to name your home folder and can't 
be changed.</property>
+            <property name="wrap">True</property>
+            <attributes>
+              <attribute name="scale" value="0.8"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">3</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="password_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">end</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">password_entry</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">4</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="password_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="visibility">False</property>
+            <property name="invisible_char">●</property>
+            <property name="invisible_char_set">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">4</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="confirm_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">end</property>
+            <property name="xalign">1</property>
+            <property name="label" translatable="yes">_Confirm password</property>
+            <property name="use_underline">True</property>
+            <property name="mnemonic_widget">confirm_entry</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">5</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="confirm_entry">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="visibility">False</property>
+            <property name="sensitive">False</property>
+            <property name="invisible_char">●</property>
+            <property name="invisible_char_set">True</property>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">5</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="password_explanation">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="label" translatable="yes">Try to use at least 8 different characters. Mix upper 
and lower case and use a number or two.</property>
+            <property name="wrap">True</property>
+            <attributes>
+              <attribute name="scale" value="0.8"/>
+            </attributes>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">6</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="valign">start</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">2</property>
+            <child>
+              <object class="GtkLabel" id="password_strength_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label"></property>
+                <attributes>
+                  <attribute name="scale" value="0.8"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLevelBar" id="password_strength">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="halign">start</property>
+                <property name="valign">center</property>
+                <property name="max-value">4</property>
+                <property name="mode">discrete</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">2</property>
+            <property name="top_attach">4</property>
+            <property name="width">1</property>
+            <property name="height">2</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/gnome-initial-setup/pages/account/gis-account-page.c 
b/gnome-initial-setup/pages/account/gis-account-page.c
index c073a77..4ee6711 100644
--- a/gnome-initial-setup/pages/account/gis-account-page.c
+++ b/gnome-initial-setup/pages/account/gis-account-page.c
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "account-resources.h"
 #include "gis-account-page.h"
+#include "gis-account-page-local.h"
 
 #include <glib/gi18n.h>
 #include <gio/gio.h>
@@ -57,12 +58,7 @@ typedef enum {
 
 struct _GisAccountPagePrivate
 {
-  GtkWidget *local_fullname_entry;
-  GtkWidget *local_username_combo;
-  GtkWidget *local_password_entry;
-  GtkWidget *local_confirm_entry;
-  GtkWidget *local_password_strength;
-  GtkWidget *local_password_strength_label;
+  GtkWidget *page_local;
 
   GtkWidget *enterprise_login;
   GtkWidget *enterprise_password;
@@ -79,18 +75,11 @@ struct _GisAccountPagePrivate
   GtkWidget *page_toggle;
   GtkWidget *notebook;
 
-  ActUser *act_user;
   ActUserManager *act_client;
+  ActUser *act_user;
 
   UmAccountMode mode;
 
-  gboolean valid_name;
-  gboolean valid_username;
-  gboolean valid_confirm;
-  const gchar *password_reason;
-  guint reason_timeout;
-  ActUserAccountType account_type;
-
   gboolean has_enterprise;
   guint realmd_watch;
   UmRealmManager *realm_manager;
@@ -131,34 +120,6 @@ show_error_dialog (GisAccountPage *page,
   gtk_window_present (GTK_WINDOW (dialog));
 }
 
-static void
-clear_account_page (GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-
-  priv->valid_name = FALSE;
-  priv->valid_username = FALSE;
-  priv->valid_confirm = FALSE;
-
-  /* FIXME: change this for a large deployment scenario; maybe through a GSetting? */
-  priv->account_type = ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR;
-
-  gtk_entry_set_text (GTK_ENTRY (priv->local_fullname_entry), "");
-  gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX 
(priv->local_username_combo))));
-  gtk_entry_set_text (GTK_ENTRY (priv->local_password_entry), "");
-  gtk_entry_set_text (GTK_ENTRY (priv->local_confirm_entry), "");
-}
-
-static gboolean
-local_validate (GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-
-  return priv->valid_name &&
-         priv->valid_username &&
-         priv->valid_confirm;
-}
-
 static gboolean
 enterprise_validate (GisAccountPage *page)
 {
@@ -189,7 +150,7 @@ page_validate (GisAccountPage *page)
 
   switch (priv->mode) {
   case UM_LOCAL:
-    return local_validate (page);
+    return gis_account_page_local_validate (GIS_ACCOUNT_PAGE_LOCAL (priv->page_local));
   case UM_ENTERPRISE:
     return enterprise_validate (page);
   default:
@@ -198,12 +159,19 @@ page_validate (GisAccountPage *page)
 }
 
 static void
-update_account_page_status (GisAccountPage *page)
+update_page_validation (GisAccountPage *page)
 {
   gis_page_set_complete (GIS_PAGE (page), page_validate (page));
 }
 
 static void
+on_validation_changed (gpointer        page_area,
+                       GisAccountPage *page)
+{
+  update_page_validation (page);
+}
+
+static void
 set_mode (GisAccountPage *page,
           UmAccountMode   mode)
 {
@@ -216,7 +184,7 @@ set_mode (GisAccountPage *page,
 
   gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), (mode == UM_LOCAL) ? 0 : 1);
 
-  update_account_page_status (page);
+  update_page_validation (page);
 }
 
 static void
@@ -237,232 +205,6 @@ set_has_enterprise (GisAccountPage *page,
 }
 
 static void
-update_valid_confirm (GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-  const gchar *password, *verify;
-
-  password = gtk_entry_get_text (GTK_ENTRY (priv->local_password_entry));
-  verify = gtk_entry_get_text (GTK_ENTRY (priv->local_confirm_entry));
-
-  priv->valid_confirm = strcmp (password, verify) == 0;
-}
-
-static void
-fullname_changed (GtkWidget      *w,
-                  GParamSpec     *pspec,
-                  GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-  GtkWidget *entry;
-  GtkTreeModel *model;
-  const char *name;
-
-  name = gtk_entry_get_text (GTK_ENTRY (w));
-
-  entry = gtk_bin_get_child (GTK_BIN (priv->local_username_combo));
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->local_username_combo));
-
-  gtk_list_store_clear (GTK_LIST_STORE (model));
-
-  priv->valid_name = is_valid_name (name);
-
-  if (!priv->valid_name) {
-    gtk_entry_set_text (GTK_ENTRY (entry), "");
-    return;
-  }
-
-  generate_username_choices (name, GTK_LIST_STORE (model));
-
-  gtk_combo_box_set_active (GTK_COMBO_BOX (priv->local_username_combo), 0);
-
-  update_account_page_status (page);
-}
-
-static void
-username_changed (GtkComboBoxText *combo,
-                  GisAccountPage  *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-  const gchar *username;
-  gchar *tip;
-  GtkWidget *entry;
-
-  username = gtk_combo_box_text_get_active_text (combo);
-
-  priv->valid_username = is_valid_username (username, &tip);
-
-  entry = gtk_bin_get_child (GTK_BIN (combo));
-
-  if (tip) {
-    set_entry_validation_error (GTK_ENTRY (entry), tip);
-    g_free (tip);
-  }
-  else {
-    clear_entry_validation_error (GTK_ENTRY (entry));
-    /* We hit this the first time when there has been no change to password but
-     * the two empty passwords are valid for no password.
-     */
-    update_valid_confirm (page);
-  }
-
-  update_account_page_status (page);
-}
-
-static gboolean
-reason_timeout_cb (gpointer data)
-{
-  GisAccountPage *page = GIS_ACCOUNT_PAGE (data);
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-  const gchar *password;
-  const gchar *verify;
-
-  password = gtk_entry_get_text (GTK_ENTRY (priv->local_password_entry));
-  verify = gtk_entry_get_text (GTK_ENTRY (priv->local_confirm_entry));
-
-  if (strlen (password) == 0)
-    set_entry_validation_error (GTK_ENTRY (priv->local_password_entry), _("No password"));
-  else
-    set_entry_validation_error (GTK_ENTRY (priv->local_password_entry), priv->password_reason);
-
-  if (strlen (verify) > 0 && !priv->valid_confirm)
-    set_entry_validation_error (GTK_ENTRY (priv->local_confirm_entry), _("Passwords do not match"));
-
-  priv->reason_timeout = 0;
-
-  return G_SOURCE_REMOVE;
-}
-
-static void
-refresh_reason_timeout (GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-
-  if (priv->reason_timeout != 0)
-    g_source_remove (priv->reason_timeout);
-
-  priv->reason_timeout = g_timeout_add (600, reason_timeout_cb, page);
-}
-
-static void
-update_password_entries (GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-  const gchar *password;
-  const gchar *username;
-  gdouble strength;
-  gint strength_level;
-  const gchar *hint;
-  const gchar *long_hint = NULL;
-  gchar *strength_hint;
-
-  password = gtk_entry_get_text (GTK_ENTRY (priv->local_password_entry));
-  username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->local_username_combo));
-
-  strength = pw_strength (password, NULL, username, &hint, &long_hint, &strength_level);
-  gtk_level_bar_set_value (GTK_LEVEL_BAR (priv->local_password_strength), strength_level);
-
-  if (strlen (password) == 0)
-    strength_hint = g_strdup ("");
-  else
-    strength_hint = g_strdup_printf (_("Strength: %s"), hint);
-  gtk_label_set_label (GTK_LABEL (priv->local_password_strength_label), strength_hint);
-  g_free (strength_hint);
-
-  if (strength == 0.0) {
-    priv->password_reason = long_hint ? long_hint : hint;
-  }
-
-  update_valid_confirm (page);
-
-  if (priv->valid_confirm)
-    clear_entry_validation_error (GTK_ENTRY (priv->local_password_entry));
-
-  gtk_widget_set_sensitive (priv->local_confirm_entry, TRUE);
-
-  refresh_reason_timeout (page);
-}
-
-static void
-password_changed (GtkWidget      *w,
-                  GParamSpec     *pspec,
-                  GisAccountPage *page)
-{
-  clear_entry_validation_error (GTK_ENTRY (w));
-  update_password_entries (page);
-  update_account_page_status (page);
-}
-
-static gboolean
-password_entry_focus_out (GtkWidget      *widget,
-                          GdkEventFocus  *event,
-                          GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-
-  if (priv->reason_timeout != 0)
-    g_source_remove (priv->reason_timeout);
-
-  return FALSE;
-}
-
-static gboolean
-confirm_entry_focus_out (GtkWidget      *widget,
-                         GdkEventFocus  *event,
-                         GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-  GtkEntry *entry = GTK_ENTRY (widget);
-  const gchar *verify;
-
-  verify = gtk_entry_get_text (entry);
-
-  if (strlen (verify) > 0 && !priv->valid_confirm)
-    set_entry_validation_error (entry, _("Passwords do not match"));
-  else
-    clear_entry_validation_error (entry);
-
-  return FALSE;
-}
-
-static void
-local_create_user (GisAccountPage *page)
-{
-  GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
-  const gchar *username;
-  const gchar *password;
-  const gchar *fullname;
-  const gchar *language;
-  GError *error = NULL;
-
-  username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->local_username_combo));
-  fullname = gtk_entry_get_text (GTK_ENTRY (priv->local_fullname_entry));
-  password = gtk_entry_get_text (GTK_ENTRY (priv->local_password_entry));
-
-  priv->act_user = act_user_manager_create_user (priv->act_client, username, fullname, priv->account_type, 
&error);
-  if (error != NULL) {
-    g_warning ("Failed to create user: %s", error->message);
-    g_error_free (error);
-    return;
-  }
-
-  act_user_set_user_name (priv->act_user, username);
-  act_user_set_account_type (priv->act_user, priv->account_type);
-  if (strlen (password) == 0)
-    act_user_set_password_mode (priv->act_user, ACT_USER_PASSWORD_MODE_NONE);
-  else
-    act_user_set_password (priv->act_user, password, "");
-
-  language = gis_driver_get_user_language (GIS_PAGE (page)->driver);
-  if (language)
-    act_user_set_language (priv->act_user, language);
-
-  gis_driver_set_user_permissions (GIS_PAGE (page)->driver,
-                                   priv->act_user,
-                                   password);
-}
-
-static void
 on_permit_user_login (GObject *source,
                       GAsyncResult *result,
                       gpointer user_data)
@@ -1024,7 +766,7 @@ on_domain_changed (GtkComboBox *widget,
   GisAccountPagePrivate *priv = gis_account_page_get_instance_private (page);
 
   priv->domain_chosen = TRUE;
-  update_account_page_status (page);
+  update_page_validation (page);
   clear_entry_validation_error (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget))));
 }
 
@@ -1033,7 +775,7 @@ on_entry_changed (GtkEditable *editable,
                   gpointer user_data)
 {
   GisAccountPage *page = user_data;
-  update_account_page_status (page);
+  update_page_validation (page);
   clear_entry_validation_error (GTK_ENTRY (editable));
 }
 
@@ -1072,7 +814,7 @@ gis_account_page_save_data (GisPage *gis_page)
 
   switch (priv->mode) {
   case UM_LOCAL:
-    local_create_user (page);
+    gis_account_page_local_create_user (GIS_ACCOUNT_PAGE_LOCAL (priv->page_local));
     break;
   case UM_ENTERPRISE:
     break;
@@ -1082,6 +824,21 @@ gis_account_page_save_data (GisPage *gis_page)
 }
 
 static void
+on_local_user_created (GtkWidget      *page_local,
+                       ActUser        *user,
+                       char           *password,
+                       GisAccountPage *page)
+{
+  const gchar *language;
+
+  language = gis_driver_get_user_language (GIS_PAGE (page)->driver);
+  if (language)
+    act_user_set_language (user, language);
+
+  gis_driver_set_user_permissions (GIS_PAGE (page)->driver, user, password);
+}
+
+static void
 gis_account_page_constructed (GObject *object)
 {
   GisAccountPage *page = GIS_ACCOUNT_PAGE (object);
@@ -1094,19 +851,6 @@ gis_account_page_constructed (GObject *object)
                                          on_realmd_appeared, on_realmd_disappeared,
                                          page, NULL);
 
-  g_signal_connect (priv->local_fullname_entry, "notify::text",
-                    G_CALLBACK (fullname_changed), page);
-  g_signal_connect (priv->local_username_combo, "changed",
-                    G_CALLBACK (username_changed), page);
-  g_signal_connect (priv->local_password_entry, "notify::text",
-                    G_CALLBACK (password_changed), page);
-  g_signal_connect (priv->local_confirm_entry, "notify::text",
-                    G_CALLBACK (password_changed), page);
-  g_signal_connect_after (priv->local_password_entry, "focus-out-event",
-                          G_CALLBACK (password_entry_focus_out), page);
-  g_signal_connect_after (priv->local_confirm_entry, "focus-out-event",
-                          G_CALLBACK (confirm_entry_focus_out), page);
-
   g_signal_connect (priv->join_dialog, "response",
                     G_CALLBACK (on_join_response), page);
   g_signal_connect (priv->enterprise_domain, "changed",
@@ -1116,8 +860,12 @@ gis_account_page_constructed (GObject *object)
 
   priv->act_client = act_user_manager_get_default ();
 
-  clear_account_page (page);
-  update_account_page_status (page);
+  g_signal_connect (priv->page_local, "validation-changed",
+                    G_CALLBACK (on_validation_changed), page);
+  g_signal_connect (priv->page_local, "user-created",
+                    G_CALLBACK (on_local_user_created), page);
+
+  update_page_validation (page);
 
   priv->has_enterprise = FALSE;
 
@@ -1165,12 +913,7 @@ gis_account_page_class_init (GisAccountPageClass *klass)
 
   gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), 
"/org/gnome/initial-setup/gis-account-page.ui");
 
-  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, 
local_fullname_entry);
-  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, 
local_username_combo);
-  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, 
local_password_entry);
-  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, 
local_confirm_entry);
-  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, 
local_password_strength);
-  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, 
local_password_strength_label);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, page_local);
 
   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, enterprise_login);
   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPage, 
enterprise_password);
@@ -1199,6 +942,7 @@ static void
 gis_account_page_init (GisAccountPage *page)
 {
   g_resources_register (account_get_resource ());
+  g_type_ensure (GIS_TYPE_ACCOUNT_PAGE_LOCAL);
 
   gtk_widget_init_template (GTK_WIDGET (page));
 }
diff --git a/gnome-initial-setup/pages/account/gis-account-page.ui 
b/gnome-initial-setup/pages/account/gis-account-page.ui
index 889e07b..12dbdd5 100644
--- a/gnome-initial-setup/pages/account/gis-account-page.ui
+++ b/gnome-initial-setup/pages/account/gis-account-page.ui
@@ -19,282 +19,10 @@
             <property name="show_tabs">False</property>
             <property name="show_border">False</property>
             <child>
-              <object class="GtkGrid" id="local_area">
+              <object class="GisAccountPageLocal" id="page_local">
                 <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="row_spacing">6</property>
-                <property name="column_spacing">12</property>
-                <child>
-                  <object class="GtkLabel" id="local_title">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="halign">start</property>
-                    <property name="valign">start</property>
-                    <property name="margin_bottom">8</property>
-                    <property name="hexpand">True</property>
-                    <property name="label" translatable="yes">Create a Local Account</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                      <attribute name="scale" value="1.2"/>
-                    </attributes>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                    <property name="width">2</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="local_fullname_label">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="halign">end</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">_Full Name</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">local_fullname_entry</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="local_fullname_entry">
-                    <property name="max_length">255</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="invisible_char">●</property>
-                    <property name="invisible_char_set">True</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="local_username_label">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="halign">end</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">_Username</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">local_username_combo</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="GtkComboBoxText" id="local_username_combo">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="has_entry">True</property>
-                    <property name="entry_text_column">0</property>
-                    <property name="id_column">1</property>
-                    <child internal-child="entry">
-                      <object class="GtkEntry" id="comboboxtext-entry">
-                        <property name="can_focus">True</property>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">2</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="local_username_explanation">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="halign">start</property>
-                    <property name="margin_bottom">12</property>
-                    <property name="label" translatable="yes">This will be used to name your home folder and 
can't be changed.</property>
-                    <property name="wrap">True</property>
-                    <attributes>
-                      <attribute name="scale" value="0.8"/>
-                    </attributes>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">3</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="local_password_label">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="halign">end</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">_Password</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">local_password_entry</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">4</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="local_password_entry">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="visibility">False</property>
-                    <property name="invisible_char">●</property>
-                    <property name="invisible_char_set">True</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">4</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="local_confirm_label">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="halign">end</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">_Confirm password</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">local_confirm_entry</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">5</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="local_confirm_entry">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="visibility">False</property>
-                    <property name="sensitive">False</property>
-                    <property name="invisible_char">●</property>
-                    <property name="invisible_char_set">True</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">5</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="local_password_explanation">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="halign">start</property>
-                    <property name="label" translatable="yes">Try to use at least 8 different characters. 
Mix upper and lower case and use a number or two.</property>
-                    <property name="wrap">True</property>
-                    <attributes>
-                      <attribute name="scale" value="0.8"/>
-                    </attributes>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">6</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkBox" id="box1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="valign">start</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">2</property>
-                    <child>
-                      <object class="GtkLabel" id="local_password_strength_label">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label"></property>
-                        <attributes>
-                          <attribute name="scale" value="0.8"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLevelBar" id="local_password_strength">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="halign">start</property>
-                        <property name="valign">center</property>
-                        <property name="max-value">4</property>
-                        <property name="mode">discrete</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="left_attach">2</property>
-                    <property name="top_attach">4</property>
-                    <property name="width">1</property>
-                    <property name="height">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
               </object>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label1">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">page 1</property>
-              </object>
-              <packing>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
             <child>
               <object class="GtkGrid" id="enterprise_area">
                 <property name="visible">True</property>
@@ -784,16 +512,4 @@
       <column type="GObject"/>
     </columns>
   </object>
-
-  <object class="GtkSizeGroup" id="sizegroup1">
-    <widgets>
-      <widget name="local_fullname_label"/>
-      <widget name="local_username_label"/>
-      <widget name="local_password_label"/>
-      <widget name="local_confirm_label"/>
-      <widget name="label4"/>
-      <widget name="label8"/>
-      <widget name="label9"/>
-    </widgets>
-  </object>
 </interface>


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