[accounts-dialog/control-center-panel: 8/15] Turn the account type chooser into a standalone widget too



commit e57ffb93c846ffaa72dbd29ae4272df5635873ac
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jun 13 20:49:10 2010 -0400

    Turn the account type chooser into a standalone widget too

 data/user-accounts-dialog.ui |  164 +---------------
 src/Makefile.am              |    4 +
 src/um-editable-button.c     |   28 +++-
 src/um-editable-button.h     |    2 +
 src/um-editable-combo.c      |  404 ++++++++++++++++++++++++++++++++++++++
 src/um-editable-combo.h      |   72 +++++++
 src/um-user-panel.c          |  446 ++++++++----------------------------------
 7 files changed, 595 insertions(+), 525 deletions(-)
---
diff --git a/data/user-accounts-dialog.ui b/data/user-accounts-dialog.ui
index 4660cd4..891e085 100644
--- a/data/user-accounts-dialog.ui
+++ b/data/user-accounts-dialog.ui
@@ -214,43 +214,8 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkNotebook" id="account-location-notebook">
+                              <object class="UmEditableButton" id="account-location-button">
                                 <property name="visible">True</property>
-                                <property name="show_tabs">False</property>
-                                <property name="show_border">False</property>
-                                <child>
-                                  <object class="GtkLabel" id="account-location-value-label">
-                                    <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkButton" id="account-location-button">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="receives_default">True</property>
-                                    <property name="relief">none</property>
-                                    <child>
-                                      <object class="GtkLabel" id="account-location-button-label">
-                                        <property name="visible">True</property>
-                                        <property name="xalign">0</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkEntry" id="account-location-entry">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="invisible_char">&#x25CF;</property>
-                                  </object>
-                                  <packing>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
                               </object>
                               <packing>
                                 <property name="left_attach">1</property>
@@ -296,48 +261,10 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkNotebook" id="account-type-notebook">
+                              <object class="UmEditableCombo" id="account-type-combo">
                                 <property name="visible">True</property>
-                                <property name="show_tabs">False</property>
-                                <property name="show_border">False</property>
-                                <child>
-                                  <object class="GtkLabel" id="account-type-value-label">
-                                    <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkButton" id="account-type-button">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="receives_default">True</property>
-                                    <property name="relief">none</property>
-                                    <child>
-                                      <object class="GtkLabel" id="account-type-button-label">
-                                        <property name="visible">True</property>
-                                        <property name="xalign">0</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkComboBox" id="account-type-combo">
-                                    <property name="visible">True</property>
-                                    <property name="model">account-type-model</property>
-                                    <child>
-                                      <object class="GtkCellRendererText" id="account-type-cell"/>
-                                      <attributes>
-                                        <attribute name="text">0</attribute>
-                                      </attributes>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
+                                <property name="model">account-type-model</property>
+                                <property name="text-column">0</property>
                               </object>
                               <packing>
                                 <property name="left_attach">1</property>
@@ -374,50 +301,10 @@
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkNotebook" id="full-name-notebook">
+                                  <object class="UmEditableButton" id="full-name-button">
                                     <property name="visible">True</property>
-                                    <property name="show_tabs">False</property>
-                                    <property name="show_border">False</property>
-                                    <child>
-                                      <object class="GtkLabel" id="full-name-value-label">
-                                        <property name="visible">True</property>
-                                        <property name="xalign">0</property>
-                                        <attributes>
-                                          <attribute name="weight" value="bold"/>
-                                          <attribute name="scale" value="1.200000"/>
-                                        </attributes>
-                                      </object>
-                                    </child>
-                                    <child>
-                                      <object class="GtkButton" id="full-name-button">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                        <property name="receives_default">True</property>
-                                        <property name="relief">none</property>
-                                        <child>
-                                          <object class="GtkLabel" id="full-name-button-label">
-                                            <property name="visible">True</property>
-                                            <property name="xalign">0</property>
-                                            <attributes>
-                                              <attribute name="weight" value="bold"/>
-                                              <attribute name="scale" value="1.200000"/>
-                                            </attributes>
-                                          </object>
-                                        </child>
-                                      </object>
-                                      <packing>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkEntry" id="full-name-entry">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="position">2</property>
-                                      </packing>
-                                    </child>
+                                    <property name="scale">1.2</property>
+                                    <property name="weight">700</property>
                                   </object>
                                   <packing>
                                     <property name="position">1</property>
@@ -496,43 +383,8 @@
                               </packing>
                             </child>
                             <child>
-                              <object class="GtkNotebook" id="account-email-notebook">
+                              <object class="UmEditableButton" id="account-email-button">
                                 <property name="visible">True</property>
-                                <property name="show_tabs">False</property>
-                                <property name="show_border">False</property>
-                                <child>
-                                  <object class="GtkLabel" id="account-email-value-label">
-                                    <property name="visible">True</property>
-                                    <property name="xalign">0</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkButton" id="account-email-button">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="receives_default">True</property>
-                                    <property name="relief">none</property>
-                                    <child>
-                                      <object class="GtkLabel" id="account-email-button-label">
-                                        <property name="visible">True</property>
-                                        <property name="xalign">0</property>
-                                      </object>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkEntry" id="account-email-entry">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="invisible_char">&#x25CF;</property>
-                                  </object>
-                                  <packing>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
                               </object>
                               <packing>
                                 <property name="left_attach">1</property>
diff --git a/src/Makefile.am b/src/Makefile.am
index e9e91b9..a6c6398 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -63,6 +63,10 @@ libuser_properties_la_SOURCES = 	\
 	run-passwd.h			\
 	run-passwd.c			\
 	$(MARSHALFILES)			\
+	um-editable-button.h		\
+	um-editable-button.c		\
+	um-editable-combo.h		\
+	um-editable-combo.c		\
 	um-user-panel.h 		\
 	um-user-panel.c			\
 	um-user-module.c
diff --git a/src/um-editable-button.c b/src/um-editable-button.c
index 06a33e3..9e376c8 100644
--- a/src/um-editable-button.c
+++ b/src/um-editable-button.c
@@ -50,6 +50,13 @@ enum {
         PROP_WEIGHT_SET
 };
 
+enum {
+        EDITING_DONE,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
 G_DEFINE_TYPE (UmEditableButton, um_editable_button, GTK_TYPE_ALIGNMENT);
 
 void
@@ -119,6 +126,10 @@ update_entry_font (GtkWidget        *widget,
         if (!priv->weight_set && !priv->scale_set)
                 return;
 
+        g_signal_handlers_block_by_func (widget, update_entry_font, button);
+
+        gtk_widget_modify_font (widget, NULL);
+
         desc = pango_font_description_copy (widget->style->font_desc);
         if (priv->weight_set)
                 pango_font_description_set_weight (desc, priv->weight);
@@ -126,11 +137,11 @@ update_entry_font (GtkWidget        *widget,
                 size = pango_font_description_get_size (desc);
                 pango_font_description_set_size (desc, priv->scale * size);
         }
-        g_signal_handlers_block_by_func (widget, update_entry_font, button);
         gtk_widget_modify_font (widget, desc);
-        g_signal_handlers_unblock_by_func (widget, update_entry_font, button);
 
         pango_font_description_free (desc);
+
+        g_signal_handlers_unblock_by_func (widget, update_entry_font, button);
 }
 
 static void
@@ -303,6 +314,15 @@ um_editable_button_class_init (UmEditableButtonClass *class)
         object_class->get_property = um_editable_button_get_property;
         object_class->finalize = um_editable_button_finalize;
 
+        signals[EDITING_DONE] =
+                g_signal_new ("editing-done",
+                              G_TYPE_FROM_CLASS (class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (UmEditableButtonClass, editing_done),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
+
         g_object_class_install_property (object_class, PROP_TEXT,
                 g_param_spec_string ("text",
                                      "Text", "The text of the button",
@@ -354,6 +374,8 @@ stop_editing (UmEditableButton *button)
         um_editable_button_set_text (button,
                                      gtk_entry_get_text (button->priv->entry));
         gtk_notebook_set_current_page (button->priv->notebook, 1);
+
+        g_signal_emit (button, signals[EDITING_DONE], 0);
 }
 
 static void
@@ -447,5 +469,3 @@ um_editable_button_new (void)
 {
         return (GtkWidget *) g_object_new (UM_TYPE_EDITABLE_BUTTON, NULL);
 }
-
-
diff --git a/src/um-editable-button.h b/src/um-editable-button.h
index 7e8d4f9..a378ba1 100644
--- a/src/um-editable-button.h
+++ b/src/um-editable-button.h
@@ -48,6 +48,8 @@ struct _UmEditableButton
 struct _UmEditableButtonClass
 {
   GtkAlignmentClass parent_class;
+
+  void (* editing_done) (UmEditableButton *button);
 };
 
 GType        um_editable_button_get_type     (void) G_GNUC_CONST;
diff --git a/src/um-editable-combo.c b/src/um-editable-combo.c
new file mode 100644
index 0000000..bab2b13
--- /dev/null
+++ b/src/um-editable-combo.c
@@ -0,0 +1,404 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2009-2010  Red Hat, Inc,
+ *
+ * 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 3 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: Matthias Clasen <mclasen redhat com>
+ */
+
+#include <gdk/gdkkeysyms.h>
+#include "um-editable-combo.h"
+
+struct _UmEditableComboPrivate {
+        GtkNotebook *notebook;
+        GtkLabel    *label;
+        GtkButton   *button;
+        GtkComboBox *combo;
+        GtkWidget   *toplevel;
+
+        gint editable;
+        gint active;
+        gint text_column;
+};
+
+#define UM_EDITABLE_COMBO_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UM_TYPE_EDITABLE_COMBO, UmEditableComboPrivate))
+
+enum {
+        PROP_0,
+        PROP_EDITABLE,
+        PROP_ACTIVE,
+        PROP_MODEL,
+        PROP_TEXT_COLUMN
+};
+
+enum {
+        EDITING_DONE,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE (UmEditableCombo, um_editable_combo, GTK_TYPE_ALIGNMENT);
+
+void
+um_editable_combo_set_editable (UmEditableCombo *combo,
+                                gboolean         editable)
+{
+        UmEditableComboPrivate *priv;
+
+        priv = combo->priv;
+
+        if (priv->editable != editable) {
+                priv->editable = editable;
+
+                gtk_notebook_set_current_page (priv->notebook, editable ? 1 : 0);
+
+                g_object_notify (G_OBJECT (combo), "editable");
+        }
+}
+
+gboolean
+um_editable_combo_get_editable (UmEditableCombo *combo)
+{
+        return combo->priv->editable;
+}
+
+void
+um_editable_combo_set_model (UmEditableCombo *combo,
+                             GtkTreeModel    *model)
+{
+        UmEditableComboPrivate *priv = combo->priv;
+
+        gtk_combo_box_set_active (priv->combo, -1);
+        gtk_combo_box_set_model (priv->combo, model);
+
+        g_object_notify (G_OBJECT (combo), "model");
+}
+
+GtkTreeModel *
+um_editable_combo_get_model (UmEditableCombo *combo)
+{
+        return gtk_combo_box_get_model (combo->priv->combo);
+}
+
+void
+um_editable_combo_set_text_column (UmEditableCombo *combo,
+                                   gint             text_column)
+{
+        UmEditableComboPrivate *priv = combo->priv;
+        GList *cells;
+
+        if (priv->text_column == text_column)
+                return;
+
+        priv->text_column = text_column;
+
+        cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->combo));
+        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->combo),
+                                        cells->data,
+                                        "text", text_column,
+                                        NULL);
+        g_list_free (cells);
+
+        g_object_notify (G_OBJECT (combo), "text-column");
+}
+
+gint
+um_editable_combo_get_text_column (UmEditableCombo *combo)
+{
+        return combo->priv->text_column;
+}
+
+void
+um_editable_combo_set_active (UmEditableCombo *combo,
+                              gint             active)
+{
+        UmEditableComboPrivate *priv = combo->priv;
+        GtkWidget *label;
+        gchar *text;
+        GtkTreeModel *model;
+        GtkTreeIter iter;
+
+        if (priv->active == active)
+                return;
+
+        priv->active = active;
+        gtk_combo_box_set_active (priv->combo, active);
+
+        gtk_combo_box_get_active_iter (priv->combo, &iter);
+        model = gtk_combo_box_get_model (priv->combo);
+        gtk_tree_model_get (model, &iter, priv->text_column, &text, -1);
+
+        gtk_label_set_text (priv->label, text);
+        label = gtk_bin_get_child ((GtkBin*)priv->button);
+        gtk_label_set_text (GTK_LABEL (label), text);
+
+        g_object_notify (G_OBJECT (combo), "active");
+}
+
+gint
+um_editable_combo_get_active (UmEditableCombo *combo)
+{
+        return combo->priv->active;
+}
+
+static void
+um_editable_combo_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+        UmEditableCombo *combo = UM_EDITABLE_COMBO (object);
+
+        switch (prop_id) {
+        case PROP_EDITABLE:
+                um_editable_combo_set_editable (combo, g_value_get_boolean (value));
+                break;
+        case PROP_MODEL:
+                um_editable_combo_set_model (combo, g_value_get_object (value));
+                break;
+        case PROP_TEXT_COLUMN:
+                um_editable_combo_set_text_column (combo, g_value_get_int (value));
+                break;
+        case PROP_ACTIVE:
+                um_editable_combo_set_active (combo, g_value_get_int (value));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+um_editable_combo_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+        UmEditableCombo *combo = UM_EDITABLE_COMBO (object);
+
+        switch (prop_id) {
+        case PROP_EDITABLE:
+                g_value_set_boolean (value,
+                                     um_editable_combo_get_editable (combo));
+                break;
+        case PROP_MODEL:
+                g_value_set_object (value,
+                                    um_editable_combo_get_model (combo));
+                break;
+        case PROP_TEXT_COLUMN:
+                g_value_set_int (value,
+                                 um_editable_combo_get_text_column (combo));
+                break;
+        case PROP_ACTIVE:
+                g_value_set_int (value,
+                                 um_editable_combo_get_active (combo));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+um_editable_combo_class_init (UmEditableComboClass *class)
+{
+        GObjectClass *object_class;
+
+        object_class = G_OBJECT_CLASS (class);
+
+        object_class->set_property = um_editable_combo_set_property;
+        object_class->get_property = um_editable_combo_get_property;
+
+        signals[EDITING_DONE] =
+                g_signal_new ("editing-done",
+                              G_TYPE_FROM_CLASS (class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (UmEditableComboClass, editing_done),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
+
+        g_object_class_install_property (object_class, PROP_MODEL,
+                g_param_spec_object ("model",
+                                     "Model", "The options to present in the combobox",
+                                     GTK_TYPE_TREE_MODEL,
+                                     G_PARAM_READWRITE));
+
+        g_object_class_install_property (object_class, PROP_TEXT_COLUMN,
+                g_param_spec_int ("text-column",
+                                  "Text Column", "The model column that contains the displayable text",
+                                  -1, G_MAXINT, -1,
+                                  G_PARAM_READWRITE));
+
+
+        g_object_class_install_property (object_class, PROP_EDITABLE,
+                g_param_spec_boolean ("editable",
+                                      "Editable", "Whether the text can be edited",
+                                      FALSE,
+                                      G_PARAM_READWRITE));
+
+        g_object_class_install_property (object_class, PROP_ACTIVE,
+                g_param_spec_int ("active",
+                                  "Active choice", "The index of the selected choice",
+                                  -1, G_MAXINT, -1,
+                                  G_PARAM_READWRITE));
+
+        g_type_class_add_private (class, sizeof (UmEditableComboPrivate));
+}
+
+static void
+start_editing (UmEditableCombo *combo)
+{
+        gtk_notebook_set_current_page (combo->priv->notebook, 2);
+}
+
+static void
+stop_editing (UmEditableCombo *combo)
+{
+        um_editable_combo_set_active (combo,
+                                      gtk_combo_box_get_active (combo->priv->combo));
+        gtk_notebook_set_current_page (combo->priv->notebook, 1);
+
+        g_signal_emit (combo, signals[EDITING_DONE], 0);
+}
+
+static void
+cancel_editing (UmEditableCombo *combo)
+{
+        gtk_combo_box_set_active (combo->priv->combo,
+                                  um_editable_combo_get_active (combo));
+        gtk_notebook_set_current_page (combo->priv->notebook, 1);
+}
+
+static void
+button_clicked (GtkWidget       *widget,
+                UmEditableCombo *combo)
+{
+        if (combo->priv->editable)
+                start_editing (combo);
+}
+
+static void
+combo_changed (GtkWidget       *widget,
+               UmEditableCombo *combo)
+{
+        if (combo->priv->editable)
+                stop_editing (combo);
+}
+
+static gboolean
+combo_key_press (GtkWidget       *widget,
+                 GdkEventKey     *event,
+                 UmEditableCombo *combo)
+{
+        if (event->keyval == GDK_Escape) {
+                cancel_editing (combo);
+                return TRUE;
+        }
+        return FALSE;
+}
+
+static void
+focus_moved (GtkWindow       *window,
+             GtkWidget       *widget,
+             UmEditableCombo *combo)
+{
+        if (gtk_notebook_get_current_page (combo->priv->notebook) == 2 &&
+            (!widget || !gtk_widget_is_ancestor (widget, (GtkWidget *)combo)))
+                stop_editing (combo);
+}
+
+static void
+combo_hierarchy_changed (GtkWidget       *widget,
+                         GtkWidget       *previous_toplevel,
+                         UmEditableCombo *combo)
+{
+        UmEditableComboPrivate *priv;
+        GtkWidget *toplevel;
+
+        priv = combo->priv;
+
+        toplevel = gtk_widget_get_toplevel (widget);
+        if (priv->toplevel != toplevel) {
+                if (priv->toplevel)
+                        g_signal_handlers_disconnect_by_func (priv->toplevel,
+                                                              focus_moved, combo);
+
+                if (GTK_IS_WINDOW (toplevel))
+                        priv->toplevel = toplevel;
+                else
+                        priv->toplevel = NULL;
+
+                if (priv->toplevel)
+                        g_signal_connect (priv->toplevel, "set-focus",
+                                          G_CALLBACK (focus_moved), combo);
+        }
+}
+
+static void
+um_editable_combo_init (UmEditableCombo *combo)
+{
+        UmEditableComboPrivate *priv;
+        GtkCellRenderer *cell;
+
+        priv = combo->priv = UM_EDITABLE_COMBO_GET_PRIVATE (combo);
+
+        priv->active = -1;
+        priv->text_column = -1;
+
+        priv->notebook = (GtkNotebook*)gtk_notebook_new ();
+        gtk_notebook_set_show_tabs (priv->notebook, FALSE);
+        gtk_notebook_set_show_border (priv->notebook, FALSE);
+
+        priv->label = (GtkLabel*)gtk_label_new ("");
+        gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5);
+        gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->label, NULL);
+
+        priv->button = (GtkButton*)gtk_button_new_with_label ("");
+        gtk_widget_set_receives_default ((GtkWidget*)priv->button, TRUE);
+        gtk_button_set_relief (priv->button, GTK_RELIEF_NONE);
+        gtk_button_set_alignment (priv->button, 0.0, 0.5);
+        gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->button, NULL);
+        g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked), combo);
+
+        priv->combo = (GtkComboBox*)gtk_combo_box_new ();
+        cell = gtk_cell_renderer_text_new ();
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo), cell, TRUE);
+        gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->combo, NULL);
+
+        g_signal_connect (priv->combo, "changed", G_CALLBACK (combo_changed), combo);
+        g_signal_connect (priv->combo, "key-press-event", G_CALLBACK (combo_key_press), combo);
+
+        gtk_container_add (GTK_CONTAINER (combo), (GtkWidget*)priv->notebook);
+
+        gtk_widget_show ((GtkWidget*)priv->notebook);
+        gtk_widget_show ((GtkWidget*)priv->label);
+        gtk_widget_show ((GtkWidget*)priv->button);
+        gtk_widget_show ((GtkWidget*)priv->combo);
+
+        gtk_notebook_set_current_page (priv->notebook, 0);
+
+        /* ugly hack to catch the combo box losing focus */
+        g_signal_connect (combo, "hierarchy-changed",
+                          G_CALLBACK (combo_hierarchy_changed), combo);
+}
+
+GtkWidget *
+um_editable_combo_new (void)
+{
+        return (GtkWidget *) g_object_new (UM_TYPE_EDITABLE_COMBO, NULL);
+}
diff --git a/src/um-editable-combo.h b/src/um-editable-combo.h
new file mode 100644
index 0000000..7ddd1a8
--- /dev/null
+++ b/src/um-editable-combo.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2009-2010  Red Hat, Inc,
+ *
+ * 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 3 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: Matthias Clasen <mclasen redhat com>
+ */
+
+#ifndef _UM_EDITABLE_COMBO_H
+#define _UM_EDITABLE_COMBO_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define UM_TYPE_EDITABLE_COMBO  um_editable_combo_get_type()
+
+#define UM_EDITABLE_COMBO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UM_TYPE_EDITABLE_COMBO, UmEditableCombo))
+#define UM_EDITABLE_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_EDITABLE_COMBO, UmEditableComboClass))
+#define UM_IS_EDITABLE_COMBO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UM_TYPE_EDITABLE_COMBO))
+#define UM_IS_EDITABLE_COMBO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_EDITABLE_COMBO))
+#define UM_EDITABLE_COMBO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UM_TYPE_EDITABLE_COMBO, UmEditableComboClass))
+
+typedef struct _UmEditableCombo UmEditableCombo;
+typedef struct _UmEditableComboClass UmEditableComboClass;
+typedef struct _UmEditableComboPrivate UmEditableComboPrivate;
+
+struct _UmEditableCombo
+{
+  GtkAlignment parent;
+
+  UmEditableComboPrivate *priv;
+};
+
+struct _UmEditableComboClass
+{
+  GtkAlignmentClass parent_class;
+
+  void (* editing_done) (UmEditableCombo *combo);
+};
+
+GType         um_editable_combo_get_type        (void) G_GNUC_CONST;
+GtkWidget    *um_editable_combo_new             (void);
+void          um_editable_combo_set_editable    (UmEditableCombo *combo,
+                                                 gboolean         editable);
+gboolean      um_editable_combo_get_editable    (UmEditableCombo *combo);
+void          um_editable_combo_set_model       (UmEditableCombo *combo,
+                                                 GtkTreeModel    *model);
+GtkTreeModel *um_editable_combo_get_model       (UmEditableCombo *combo);
+void          um_editable_combo_set_text_column (UmEditableCombo *combo,
+                                                 gint             column);
+gint          um_editable_combo_get_text_column (UmEditableCombo *combo);
+void          um_editable_combo_set_active      (UmEditableCombo *combo,
+                                                 gint             active);
+gint          um_editable_combo_get_active      (UmEditableCombo *combo);
+
+G_END_DECLS
+
+#endif /* _UM_EDITABLE_COMBO_H_ */
diff --git a/src/um-user-panel.c b/src/um-user-panel.c
index 32bbbe1..243294f 100644
--- a/src/um-user-panel.c
+++ b/src/um-user-panel.c
@@ -47,6 +47,10 @@
 #include "um-user.h"
 #include "um-user-manager.h"
 
+#include "um-strength-bar.h"
+#include "um-editable-button.h"
+#include "um-editable-combo.h"
+
 #include "um-account-dialog.h"
 #include "um-language-dialog.h"
 #include "um-login-options.h"
@@ -54,7 +58,6 @@
 #include "um-photo-dialog.h"
 #include "um-fingerprint-dialog.h"
 #include "um-utils.h"
-#include "um-strength-bar.h"
 #include "gdm-languages.h"
 
 G_DEFINE_DYNAMIC_TYPE (UmUserPanel, um_user_panel, CC_TYPE_PANEL)
@@ -485,31 +488,12 @@ show_user (UmUser *user, UmUserPanelPrivate *d)
 
         um_photo_dialog_set_user (d->photo_dialog, user);
 
-        label = get_widget (d, "full-name-value-label");
-        gtk_label_set_text (GTK_LABEL (label), um_user_get_real_name (user));
+        label = get_widget (d, "full-name-button");
+        um_editable_button_set_text (UM_EDITABLE_BUTTON (label), um_user_get_real_name (user));
         gtk_widget_set_tooltip_text (label, um_user_get_user_name (user));
 
-        label = get_widget (d, "full-name-button-label");
-        gtk_label_set_text (GTK_LABEL (label), um_user_get_real_name (user));
-        widget = get_widget (d, "full-name-button");
-        gtk_widget_set_tooltip_text (label, um_user_get_user_name (user));
-        widget = get_widget (d, "full-name-entry");
-        gtk_entry_set_text (GTK_ENTRY (widget), um_user_get_real_name (user));
-
-        label = get_widget (d, "account-type-value-label");
-        gtk_label_set_text (GTK_LABEL (label), um_account_type_get_name (um_user_get_account_type (user)));
-        label = get_widget (d, "account-type-button-label");
-        gtk_label_set_text (GTK_LABEL (label), um_account_type_get_name (um_user_get_account_type (user)));
-        combo = get_widget (d, "account-type-combo");
-        model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
-        gtk_tree_model_get_iter_first (model, &iter);
-        do {
-                gint t;
-                gtk_tree_model_get (model, &iter, 1, &t, -1);
-                if (t == um_user_get_account_type (user)) {
-                        gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
-                }
-        }  while (gtk_tree_model_iter_next (model, &iter));
+        label = get_widget (d, "account-type-combo");
+        um_editable_combo_set_active (UM_EDITABLE_COMBO (label), um_user_get_account_type (user));
 
         if (um_user_get_locked (user)) {
                 text = C_("Password mode", "Account disabled");
@@ -535,12 +519,8 @@ show_user (UmUser *user, UmUserPanelPrivate *d)
         gtk_label_set_text (GTK_LABEL (label), text);
 
         text = um_user_get_email (user);
-        widget = get_widget (d, "account-email-value-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "account-email-button-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "account-email-entry");
-        gtk_entry_set_text (GTK_ENTRY (widget), text);
+        widget = get_widget (d, "account-email-button");
+        um_editable_button_set_text (UM_EDITABLE_BUTTON (widget), text);
 
         widget = get_widget (d, "account-language-combo");
         g_signal_handlers_block_by_func (widget, language_changed, d);
@@ -572,12 +552,8 @@ show_user (UmUser *user, UmUserPanelPrivate *d)
         g_signal_handlers_unblock_by_func (widget, language_changed, d);
 
         text = um_user_get_location (user);
-        label = get_widget (d, "account-location-value-label");
-        gtk_label_set_text (GTK_LABEL (label), nonempty (text));
-        label = get_widget (d, "account-location-button-label");
-        gtk_label_set_text (GTK_LABEL (label), nonempty (text));
-        label = get_widget (d, "account-location-entry");
-        gtk_entry_set_text (GTK_ENTRY (label), text);
+        label = get_widget (d, "account-location-button");
+        um_editable_button_set_text (UM_EDITABLE_BUTTON (label), text);
 
         widget = get_widget (d, "account-fingerprint-notebook");
         label = get_widget (d, "account-fingerprint-label");
@@ -598,7 +574,6 @@ static void lockbutton_changed (PolkitLockButton *button, gpointer data);
 static void
 selected_user_changed (GtkTreeSelection *selection, UmUserPanelPrivate *d)
 {
-        GtkWidget *widget;
         GtkTreeModel *model;
         GtkTreeIter iter;
         UmUser *user;
@@ -632,13 +607,7 @@ name_style_set (GtkWidget *widget, GtkStyle *previous_style, UmUserPanelPrivate
 }
 
 static void
-change_name_start (GtkButton *button, UmUserPanelPrivate *d)
-{
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 2);
-}
-
-static void
-change_name_done (GtkWidget         *entry,
+change_name_done (GtkWidget          *entry,
                   UmUserPanelPrivate *d)
 {
         const gchar *text;
@@ -646,130 +615,34 @@ change_name_done (GtkWidget         *entry,
 
         user = get_selected_user (d);
 
-        text = gtk_entry_get_text (GTK_ENTRY (entry));
+        text = um_editable_button_get_text (UM_EDITABLE_BUTTON (entry));
         if (g_strcmp0 (text, um_user_get_location (user)) != 0) {
                 um_user_set_real_name (user, text);
         }
-
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 1);
-}
-
-static void
-change_name_canceled (UmUserPanelPrivate *d)
-{
-        UmUser *user;
-        const gchar *text;
-        GtkWidget *widget;
-
-        user = get_selected_user (d);
-        text = um_user_get_real_name (user);
-
-        widget = get_widget (d, "full-name-value-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "full-name-button-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "full-name-entry");
-        gtk_entry_set_text (GTK_ENTRY (widget), text);
-
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 1);
-}
-
-static void
-change_name_activate (GtkWidget         *widget,
-                      UmUserPanelPrivate *d)
-{
-        change_name_done (widget, d);
-}
-
-static gboolean
-change_name_focus_out (GtkWidget         *widget,
-                       GdkEventFocus     *event,
-                       UmUserPanelPrivate *d)
-{
-        change_name_done (widget, d);
-
-        return FALSE;
-}
-
-static gboolean
-change_name_key_press (GtkWidget         *widget,
-                       GdkEventKey       *event,
-                       UmUserPanelPrivate *d)
-{
-        if (event->keyval == GDK_Escape) {
-                change_name_canceled (d);
-        }
-
-        return FALSE;
-}
-
-static void
-change_account_type_authorized_cb (GObject           *source,
-                                   GAsyncResult      *res,
-                                   UmUserPanelPrivate *d)
-{
-        GError *error;
-        PolkitAuthorizationResult *result;
-        gboolean is_authorized;
-
-        error = NULL;
-        is_authorized = FALSE;
-        result = polkit_authority_check_authorization_finish (d->authority,
-                                                              res,
-                                                              &error);
-        if (error) {
-                g_warning ("polkit check failed: %s", error->message);
-                g_error_free (error);
-        }
-        else {
-                if (polkit_authorization_result_get_is_authorized (result)) {
-                        is_authorized = TRUE;
-                }
-
-                g_object_unref (result);
-        }
-
-        if (is_authorized) {
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook")), 2);
-        }
 }
 
 static void
-change_account_type_start (GtkButton         *button,
-                           UmUserPanelPrivate *d)
-{
-        PolkitSubject *subject;
-
-        subject = polkit_unix_process_new (getpid ());
-
-        polkit_authority_check_authorization (d->authority,
-                                              subject,
-                                              "org.freedesktop.accounts.user-administration",
-                                              NULL,
-                                              POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
-                                              NULL,
-                                              (GAsyncReadyCallback)change_account_type_authorized_cb,
-                                              d);
-
-        g_object_unref (subject);
-}
-
-static void
-account_type_changed (GtkComboBox       *combo,
+account_type_changed (UmEditableCombo    *combo,
                       UmUserPanelPrivate *d)
 {
+        gint active;
+        gint account_type;
+        UmUser *user;
         GtkTreeModel *model;
+        GtkTreePath *path;
         GtkTreeIter iter;
-        gint t;
-        UmUser *user;
 
         user = get_selected_user (d);
-        model = gtk_combo_box_get_model (combo);
-        gtk_combo_box_get_active_iter (combo, &iter);
-        gtk_tree_model_get (model, &iter, 1, &t, -1);
+        active = um_editable_combo_get_active (combo);
 
-        if (t != um_user_get_account_type (user)) {
-                um_user_set_account_type (user, t);
+        model = um_editable_combo_get_model (combo);
+        gtk_tree_path_new_from_indices (active, -1);
+        gtk_tree_model_get_iter (model, &iter, path);
+        gtk_tree_path_free (path);
+        gtk_tree_model_get (model, &iter, 1, &account_type, -1);
+
+        if (account_type != um_user_get_account_type (user)) {
+                um_user_set_account_type (user, account_type);
         }
 }
 
@@ -915,14 +788,7 @@ change_password (GtkButton *button, UmUserPanelPrivate *d)
 }
 
 static void
-change_email_start (GtkButton         *button,
-                    UmUserPanelPrivate *d)
-{
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 2);
-}
-
-static void
-change_email_done (GtkWidget         *entry,
+change_email_done (UmEditableButton   *button,
                    UmUserPanelPrivate *d)
 {
         const gchar *text;
@@ -930,68 +796,10 @@ change_email_done (GtkWidget         *entry,
 
         user = get_selected_user (d);
 
-        text = gtk_entry_get_text (GTK_ENTRY (entry));
+        text = um_editable_button_get_text (button);
         if (g_strcmp0 (text, um_user_get_email (user)) != 0) {
                 um_user_set_email (user, text);
         }
-
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 1);
-}
-
-static void
-change_email_canceled (UmUserPanelPrivate *d)
-{
-        UmUser *user;
-        const gchar *text;
-        GtkWidget *widget;
-
-        user = get_selected_user (d);
-        text = um_user_get_email (user);
-
-        widget = get_widget (d, "account-email-value-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "account-email-button-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "account-email-entry");
-        gtk_entry_set_text (GTK_ENTRY (widget), text);
-
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 1);
-}
-
-static void
-change_email_activate (GtkWidget         *widget,
-                       UmUserPanelPrivate *d)
-{
-        change_email_done (widget, d);
-}
-
-static gboolean
-change_email_focus_out (GtkWidget         *widget,
-                        GdkEventFocus     *event,
-                        UmUserPanelPrivate *d)
-{
-        change_email_done (widget, d);
-
-        return FALSE;
-}
-
-static gboolean
-change_email_key_press (GtkWidget         *widget,
-                        GdkEventKey       *event,
-                        UmUserPanelPrivate *d)
-{
-        if (event->keyval == GDK_Escape) {
-                change_email_canceled (d);
-        }
-
-        return FALSE;
-}
-
-static void
-change_location_start (GtkButton         *button,
-                       UmUserPanelPrivate *d)
-{
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 2);
 }
 
 static void
@@ -1003,61 +811,10 @@ change_location_done (GtkWidget         *entry,
 
         user = get_selected_user (d);
 
-        text = gtk_entry_get_text (GTK_ENTRY (entry));
+        text = um_editable_button_get_text (UM_EDITABLE_BUTTON (entry));
         if (g_strcmp0 (text, um_user_get_location (user)) != 0) {
                 um_user_set_location (user, text);
         }
-
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 1);
-}
-
-static void
-change_location_canceled (UmUserPanelPrivate *d)
-{
-        UmUser *user;
-        const gchar *text;
-        GtkWidget *widget;
-
-        user = get_selected_user (d);
-        text = um_user_get_location (user);
-
-        widget = get_widget (d, "account-location-value-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "account-location-button-label");
-        gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
-        widget = get_widget (d, "account-location-entry");
-        gtk_entry_set_text (GTK_ENTRY (widget), text);
-
-        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 1);
-}
-
-static void
-change_location_activate (GtkWidget         *widget,
-                          UmUserPanelPrivate *d)
-{
-        change_location_done (widget, d);
-}
-
-static gboolean
-change_location_focus_out (GtkWidget         *widget,
-                           GdkEventFocus     *event,
-                           UmUserPanelPrivate *d)
-{
-        change_location_done (widget, d);
-
-        return FALSE;
-}
-
-static gboolean
-change_location_key_press (GtkWidget         *widget,
-                           GdkEventKey       *event,
-                           UmUserPanelPrivate *d)
-{
-        if (event->keyval == GDK_Escape) {
-                change_location_canceled (d);
-        }
-
-        return FALSE;
 }
 
 static void
@@ -1207,6 +964,25 @@ users_loaded (UmUserManager     *manager,
 }
 
 static void
+add_unlock_tooltip (GtkWidget *button)
+{
+        setup_tooltip_with_embedded_icon (button,
+                                          _("To make changes,\nclick the * icon first"),
+                                          "*",
+                                          "security-medium");
+        g_signal_connect (button, "button-release-event",
+                           G_CALLBACK (show_tooltip_now), NULL);
+}
+
+static void
+remove_unlock_tooltip (GtkWidget *button)
+{
+        setup_tooltip_with_embedded_icon (button, NULL, NULL, NULL);
+        g_signal_handlers_disconnect_by_func (button,
+                                              G_CALLBACK (show_tooltip_now), NULL);
+}
+
+static void
 lockbutton_changed (PolkitLockButton *button,
                     gpointer          data)
 {
@@ -1249,23 +1025,28 @@ lockbutton_changed (PolkitLockButton *button,
         }
 
         if (is_authorized) {
-                if (gtk_notebook_get_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook"))) == 0) {
-
-                        gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook")), 1);
-                }
+                um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), TRUE);
+                remove_unlock_tooltip (get_widget (d, "account-type-combo"));
         }
         else {
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook")), 0);
+                um_editable_combo_set_editable (UM_EDITABLE_COMBO (get_widget (d, "account-type-combo")), FALSE);
+                add_unlock_tooltip (get_widget (d, "account-type-combo"));
         }
 
         if (is_authorized || self_selected) {
                 gtk_widget_show (get_widget (d, "user-icon-button"));
                 gtk_widget_hide (get_widget (d, "user-icon-nonbutton"));
 
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 1);
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 1);
+                um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, "full-name-button")), TRUE);
+                remove_unlock_tooltip (get_widget (d, "full-name-button"));
+
+                um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, "account-email-button")), TRUE);
+                remove_unlock_tooltip (get_widget (d, "account-email-button"));
+
+                um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, "account-location-button")), TRUE);
+                remove_unlock_tooltip (get_widget (d, "account-location-button"));
+
                 gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-language-notebook")), 1);
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 1);
                 gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-password-notebook")), 1);
                 gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-fingerprint-notebook")), 1);
         }
@@ -1273,10 +1054,16 @@ lockbutton_changed (PolkitLockButton *button,
                 gtk_widget_hide (get_widget (d, "user-icon-button"));
                 gtk_widget_show (get_widget (d, "user-icon-nonbutton"));
 
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 0);
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 0);
+                um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, "full-name-button")), FALSE);
+                add_unlock_tooltip (get_widget (d, "full-name-button"));
+
+                um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, "account-email-button")), FALSE);
+                add_unlock_tooltip (get_widget (d, "account-email-button"));
+
+                um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, "account-location-button")), FALSE);
+                add_unlock_tooltip (get_widget (d, "account-location-button"));
+
                 gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-language-notebook")), 0);
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 0);
                 gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-password-notebook")), 0);
                 gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-fingerprint-notebook")), 0);
         }
@@ -1284,28 +1071,6 @@ lockbutton_changed (PolkitLockButton *button,
         um_password_dialog_set_privileged (d->password_dialog, is_authorized);
 }
 
-static void
-focus_moved (GtkWindow         *window,
-             GtkWidget         *widget,
-             UmUserPanelPrivate *d)
-{
-        GtkWidget *nb;
-
-        nb = get_widget (d, "account-type-notebook");
-
-        if (gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)) == 2 &&
-            (!widget || !gtk_widget_is_ancestor (widget, nb))) {
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), 1);
-        }
-
-        nb = get_widget (d, "account-language-notebook");
-
-        if (gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)) == 2 &&
-            (!widget || !gtk_widget_is_ancestor (widget, nb))) {
-                gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), 1);
-        }
-}
-
 static gboolean
 match_user (GtkTreeModel *model,
             gint          column,
@@ -1372,7 +1137,6 @@ match_user (GtkTreeModel *model,
 static void
 setup_main_window (UmUserPanelPrivate *d)
 {
-        GtkWidget *window;
         GtkWidget *userlist;
         GtkTreeModel *model;
         GtkListStore *store;
@@ -1384,9 +1148,6 @@ setup_main_window (UmUserPanelPrivate *d)
         gint expander_size;
         GtkWidget *box;
 
-        window = get_widget (d, "user-account-window");
-        g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
-
         userlist = get_widget (d, "list-treeview");
         store = gtk_list_store_new (NUM_USER_LIST_COLS,
                                     UM_TYPE_USER,
@@ -1458,34 +1219,12 @@ setup_main_window (UmUserPanelPrivate *d)
         g_signal_connect (button, "button-release-event",
                            G_CALLBACK (show_tooltip_now), NULL);
 
-        button = get_widget (d, "full-name-value-label");
-        setup_tooltip_with_embedded_icon (button,
-                                          _("To make changes,\nclick the * icon first"),
-                                          "*",
-                                          "security-medium");
-        g_signal_connect (button, "button-release-event",
-                           G_CALLBACK (show_tooltip_now), NULL);
-
         button = get_widget (d, "full-name-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (change_name_start), d);
-        button = get_widget (d, "full-name-entry");
-        g_signal_connect (button, "style-set", G_CALLBACK (name_style_set), d);
-        g_signal_connect (button, "activate", G_CALLBACK (change_name_activate), d);
-        g_signal_connect (button, "focus-out-event", G_CALLBACK (change_name_focus_out), d);
-        g_signal_connect (button, "key-press-event", G_CALLBACK (change_name_key_press), d);
-
-        button = get_widget (d, "account-type-value-label");
-        setup_tooltip_with_embedded_icon (button,
-                                          _("To change the account type,\nclick the * icon first"),
-                                          "*",
-                                          "security-medium");
-        g_signal_connect (button, "button-release-event",
-                           G_CALLBACK (show_tooltip_now), NULL);
+        g_signal_connect (button, "editing-done",
+                          G_CALLBACK (change_name_done), d);
 
-        button = get_widget (d, "account-type-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (change_account_type_start), d);
         button = get_widget (d, "account-type-combo");
-        g_signal_connect (button, "changed", G_CALLBACK (account_type_changed), d);
+        g_signal_connect (button, "editing-done", G_CALLBACK (account_type_changed), d);
 
         button = get_widget (d, "account-password-value-label");
         setup_tooltip_with_embedded_icon (button,
@@ -1498,20 +1237,9 @@ setup_main_window (UmUserPanelPrivate *d)
         button = get_widget (d, "account-password-button");
         g_signal_connect (button, "clicked", G_CALLBACK (change_password), d);
 
-        button = get_widget (d, "account-email-value-label");
-        setup_tooltip_with_embedded_icon (button,
-                                          _("To make changes,\nclick the * icon first"),
-                                          "*",
-                                          "security-medium");
-        g_signal_connect (button, "button-release-event",
-                           G_CALLBACK (show_tooltip_now), NULL);
-
         button = get_widget (d, "account-email-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (change_email_start), d);
-        button = get_widget (d, "account-email-entry");
-        g_signal_connect (button, "activate", G_CALLBACK (change_email_activate), d);
-        g_signal_connect (button, "focus-out-event", G_CALLBACK (change_email_focus_out), d);
-        g_signal_connect (button, "key-press-event", G_CALLBACK (change_email_key_press), d);
+        g_signal_connect (button, "editing-done",
+                          G_CALLBACK (change_email_done), d);
 
         button = get_widget (d, "account-language-value-label");
         setup_tooltip_with_embedded_icon (button,
@@ -1527,23 +1255,9 @@ setup_main_window (UmUserPanelPrivate *d)
         g_signal_connect (button, "changed", G_CALLBACK (language_changed), d);
         g_signal_connect (button, "key-press-event", G_CALLBACK (language_key_press), d);
 
-        /* ugly hack to catch the combo boxes losing focus */
-        g_signal_connect (window, "set-focus", G_CALLBACK (focus_moved), d);
-
-        button = get_widget (d, "account-location-value-label");
-        setup_tooltip_with_embedded_icon (button,
-                                          _("To make changes,\nclick the * icon first"),
-                                          "*",
-                                          "security-medium");
-        g_signal_connect (button, "button-release-event",
-                           G_CALLBACK (show_tooltip_now), NULL);
-
         button = get_widget (d, "account-location-button");
-        g_signal_connect (button, "clicked", G_CALLBACK (change_location_start), d);
-        button = get_widget (d, "account-location-entry");
-        g_signal_connect (button, "activate", G_CALLBACK (change_location_activate), d);
-        g_signal_connect (button, "focus-out-event", G_CALLBACK (change_location_focus_out), d);
-        g_signal_connect (button, "key-press-event", G_CALLBACK (change_location_key_press), d);
+        g_signal_connect (button, "editing-done",
+                          G_CALLBACK (change_location_done), d);
 
         button = get_widget (d, "account-fingerprint-button");
         g_signal_connect (button, "clicked",
@@ -1586,6 +1300,8 @@ um_user_panel_init (UmUserPanel *self)
 
         /* register types that the builder might need */
         type = um_strength_bar_get_type ();
+        type = um_editable_button_get_type ();
+        type = um_editable_combo_get_type ();
 
         d->builder = gtk_builder_new ();
         d->um = um_user_manager_ref_default ();



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