[gnome-keyring] [gcr, ui] Rework how unlock options are loaded and handled.



commit 6a9d0470e2a8fa4cf8e989c967edf01393964f87
Author: Stef Walter <stef memberwebs com>
Date:   Sun Sep 5 20:57:37 2010 +0000

    [gcr, ui] Rework how unlock options are loaded and handled.
    
     * Rework GcrUnlockOptionsWidget API.
     * Prepare for migration to gsettings.

 daemon/gpg-agent/gkd-gpg-agent-ops.c |   31 +++--
 gcr/Makefile.am                      |    2 +
 gcr/gcr-unlock-options-widget.c      |  240 ++++++++++++++++++++++------------
 gcr/gcr-unlock-options-widget.h      |   29 +++-
 gcr/gcr-unlock-options-widget.ui     |   36 ++++--
 gcr/gcr-unlock-options.h             |   32 +++++
 gcr/tests/.gitignore                 |    1 +
 gcr/tests/Makefile.am                |   17 ++-
 gcr/tests/ui-test-unlock-options.c   |   83 ++++++++++++
 pkcs11/wrap-layer/gkm-wrap-prompt.c  |  116 ++++++++++-------
 ui/gku-prompt-tool.c                 |   99 ++++++--------
 ui/gku-prompt.c                      |   69 +++++++---
 ui/gku-prompt.h                      |   21 ++--
 ui/gku-prompt.ui                     |   49 ++-----
 ui/tests/test-data/prompt-empty      |    2 +
 ui/tests/test-data/prompt-full       |    4 +-
 ui/tests/test-data/prompt-test       |    1 +
 17 files changed, 544 insertions(+), 288 deletions(-)
---
diff --git a/daemon/gpg-agent/gkd-gpg-agent-ops.c b/daemon/gpg-agent/gkd-gpg-agent-ops.c
index 89ea21d..556e995 100644
--- a/daemon/gpg-agent/gkd-gpg-agent-ops.c
+++ b/daemon/gpg-agent/gkd-gpg-agent-ops.c
@@ -27,6 +27,8 @@
 #include "egg/egg-error.h"
 #include "egg/egg-secure-memory.h"
 
+#include "gcr/gcr-unlock-options.h"
+
 #include "pkcs11/pkcs11i.h"
 
 #include "ui/gku-prompt.h"
@@ -312,7 +314,6 @@ prepare_password_prompt (GP11Session *session, const gchar *errmsg, const gchar
 	gku_prompt_show_widget (prompt, "password_area");
 	gku_prompt_show_widget (prompt, "details_area");
 	gku_prompt_show_widget (prompt, "options_area");
-	gku_prompt_show_widget (prompt, "lock_area");
 
 	auto_unlock = FALSE;
 
@@ -333,14 +334,10 @@ prepare_password_prompt (GP11Session *session, const gchar *errmsg, const gchar
 		auto_unlock = TRUE;
 	}
 
-	if (auto_unlock)
-		gku_prompt_show_widget (prompt, "auto_area");
-	else
-		gku_prompt_hide_widget (prompt, "auto_area");
-
-	gku_prompt_set_unlock_label (prompt, "label-idle", _("Forget this password if idle for"));
-	gku_prompt_set_unlock_label (prompt, "label-timeout", _("Forget this password after"));
-	gku_prompt_set_unlock_label (prompt, "label-session", _("Forget this password when I log out"));
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS, auto_unlock, NULL);
+	gku_prompt_set_unlock_label (prompt, GCR_UNLOCK_OPTION_IDLE, _("Forget this password if idle for"));
+	gku_prompt_set_unlock_label (prompt, GCR_UNLOCK_OPTION_TIMEOUT, _("Forget this password after"));
+	gku_prompt_set_unlock_label (prompt, GCR_UNLOCK_OPTION_SESSION, _("Forget this password when I log out"));
 
 	gp11_list_unref_free (objects);
 
@@ -360,8 +357,9 @@ do_get_password (GP11Session *session, const gchar *keyid, const gchar *errmsg,
 {
 	GP11Attributes *attrs;
 	gchar *password = NULL;
-	gint value = 0;
 	GkuPrompt *prompt;
+	const gchar *choice;
+	guint ttl;
 
 	g_assert (GP11_IS_SESSION (session));
 	g_assert (keyid);
@@ -383,16 +381,19 @@ do_get_password (GP11Session *session, const gchar *keyid, const gchar *errmsg,
 		/* Load up the save options */
 		attrs = gp11_attributes_new ();
 
-		if (gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_AUTO, &value))
+		choice = gku_prompt_get_unlock_choice (prompt);
+		ttl = gku_prompt_get_unlock_ttl (prompt);
+
+		if (g_str_equal (choice, GCR_UNLOCK_OPTION_ALWAYS))
 			gp11_attributes_add_string (attrs, CKA_G_COLLECTION, "login");
 		else
 			gp11_attributes_add_string (attrs, CKA_G_COLLECTION, "session");
 
-		if (gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_IDLE, &value) && value > 0)
-			gp11_attributes_add_ulong (attrs, CKA_G_DESTRUCT_IDLE, value);
+		if (g_str_equal (choice, GCR_UNLOCK_OPTION_IDLE))
+			gp11_attributes_add_ulong (attrs, CKA_G_DESTRUCT_IDLE, ttl);
 
-		if (gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_TIMEOUT, &value) && value > 0)
-			gp11_attributes_add_ulong (attrs, CKA_G_DESTRUCT_AFTER, value);
+		else if (g_str_equal (choice, GCR_UNLOCK_OPTION_TIMEOUT))
+			gp11_attributes_add_ulong (attrs, CKA_G_DESTRUCT_AFTER, ttl);
 
 		/* Now actually save the password */
 		do_save_password (session, keyid, description, password, attrs);
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 6ec1c9b..5ce7d30 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -23,6 +23,7 @@ inc_HEADERS = \
 	gcr-parser.h \
 	gcr-simple-certificate.h \
 	gcr-types.h \
+	gcr-unlock-options.h \
 	gcr-unlock-options-widget.h
 
 # ------------------------------------------------------------------
@@ -53,6 +54,7 @@ libgcr GCR_VERSION_SUFFIX@_la_SOURCES = \
 	gcr-parser.c gcr-parser.h \
 	gcr-simple-certificate.c gcr-simple-certificate.h \
 	gcr-types.h \
+	gcr-unlock-options.h \
 	gcr-unlock-options-widget.c gcr-unlock-options-widget.h \
 	$(BUILT_SOURCES)
 
diff --git a/gcr/gcr-unlock-options-widget.c b/gcr/gcr-unlock-options-widget.c
index 61d0a77..6939c46 100644
--- a/gcr/gcr-unlock-options-widget.c
+++ b/gcr/gcr-unlock-options-widget.c
@@ -25,16 +25,13 @@
 
 enum {
 	PROP_0,
-	PROP_UNLOCK_TIMEOUT,
-	PROP_UNLOCK_IDLE
+	PROP_CHOICE,
+	PROP_TTL
 };
 
 struct _GcrUnlockOptionsWidgetPrivate {
 	GtkBuilder *builder;
-	GtkToggleButton *lock_logout;
-	GtkToggleButton *lock_after;
-	GtkToggleButton *lock_idle;
-	GtkSpinButton *spin_minutes;
+	gchar *choice;
 };
 
 G_DEFINE_TYPE (GcrUnlockOptionsWidget, gcr_unlock_options_widget, GTK_TYPE_ALIGNMENT);
@@ -59,32 +56,55 @@ builder_get_spin_button (GtkBuilder *builder, const gchar *name)
 	return GTK_SPIN_BUTTON (object);
 }
 
+static const gchar*
+widget_name_for_option (const gchar *option)
+{
+	g_return_val_if_fail (option, NULL);
+	if (g_str_equal (option, GCR_UNLOCK_OPTION_ALWAYS))
+		return "lock_always_choice";
+	else if (g_str_equal (option, GCR_UNLOCK_OPTION_SESSION))
+		return "lock_session_choice";
+	else if (g_str_equal (option, GCR_UNLOCK_OPTION_TIMEOUT))
+		return "lock_timeout_choice";
+	else if (g_str_equal (option, GCR_UNLOCK_OPTION_IDLE))
+		return "lock_idle_choice";
+	else
+		return NULL;
+}
+
+static GtkToggleButton*
+widget_button_for_option (GcrUnlockOptionsWidget *self, const gchar *option)
+{
+	const gchar *name = widget_name_for_option (option);
+	g_return_val_if_fail (name, NULL);
+	return builder_get_toggle_button (self->pv->builder, name);
+}
+
+static const gchar*
+widget_button_to_option (GcrUnlockOptionsWidget *self, GtkToggleButton *button)
+{
+	const gchar *option;
+	g_return_val_if_fail (button, NULL);
+	option = g_object_get_data (G_OBJECT (button), "unlock-choice");
+	g_return_val_if_fail (option, NULL);
+	return option;
+}
+
 static void
-on_timeout_choices_toggled (GtkToggleButton *unused, GtkBuilder *builder)
+on_choice_toggled (GtkToggleButton *button, GcrUnlockOptionsWidget *self)
 {
 	GtkWidget *spin;
 	GtkToggleButton *after, *idle;
 
-	spin = GTK_WIDGET (gtk_builder_get_object (builder, "lock_minutes_spin"));
-	after = builder_get_toggle_button (builder, "lock_after_choice");
-	idle = builder_get_toggle_button (builder, "lock_idle_choice");
+	spin = GTK_WIDGET (gtk_builder_get_object (self->pv->builder, "lock_minutes_spin"));
+	after = builder_get_toggle_button (self->pv->builder, "lock_timeout_choice");
+	idle = builder_get_toggle_button (self->pv->builder, "lock_idle_choice");
 	gtk_widget_set_sensitive (spin, gtk_toggle_button_get_active (after) ||
 	                                gtk_toggle_button_get_active (idle));
 
-}
-
-static const gchar*
-widget_name_for_option (guint option)
-{
-	switch (option) {
-	case GCR_UNLOCK_OPTION_SESSION:
-		return "lock_logout_choice";
-	case GCR_UNLOCK_OPTION_TIMEOUT:
-		return "lock_after_choice";
-	case GCR_UNLOCK_OPTION_IDLE:
-		return "lock_idle_choice";
-	default:
-		return NULL;
+	if (gtk_toggle_button_get_active (button)) {
+		g_free (self->pv->choice);
+		self->pv->choice = g_strdup (widget_button_to_option (self, button));
 	}
 }
 
@@ -112,13 +132,22 @@ gcr_unlock_options_widget_constructor (GType type, guint n_props, GObjectConstru
 		gtk_container_add (GTK_CONTAINER (self), widget);
 		gtk_widget_show (widget);
 
-		button = builder_get_toggle_button (self->pv->builder, "lock_logout_choice");
-		g_signal_connect (button, "toggled", G_CALLBACK (on_timeout_choices_toggled), self->pv->builder);
-		button = builder_get_toggle_button (self->pv->builder, "lock_after_choice");
-		g_signal_connect (button, "toggled", G_CALLBACK (on_timeout_choices_toggled), self->pv->builder);
+		button = builder_get_toggle_button (self->pv->builder, "lock_always_choice");
+		g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
+		g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_ALWAYS);
+
+		button = builder_get_toggle_button (self->pv->builder, "lock_session_choice");
+		g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
+		g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_SESSION);
+		on_choice_toggled (button, self);
+
+		button = builder_get_toggle_button (self->pv->builder, "lock_timeout_choice");
+		g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
+		g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_TIMEOUT);
+
 		button = builder_get_toggle_button (self->pv->builder, "lock_idle_choice");
-		g_signal_connect (button, "toggled", G_CALLBACK (on_timeout_choices_toggled), self->pv->builder);
-		on_timeout_choices_toggled (button, self->pv->builder);
+		g_signal_connect (button, "toggled", G_CALLBACK (on_choice_toggled), self);
+		g_object_set_data (G_OBJECT (button), "unlock-choice", GCR_UNLOCK_OPTION_IDLE);
 	}
 
 	return obj;
@@ -149,6 +178,8 @@ gcr_unlock_options_widget_finalize (GObject *obj)
 	GcrUnlockOptionsWidget *self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
 
 	g_assert (!self->pv->builder);
+	g_free (self->pv->choice);
+	self->pv->choice = NULL;
 
 	G_OBJECT_CLASS (gcr_unlock_options_widget_parent_class)->finalize (obj);
 }
@@ -158,34 +189,13 @@ gcr_unlock_options_widget_set_property (GObject *obj, guint prop_id, const GValu
                                         GParamSpec *pspec)
 {
 	GcrUnlockOptionsWidget *self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
-	GtkToggleButton *button;
-	GtkSpinButton *spin;
-	gint seconds;
-
-	spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
 
 	switch (prop_id) {
-	case PROP_UNLOCK_TIMEOUT:
-		button = builder_get_toggle_button (self->pv->builder, "lock_after_choice");
-		seconds = g_value_get_int (value);
-		if (seconds <= 0) {
-			gtk_toggle_button_set_active (button, FALSE);
-		} else {
-			gtk_toggle_button_set_active (button, TRUE);
-			spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
-			gtk_spin_button_set_value (spin, seconds / 60);
-		}
+	case PROP_CHOICE:
+		gcr_unlock_options_widget_set_choice (self, g_value_get_string (value));
 		break;
-	case PROP_UNLOCK_IDLE:
-		button = builder_get_toggle_button (self->pv->builder, "lock_idle_choice");
-		seconds = g_value_get_int (value);
-		if (seconds <= 0) {
-			gtk_toggle_button_set_active (button, FALSE);
-		} else {
-			gtk_toggle_button_set_active (button, TRUE);
-			spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
-			gtk_spin_button_set_value (spin, seconds / 60);
-		}
+	case PROP_TTL:
+		gcr_unlock_options_widget_set_ttl (self, g_value_get_uint (value));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -198,27 +208,13 @@ gcr_unlock_options_widget_get_property (GObject *obj, guint prop_id, GValue *val
                                         GParamSpec *pspec)
 {
 	GcrUnlockOptionsWidget *self = GCR_UNLOCK_OPTIONS_WIDGET (obj);
-	GtkToggleButton *button;
-	GtkSpinButton *spin;
-	gint minutes;
-
-	spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
-	minutes = gtk_spin_button_get_value_as_int (spin);
 
 	switch (prop_id) {
-	case PROP_UNLOCK_TIMEOUT:
-		button = builder_get_toggle_button (self->pv->builder, "lock_after_choice");
-		if (!gtk_toggle_button_get_active (button))
-			g_value_set_int (value, 0);
-		else
-			g_value_set_int (value, minutes * 60);
+	case PROP_CHOICE:
+		g_value_set_string (value, gcr_unlock_options_widget_get_choice (self));
 		break;
-	case PROP_UNLOCK_IDLE:
-		button = builder_get_toggle_button (self->pv->builder, "lock_idle_choice");
-		if (!gtk_toggle_button_get_active (button))
-			g_value_set_int (value, 0);
-		else
-			g_value_set_int (value, minutes * 60);
+	case PROP_TTL:
+		g_value_set_uint (value, gcr_unlock_options_widget_get_ttl (self));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -240,13 +236,13 @@ gcr_unlock_options_widget_class_init (GcrUnlockOptionsWidgetClass *klass)
 	gobject_class->set_property = gcr_unlock_options_widget_set_property;
 	gobject_class->get_property = gcr_unlock_options_widget_get_property;
 
-	g_object_class_install_property (gobject_class, PROP_UNLOCK_TIMEOUT,
-	               g_param_spec_int ("unlock-timeout", "Unlock Timeout", "Unlock Timeout",
-	                                 0, G_MAXINT, 0, G_PARAM_READWRITE));
+	g_object_class_install_property (gobject_class, PROP_CHOICE,
+	               g_param_spec_string ("choice", "Choice", "Unlock Option Choice",
+	                                    NULL, G_PARAM_READWRITE));
 
-	g_object_class_install_property (gobject_class, PROP_UNLOCK_IDLE,
-	               g_param_spec_int ("unlock-idle", "Unlock Idle", "Unlock Idle Timeout",
-	                                 0, G_MAXINT, 0, G_PARAM_READWRITE));
+	g_object_class_install_property (gobject_class, PROP_TTL,
+	               g_param_spec_uint ("ttl", "TTL", "Unlock Option Timeout in Seconds",
+	                                  0, G_MAXUINT, 0, G_PARAM_READWRITE));
 }
 
 /* -----------------------------------------------------------------------------
@@ -260,12 +256,61 @@ gcr_unlock_options_widget_new (void)
 }
 
 const gchar*
-gcr_unlock_options_widget_get_label (GcrUnlockOptionsWidget *self, guint option)
+gcr_unlock_options_widget_get_choice (GcrUnlockOptionsWidget *self)
+{
+	g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), NULL);
+	return self->pv->choice;
+}
+
+void
+gcr_unlock_options_widget_set_choice (GcrUnlockOptionsWidget *self, const gchar *option)
+{
+	GtkToggleButton *button;
+
+	g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
+	g_return_if_fail (option);
+
+	button = widget_button_for_option (self, option);
+	gtk_toggle_button_set_active (button, TRUE);
+}
+
+guint
+gcr_unlock_options_widget_get_ttl (GcrUnlockOptionsWidget *self)
+{
+	GtkSpinButton *spin;
+	gint amount;
+
+	g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), 0);
+
+	spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
+	amount = gtk_spin_button_get_value_as_int (spin);
+	return amount * 60;
+}
+
+void
+gcr_unlock_options_widget_set_ttl (GcrUnlockOptionsWidget *self, guint ttl)
+{
+	GtkSpinButton *spin;
+	guint amount;
+
+	g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
+
+	amount = ttl / 60;
+	if (!amount || ttl % 60)
+		amount += 1;
+
+	spin = builder_get_spin_button (self->pv->builder, "lock_minutes_spin");
+	gtk_spin_button_set_value (spin, amount);
+}
+
+const gchar*
+gcr_unlock_options_widget_get_label (GcrUnlockOptionsWidget *self, const gchar *option)
 {
 	GtkToggleButton *button;
 	const gchar *name;
 
 	g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), NULL);
+	g_return_val_if_fail (option, NULL);
 
 	name = widget_name_for_option (option);
 	g_return_val_if_fail (name, NULL);
@@ -277,13 +322,14 @@ gcr_unlock_options_widget_get_label (GcrUnlockOptionsWidget *self, guint option)
 }
 
 void
-gcr_unlock_options_widget_set_label (GcrUnlockOptionsWidget *self, guint option,
+gcr_unlock_options_widget_set_label (GcrUnlockOptionsWidget *self, const gchar *option,
                                      const gchar *text)
 {
 	GtkToggleButton *button;
 	const gchar *name;
 
 	g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
+	g_return_if_fail (option);
 	g_return_if_fail (text);
 
 	name = widget_name_for_option (option);
@@ -294,3 +340,35 @@ gcr_unlock_options_widget_set_label (GcrUnlockOptionsWidget *self, guint option,
 
 	gtk_button_set_label (GTK_BUTTON (button), text);
 }
+
+gboolean
+gcr_unlock_options_widget_get_sensitive (GcrUnlockOptionsWidget *self, const gchar *option)
+{
+	GtkToggleButton *button;
+	GtkStateType state;
+
+	g_return_val_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self), FALSE);
+	g_return_val_if_fail (option, FALSE);
+
+	button = widget_button_for_option (self, option);
+	state = gtk_widget_get_state (GTK_WIDGET (button));
+	return (state & GTK_STATE_INSENSITIVE) != GTK_STATE_INSENSITIVE;
+}
+
+void
+gcr_unlock_options_widget_set_sensitive (GcrUnlockOptionsWidget *self, const gchar *option,
+                                         gboolean sensitive, const gchar *reason)
+{
+	GtkToggleButton *button;
+
+	g_return_if_fail (GCR_IS_UNLOCK_OPTIONS_WIDGET (self));
+	g_return_if_fail (option);
+
+	button = widget_button_for_option (self, option);
+	gtk_widget_set_sensitive (GTK_WIDGET (button), sensitive);
+
+	if (!sensitive && reason)
+		gtk_widget_set_tooltip_text (GTK_WIDGET (button), reason);
+	else if (sensitive)
+		gtk_widget_set_has_tooltip (GTK_WIDGET (button), FALSE);
+}
diff --git a/gcr/gcr-unlock-options-widget.h b/gcr/gcr-unlock-options-widget.h
index e2e7831..aab34e6 100644
--- a/gcr/gcr-unlock-options-widget.h
+++ b/gcr/gcr-unlock-options-widget.h
@@ -24,6 +24,7 @@
 #include <gtk/gtk.h>
 
 #include "gcr-types.h"
+#include "gcr-unlock-options.h"
 
 G_BEGIN_DECLS
 
@@ -47,23 +48,35 @@ struct _GcrUnlockOptionsWidgetClass {
 	GtkAlignmentClass parent_class;
 };
 
-enum {
-	GCR_UNLOCK_OPTION_SESSION = 0x01,
-	GCR_UNLOCK_OPTION_TIMEOUT = 0x02,
-	GCR_UNLOCK_OPTION_IDLE = 0x04,
-};
-
 GType                         gcr_unlock_options_widget_get_type               (void);
 
 GtkWidget*                    gcr_unlock_options_widget_new                    (void);
 
+const gchar*                  gcr_unlock_options_widget_get_choice             (GcrUnlockOptionsWidget *self);
+
+void                          gcr_unlock_options_widget_set_choice             (GcrUnlockOptionsWidget *self,
+                                                                                const gchar *option);
+
+guint                         gcr_unlock_options_widget_get_ttl                (GcrUnlockOptionsWidget *self);
+
+void                          gcr_unlock_options_widget_set_ttl                (GcrUnlockOptionsWidget *self,
+                                                                                guint ttl);
+
 const gchar*                  gcr_unlock_options_widget_get_label              (GcrUnlockOptionsWidget *self,
-                                                                                guint option);
+                                                                                const gchar *option);
 
 void                          gcr_unlock_options_widget_set_label              (GcrUnlockOptionsWidget *self,
-                                                                                guint option,
+                                                                                const gchar *option,
                                                                                 const gchar *text);
 
+gboolean                      gcr_unlock_options_widget_get_sensitive          (GcrUnlockOptionsWidget *self,
+                                                                                const gchar *option);
+
+void                          gcr_unlock_options_widget_set_sensitive          (GcrUnlockOptionsWidget *self,
+                                                                                const gchar *option,
+                                                                                gboolean sensitive,
+                                                                                const gchar *reason);
+
 G_END_DECLS
 
 #endif /* __GCR_UNLOCK_OPTIONS_WIDGET_H__ */
diff --git a/gcr/gcr-unlock-options-widget.ui b/gcr/gcr-unlock-options-widget.ui
index a0d7150..f59a1d1 100644
--- a/gcr/gcr-unlock-options-widget.ui
+++ b/gcr/gcr-unlock-options-widget.ui
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
@@ -10,38 +10,52 @@
   </object>
   <object class="GtkVBox" id="unlock-options-widget">
     <property name="visible">True</property>
-    <property name="orientation">vertical</property>
     <property name="spacing">6</property>
     <child>
-      <object class="GtkRadioButton" id="lock_logout_choice">
-        <property name="label" translatable="yes">Lock this keyring when I log out</property>
+      <object class="GtkRadioButton" id="lock_always_choice">
+        <property name="label" translatable="yes">Automatically unlock this keyring whenever I'm logged in</property>
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="receives_default">False</property>
         <property name="active">True</property>
         <property name="draw_indicator">True</property>
+        <property name="group">lock_session_choice</property>
       </object>
       <packing>
+        <property name="expand">False</property>
         <property name="position">0</property>
       </packing>
     </child>
     <child>
+      <object class="GtkRadioButton" id="lock_session_choice">
+        <property name="label" translatable="yes">Lock this keyring when I log out</property>
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="active">True</property>
+        <property name="draw_indicator">True</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
       <object class="GtkHBox" id="hbox2">
         <property name="visible">True</property>
         <property name="spacing">6</property>
         <child>
           <object class="GtkVBox" id="vbox5">
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
-              <object class="GtkRadioButton" id="lock_after_choice">
+              <object class="GtkRadioButton" id="lock_timeout_choice">
                 <property name="label" translatable="yes">Lock this keyring after</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
                 <property name="draw_indicator">True</property>
-                <property name="group">lock_logout_choice</property>
+                <property name="group">lock_session_choice</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -55,7 +69,7 @@
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
                 <property name="draw_indicator">True</property>
-                <property name="group">lock_logout_choice</property>
+                <property name="group">lock_session_choice</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -72,7 +86,7 @@
           <object class="GtkSpinButton" id="lock_minutes_spin">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
-            <property name="invisible_char">&#x2022;</property>
+            <property name="invisible_char">â?¢</property>
             <property name="adjustment">spin_adjustment</property>
             <property name="climb_rate">1</property>
             <property name="numeric">True</property>
@@ -89,12 +103,14 @@
             <property name="label" translatable="yes">minutes</property>
           </object>
           <packing>
+            <property name="expand">False</property>
             <property name="position">2</property>
           </packing>
         </child>
       </object>
       <packing>
-        <property name="position">1</property>
+        <property name="expand">False</property>
+        <property name="position">2</property>
       </packing>
     </child>
   </object>
diff --git a/gcr/gcr-unlock-options.h b/gcr/gcr-unlock-options.h
new file mode 100644
index 0000000..e4ec670
--- /dev/null
+++ b/gcr/gcr-unlock-options.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#ifndef __GCR_UNLOCK_OPTIONS_H__
+#define __GCR_UNLOCK_OPTIONS_H__
+
+G_BEGIN_DECLS
+
+#define GCR_UNLOCK_OPTION_ALWAYS    "always"
+#define GCR_UNLOCK_OPTION_SESSION   "session"
+#define GCR_UNLOCK_OPTION_TIMEOUT   "timeout"
+#define GCR_UNLOCK_OPTION_IDLE      "idle"
+
+G_END_DECLS
+
+#endif /* __GCR_UNLOCK_OPTIONS_H__ */
diff --git a/gcr/tests/.gitignore b/gcr/tests/.gitignore
index b3085f5..2fa0037 100644
--- a/gcr/tests/.gitignore
+++ b/gcr/tests/.gitignore
@@ -1 +1,2 @@
 /ui-test-details
+/ui-test-unlock-options
diff --git a/gcr/tests/Makefile.am b/gcr/tests/Makefile.am
index 0e33394..22295ad 100644
--- a/gcr/tests/Makefile.am
+++ b/gcr/tests/Makefile.am
@@ -18,7 +18,8 @@ include $(top_srcdir)/testing/testing.make
 # ------------------------------------------------------------------
 
 noinst_PROGRAMS += \
-	ui-test-details
+	ui-test-details \
+	ui-test-unlock-options
 
 ui_test_details_SOURCES = \
 	ui-test-details.c
@@ -26,11 +27,23 @@ ui_test_details_SOURCES = \
 ui_test_details_CFLAGS = \
 	-DGCR_API_SUBJECT_TO_CHANGE \
 	$(GTK_CFLAGS)
-	
+
 ui_test_details_LDADD = \
 	$(top_builddir)/gcr/libgcr GCR_VERSION_SUFFIX@.la \
 	$(GTK_LIBS) \
 	$(LIBGCRYPT_LIBS)
 
+ui_test_unlock_options_SOURCES = \
+	ui-test-unlock-options.c
+
+ui_test_unlock_options_CFLAGS = \
+	-DGCR_API_SUBJECT_TO_CHANGE \
+	$(GTK_CFLAGS)
+
+ui_test_unlock_options_LDADD = \
+	$(top_builddir)/gcr/libgcr GCR_VERSION_SUFFIX@.la \
+	$(GTK_LIBS) \
+	$(LIBGCRYPT_LIBS)
+
 EXTRA_DIST = \
 	test-data
diff --git a/gcr/tests/ui-test-unlock-options.c b/gcr/tests/ui-test-unlock-options.c
new file mode 100644
index 0000000..9b05d59
--- /dev/null
+++ b/gcr/tests/ui-test-unlock-options.c
@@ -0,0 +1,83 @@
+
+#include "config.h"
+
+#include "gcr-unlock-options-widget.h"
+
+#include <gtk/gtk.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static void
+chdir_base_dir (char* argv0)
+{
+	gchar *dir, *base;
+
+	dir = g_path_get_dirname (argv0);
+	if (chdir (dir) < 0)
+		g_warning ("couldn't change directory to: %s: %s",
+		           dir, g_strerror (errno));
+
+	base = g_path_get_basename (dir);
+	if (strcmp (base, ".libs") == 0) {
+		if (chdir ("..") < 0)
+			g_warning ("couldn't change directory to ..: %s",
+			           g_strerror (errno));
+	}
+
+	g_free (base);
+	g_free (dir);
+}
+
+static void
+test_unlock_options (void)
+{
+	GcrUnlockOptionsWidget *unlock;
+	GtkDialog *dialog;
+
+	dialog = GTK_DIALOG (gtk_dialog_new ());
+	g_object_ref_sink (dialog);
+
+	unlock = GCR_UNLOCK_OPTIONS_WIDGET (gcr_unlock_options_widget_new ());
+	gtk_widget_show (GTK_WIDGET (unlock));
+	gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (unlock));
+
+	gcr_unlock_options_widget_set_sensitive (unlock, GCR_UNLOCK_OPTION_IDLE, FALSE,
+	                                         "This is a test of the tooltip.");
+	gcr_unlock_options_widget_set_sensitive (unlock, GCR_UNLOCK_OPTION_ALWAYS, TRUE, NULL);
+	gcr_unlock_options_widget_set_label (unlock, GCR_UNLOCK_OPTION_IDLE, "Disabled label test");
+	gcr_unlock_options_widget_set_ttl (unlock, 80);
+	gcr_unlock_options_widget_set_choice (unlock, GCR_UNLOCK_OPTION_ALWAYS);
+
+	gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 400);
+	gtk_dialog_run (dialog);
+
+	g_printerr ("choice: %s\n",
+	            gcr_unlock_options_widget_get_choice (unlock));
+
+	g_printerr ("ttl: %u\n",
+	            gcr_unlock_options_widget_get_ttl (unlock));
+
+	g_printerr ("idle sensitive: %s\n",
+	            gcr_unlock_options_widget_get_sensitive (unlock, GCR_UNLOCK_OPTION_IDLE) ? "T" : "F");
+
+	g_printerr ("always sensitive: %s\n",
+	            gcr_unlock_options_widget_get_sensitive (unlock, GCR_UNLOCK_OPTION_ALWAYS) ? "T" : "F");
+
+	g_printerr ("label: %s\n",
+	            gcr_unlock_options_widget_get_label (unlock, GCR_UNLOCK_OPTION_ALWAYS));
+
+	g_object_unref (dialog);
+}
+
+int
+main(int argc, char *argv[])
+{
+	gtk_init (&argc, &argv);
+
+	chdir_base_dir (argv[0]);
+	test_unlock_options ();
+
+	return 0;
+}
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.c b/pkcs11/wrap-layer/gkm-wrap-prompt.c
index 5c858c5..8c4a1c2 100644
--- a/pkcs11/wrap-layer/gkm-wrap-prompt.c
+++ b/pkcs11/wrap-layer/gkm-wrap-prompt.c
@@ -26,6 +26,8 @@
 
 #include "egg/egg-secure-memory.h"
 
+#include "gcr/gcr-unlock-options.h"
+
 #include "gkm/gkm-attributes.h"
 #include "gkm/gkm-util.h"
 
@@ -223,10 +225,13 @@ static gboolean
 auto_unlock_should_attach (GkmWrapPrompt *self)
 {
 	GkuPrompt *prompt = GKU_PROMPT (self);
-	gint value = 0;
-	return gku_prompt_has_response (prompt) &&
-	       gku_prompt_get_unlock_option (prompt, GKU_UNLOCK_AUTO, &value) &&
-	       value != 0;
+	const gchar *choice;
+
+	if (!gku_prompt_has_response (prompt))
+		return FALSE;
+
+	choice = gku_prompt_get_unlock_choice (prompt);
+	return (choice && g_str_equal (choice, GCR_UNLOCK_OPTION_ALWAYS));
 }
 
 static void
@@ -476,9 +481,10 @@ static CK_ATTRIBUTE_PTR
 get_unlock_options_from_prompt (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
 {
 	CK_ATTRIBUTE_PTR options;
+	const gchar *choice;
 	CK_BBOOL bval;
 	CK_ULONG uval;
-	gint value;
+	guint ttl;
 
 	g_assert (GKM_WRAP_IS_PROMPT (self));
 	g_assert (n_options);
@@ -486,6 +492,10 @@ get_unlock_options_from_prompt (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
 	if (!gku_prompt_has_response (GKU_PROMPT (self)))
 		return NULL;
 
+	ttl = gku_prompt_get_unlock_ttl (GKU_PROMPT (self));
+	choice = gku_prompt_get_unlock_choice (GKU_PROMPT (self));
+	g_return_val_if_fail (choice, NULL);
+
 	*n_options = 4;
 	options = pool_alloc (self, sizeof (CK_ATTRIBUTE) * (*n_options));
 
@@ -502,17 +512,13 @@ get_unlock_options_from_prompt (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
 	options[1].ulValueLen = sizeof (bval);
 
 	/* CKA_G_DESTRUCT_IDLE */
-	value = 0;
-	gku_prompt_get_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_IDLE, &value);
-	uval = value < 0 ? 0 : value;
+	uval = g_str_equal (choice, GCR_UNLOCK_OPTION_IDLE) ? ttl : 0;
 	options[2].type = CKA_G_DESTRUCT_IDLE;
 	options[2].pValue = pool_dup (self, &uval, sizeof (uval));
 	options[2].ulValueLen = sizeof (uval);
 
 	/* CKA_G_DESTRUCT_AFTER */
-	value = 0;
-	gku_prompt_get_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_TIMEOUT, &value);
-	uval = value < 0 ? 0 : value;
+	uval = g_str_equal (choice, GCR_UNLOCK_OPTION_TIMEOUT) ? ttl : 0;
 	options[3].type = CKA_G_DESTRUCT_AFTER;
 	options[3].pValue = pool_dup (self, &uval, sizeof (uval));
 	options[3].ulValueLen = sizeof (uval);
@@ -523,20 +529,34 @@ get_unlock_options_from_prompt (GkmWrapPrompt *self, CK_ULONG_PTR n_options)
 static void
 set_unlock_options_on_prompt (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR options, CK_ULONG n_options)
 {
+	const gchar *choice;
+	gboolean have_ttl = FALSE;
 	gboolean bval;
 	gulong uval;
+	guint ttl = 0;
 
 	g_assert (GKM_WRAP_IS_PROMPT (self));
 	g_assert (options || !n_options);
 
-	if (gkm_attributes_find_boolean (options, n_options, CKA_GNOME_TRANSIENT, &bval))
-		gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_AUTO, bval ? 0 : 1);
+	if (gkm_attributes_find_boolean (options, n_options, CKA_GNOME_TRANSIENT, &bval)) {
+		choice = bval ? GCR_UNLOCK_OPTION_SESSION : GCR_UNLOCK_OPTION_ALWAYS;
+	}
+
+	if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_IDLE, &uval) && uval) {
+		choice = GCR_UNLOCK_OPTION_IDLE;
+		have_ttl = TRUE;
+		ttl = uval;
+	}
 
-	if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_IDLE, &uval))
-		gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_IDLE, (int)uval);
+	if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_AFTER, &uval) && uval) {
+		choice = GCR_UNLOCK_OPTION_TIMEOUT;
+		have_ttl = TRUE;
+		ttl = uval;
+	}
 
-	if (gkm_attributes_find_ulong (options, n_options, CKA_G_DESTRUCT_AFTER, &uval))
-		gku_prompt_set_unlock_option (GKU_PROMPT (self), GKU_UNLOCK_TIMEOUT, (int)uval);
+	gku_prompt_set_unlock_choice (GKU_PROMPT (self), choice);
+	if (have_ttl)
+		gku_prompt_set_unlock_ttl (GKU_PROMPT (self), ttl);
 }
 
 static CK_ATTRIBUTE_PTR
@@ -643,13 +663,10 @@ prepare_unlock_keyring_other (GkmWrapPrompt *self, const gchar *label)
 	gku_prompt_hide_widget (prompt, "confirm_area");
 	gku_prompt_show_widget (prompt, "details_area");
 	gku_prompt_show_widget (prompt, "password_area");
-	gku_prompt_show_widget (prompt, "lock_area");
 	gku_prompt_show_widget (prompt, "options_area");
 
 	if (gkm_wrap_login_is_usable ())
-		gku_prompt_show_widget (prompt, "auto_unlock_check");
-	else
-		gku_prompt_hide_widget (prompt, "auto_unlock_check");
+		gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS, FALSE, NULL);
 }
 
 
@@ -723,13 +740,11 @@ prepare_unlock_object (GkmWrapPrompt *self, const gchar *label, CK_OBJECT_CLASS
 	gku_prompt_hide_widget (prompt, "confirm_area");
 	gku_prompt_show_widget (prompt, "details_area");
 	gku_prompt_show_widget (prompt, "password_area");
-	gku_prompt_show_widget (prompt, "lock_area");
 	gku_prompt_show_widget (prompt, "options_area");
 
-	if (gkm_wrap_login_is_usable ())
-		gku_prompt_show_widget (prompt, "auto_unlock_check");
-	else
-		gku_prompt_hide_widget (prompt, "auto_unlock_check");
+	/* TODO: After string freeze need to add a reason */
+	if (!gkm_wrap_login_is_usable ())
+		gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS, FALSE, NULL);
 }
 
 static void
@@ -805,11 +820,12 @@ prepare_unlock_token (GkmWrapPrompt *self, CK_TOKEN_INFO_PTR tinfo)
 	gku_prompt_set_secondary_text (prompt, text);
 	g_free (text);
 
-	if (gkm_wrap_login_is_usable ()) {
-		gku_prompt_show_widget (prompt, "details_area");
-		gku_prompt_show_widget (prompt, "lock_area");
-		gku_prompt_hide_widget (prompt, "options_area");
-	}
+	gku_prompt_show_widget (prompt, "details_area");
+	gku_prompt_show_widget (prompt, "options_area");
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_IDLE, FALSE, NULL);
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_TIMEOUT, FALSE, NULL);
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS,
+	                                 gkm_wrap_login_is_usable (), NULL);
 
 	g_free (label);
 }
@@ -874,8 +890,7 @@ gkm_wrap_prompt_for_credential (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE s
 {
 	CredentialPrompt *data;
 	CK_ATTRIBUTE_PTR attr;
-	CK_ATTRIBUTE_PTR options;
-	CK_ULONG n_options, i;
+	CK_ULONG i;
 	CK_OBJECT_CLASS klass;
 	CK_OBJECT_HANDLE object;
 	GkmWrapPrompt *self;
@@ -913,11 +928,6 @@ gkm_wrap_prompt_for_credential (CK_FUNCTION_LIST_PTR module, CK_SESSION_HANDLE s
 
 	data->n_template = n_template;
 
-	/* Now load up the unlock options into the prompt*/
-	options = get_unlock_options_from_object (self, &n_options);
-	if (options != NULL)
-		set_unlock_options_on_prompt (self, options, n_options);
-
 	return self;
 }
 
@@ -954,6 +964,14 @@ gkm_wrap_prompt_do_credential (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR *template,
 
 	if (!data->password) {
 		prepare_unlock_prompt (self, attrs, n_attrs, self->iteration == 1);
+
+		/* Now load up the unlock options into the prompt*/
+		if (self->iteration == 1) {
+			options = get_unlock_options_from_object (self, &n_options);
+			if (options != NULL)
+				set_unlock_options_on_prompt (self, options, n_options);
+		}
+
 		++(self->iteration);
 
 		gku_prompt_request_attention_sync (NULL, on_prompt_attention,
@@ -1043,11 +1061,12 @@ prepare_init_token (GkmWrapPrompt *self, CK_TOKEN_INFO_PTR tinfo)
 	gku_prompt_set_secondary_text (prompt, text);
 	g_free (text);
 
-	if (gkm_wrap_login_is_usable ()) {
-		gku_prompt_show_widget (prompt, "details_area");
-		gku_prompt_show_widget (prompt, "lock_area");
-		gku_prompt_hide_widget (prompt, "options_area");
-	}
+	gku_prompt_show_widget (prompt, "details_area");
+	gku_prompt_show_widget (prompt, "options_area");
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_IDLE, FALSE, NULL);
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_TIMEOUT, FALSE, NULL);
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS,
+	                                 gkm_wrap_login_is_usable (), NULL);
 
 	g_free (label);
 }
@@ -1168,11 +1187,12 @@ prepare_set_token (GkmWrapPrompt *self, CK_TOKEN_INFO_PTR tinfo)
 	gku_prompt_set_secondary_text (prompt, text);
 	g_free (text);
 
-	if (gkm_wrap_login_is_usable ()) {
-		gku_prompt_show_widget (prompt, "details_area");
-		gku_prompt_show_widget (prompt, "lock_area");
-		gku_prompt_hide_widget (prompt, "options_area");
-	}
+	gku_prompt_show_widget (prompt, "details_area");
+	gku_prompt_show_widget (prompt, "options_area");
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_IDLE, FALSE, NULL);
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_TIMEOUT, FALSE, NULL);
+	gku_prompt_set_unlock_sensitive (prompt, GCR_UNLOCK_OPTION_ALWAYS,
+	                                 gkm_wrap_login_is_usable (), NULL);
 
 	g_free (label);
 }
diff --git a/ui/gku-prompt-tool.c b/ui/gku-prompt-tool.c
index 2475d84..01ab16a 100644
--- a/ui/gku-prompt-tool.c
+++ b/ui/gku-prompt-tool.c
@@ -210,20 +210,6 @@ on_password_changed (GtkEditable *editable, gpointer user_data)
 }
 
 /**
-* check: A toggle button that defines the state of the options_area
-* builder: The GTKBuilder data to extract "options_area" from
-*
-* Toggles the sensitivity of the "options_area" based on the Toggle Button check
-*
-**/
-static void
-on_auto_check_unlock_toggled (GtkToggleButton *check, GtkBuilder *builder)
-{
-	GtkWidget *area = GTK_WIDGET (gtk_builder_get_object (builder, "options_area"));
-	gtk_widget_set_sensitive (area, !gtk_toggle_button_get_active (check));
-}
-
-/**
 * builder: The builder object to look for visibility keys in
 * dialog: ignored
 *
@@ -425,14 +411,25 @@ prepare_security (GtkBuilder *builder, GtkDialog *dialog)
 }
 
 static void
-prepare_lock_label (GtkWidget *unlock, guint option, const gchar *field)
+prepare_unlock_option (GcrUnlockOptionsWidget *unlock, const gchar *option)
 {
-	gchar *label;
+	GError *error = NULL;
+	gboolean sensitive;
+	gchar *text;
+
+	text = g_key_file_get_string (input_data, option, "label", NULL);
+	if (text)
+		gcr_unlock_options_widget_set_label (unlock, option, text);
+	g_free (text);
+
+	sensitive = g_key_file_get_boolean (input_data, option, "sensitive", &error);
+	if (error == NULL) {
+		text = g_key_file_get_string (input_data, option, "reason", NULL);
+		gcr_unlock_options_widget_set_sensitive (unlock, option, sensitive, text);
+		g_free (text);
+	}
 
-	label = g_key_file_get_string (input_data, "unlock-options", field, NULL);
-	if (label)
-		gcr_unlock_options_widget_set_label (GCR_UNLOCK_OPTIONS_WIDGET (unlock), option, label);
-	g_free (label);
+	g_clear_error (&error);
 }
 
 /**
@@ -445,34 +442,28 @@ prepare_lock_label (GtkWidget *unlock, guint option, const gchar *field)
 static void
 prepare_lock (GtkBuilder *builder, GtkDialog *dialog)
 {
-	GtkWidget *unlock, *area;
-	gint unlock_auto;
-	GtkToggleButton *button;
-	gint unlock_idle, unlock_timeout;
-
-	button = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "auto_unlock_check"));
-	g_signal_connect (button, "toggled", G_CALLBACK (on_auto_check_unlock_toggled), builder);
-	unlock_auto = g_key_file_get_integer (input_data, "unlock-options", "unlock-auto", NULL);
-	gtk_toggle_button_set_active (button, unlock_auto == 0 ? FALSE : TRUE);
-	on_auto_check_unlock_toggled (button, builder);
-
-	unlock = gcr_unlock_options_widget_new ();
+	GcrUnlockOptionsWidget *unlock;
+	GtkWidget *area;
+	gchar *option;
+	guint ttl;
+
+	unlock = GCR_UNLOCK_OPTIONS_WIDGET (gcr_unlock_options_widget_new ());
 	area = GTK_WIDGET (gtk_builder_get_object (builder, "options_area"));
 	g_object_set_data (G_OBJECT (dialog), "unlock-options-widget", unlock);
-	gtk_container_add (GTK_CONTAINER (area), unlock);
-	gtk_widget_show (unlock);
+	gtk_container_add (GTK_CONTAINER (area), GTK_WIDGET (unlock));
+	gtk_widget_show (GTK_WIDGET (unlock));
 
-	unlock_idle = g_key_file_get_integer (input_data, "unlock-options", "unlock-idle", NULL);
-	unlock_timeout = g_key_file_get_integer (input_data, "unlock-options", "unlock-timeout", NULL);
+	ttl = g_key_file_get_integer (input_data, "unlock-options", "ttl", NULL);
+	gcr_unlock_options_widget_set_ttl (unlock, ttl);
 
-	g_object_set (unlock,
-	              "unlock-idle", unlock_idle,
-	              "unlock-timeout", unlock_timeout,
-	              NULL);
+	option = g_key_file_get_string (input_data, "unlock-options", "choice", NULL);
+	gcr_unlock_options_widget_set_choice (unlock, option ? option : GCR_UNLOCK_OPTION_SESSION);
+	g_free (option);
 
-	prepare_lock_label (unlock, GCR_UNLOCK_OPTION_IDLE, "label-idle");
-	prepare_lock_label (unlock, GCR_UNLOCK_OPTION_TIMEOUT, "label-timeout");
-	prepare_lock_label (unlock, GCR_UNLOCK_OPTION_SESSION, "label-session");
+	prepare_unlock_option (unlock, "always");
+	prepare_unlock_option (unlock, "idle");
+	prepare_unlock_option (unlock, "timeout");
+	prepare_unlock_option (unlock, "session");
 }
 
 /**
@@ -772,22 +763,18 @@ gather_response (gint response)
 static void
 gather_unlock_options (GtkBuilder *builder, GtkDialog *dialog)
 {
-	gint unlock_timeout, unlock_idle;
-	GtkToggleButton *button;
-	GtkWidget *unlock;
-
-	button = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "auto_unlock_check"));
-	g_key_file_set_integer (output_data, "unlock-options", "unlock-auto",
-	                        gtk_toggle_button_get_active (button) ? 1 : 0);
+	GcrUnlockOptionsWidget *unlock;
+	const gchar *choice;
 
 	unlock = g_object_get_data (G_OBJECT (dialog), "unlock-options-widget");
-	g_object_get (unlock,
-	              "unlock-timeout", &unlock_timeout,
-	              "unlock-idle", &unlock_idle,
-	              NULL);
 
-	g_key_file_set_integer (output_data, "unlock-options", "unlock-timeout", unlock_timeout);
-	g_key_file_set_integer (output_data, "unlock-options", "unlock-idle", unlock_idle);
+	choice = gcr_unlock_options_widget_get_choice (unlock);
+	if (choice) {
+		g_key_file_set_integer (output_data, "unlock-options", "ttl",
+		                        gcr_unlock_options_widget_get_ttl (unlock));
+
+		g_key_file_set_string (output_data, "unlock-options", "choice", choice);
+	}
 }
 
 /**
diff --git a/ui/gku-prompt.c b/ui/gku-prompt.c
index d723eb3..e1a8fcd 100644
--- a/ui/gku-prompt.c
+++ b/ui/gku-prompt.c
@@ -86,9 +86,8 @@ static void display_async_prompt (GkuPrompt *);
 
 /* User choices we transfer over during a soft prompt reset */
 const struct { const gchar *section; const gchar *name; } SOFT_RESET[] = {
-	{ "unlock-options", "unlock-auto" },
-	{ "unlock-options", "unlock-idle" },
-	{ "unlock-options", "unlock-timeout" },
+	{ "unlock-options", "choice" },
+	{ "unlock-options", "ttl" },
 	{ "details", "expanded" },
 };
 
@@ -884,33 +883,63 @@ gku_prompt_get_transport_password (GkuPrompt *self, const gchar *password_type,
 	return TRUE;
 }
 
-gboolean
-gku_prompt_get_unlock_option (GkuPrompt *self, const gchar *option, gint *value)
+const gchar*
+gku_prompt_get_unlock_choice (GkuPrompt *self)
 {
-	GError *error = NULL;
+	const gchar *result;
+	gchar *value;
 
-	g_return_val_if_fail (GKU_IS_PROMPT (self), FALSE);
-	g_return_val_if_fail (option, FALSE);
-	g_return_val_if_fail (value, FALSE);
-	g_return_val_if_fail (self->pv->output, FALSE);
+	g_return_val_if_fail (GKU_IS_PROMPT (self), NULL);
+	g_return_val_if_fail (self->pv->output, NULL);
 
-	*value = g_key_file_get_integer (self->pv->output, "unlock-options", option, &error);
-	if (error != NULL) {
-		g_clear_error (&error);
-		return FALSE;
-	}
+	value = g_key_file_get_string (self->pv->output, "unlock-options", "choice", NULL);
+	if (value == NULL)
+		return "";
 
-	return TRUE;
+	result = g_intern_string (value);
+	g_free (value);
+
+	return result;
 }
 
 void
-gku_prompt_set_unlock_option (GkuPrompt *self, const gchar *option, gint value)
+gku_prompt_set_unlock_choice (GkuPrompt *self, const gchar *option)
 {
 	g_return_if_fail (GKU_IS_PROMPT (self));
 	g_return_if_fail (option);
 	g_return_if_fail (self->pv->input);
 
-	g_key_file_set_integer (self->pv->input, "unlock-options", option, value);
+	g_key_file_set_string (self->pv->input, "unlock-options", "choice", option);
+}
+
+guint
+gku_prompt_get_unlock_ttl (GkuPrompt *self)
+{
+	g_return_val_if_fail (GKU_IS_PROMPT (self), 0);
+	g_return_val_if_fail (self->pv->output, 0);
+
+	return g_key_file_get_integer (self->pv->output, "unlock-options", "ttl", NULL);
+}
+
+void
+gku_prompt_set_unlock_ttl (GkuPrompt *self, guint ttl)
+{
+	g_return_if_fail (GKU_IS_PROMPT (self));
+	g_return_if_fail (self->pv->input);
+
+	g_key_file_set_integer (self->pv->input, "unlock-options", "ttl", ttl);
+}
+
+void
+gku_prompt_set_unlock_sensitive (GkuPrompt *self, const gchar *option,
+                                 gboolean sensitive, const gchar *reason)
+{
+	g_return_if_fail (GKU_IS_PROMPT (self));
+	g_return_if_fail (self->pv->input);
+
+	g_key_file_set_boolean (self->pv->input, option, "sensitive", sensitive);
+	if (reason)
+		g_key_file_set_string (self->pv->input, option, "reason", reason);
 }
 
 void
@@ -921,7 +950,7 @@ gku_prompt_set_unlock_label (GkuPrompt *self, const gchar *option, const gchar *
 	g_return_if_fail (label);
 	g_return_if_fail (self->pv->input);
 
-	g_key_file_set_string (self->pv->input, "unlock-options", option, label);
+	g_key_file_set_string (self->pv->input, option, "label", label);
 }
 
 /* ----------------------------------------------------------------------------------
@@ -1238,7 +1267,7 @@ void
 gku_prompt_dummy_queue_auto_password (const gchar *password)
 {
 	const static gchar *RESPONSE = "[password]\nparameter=\nvalue=%s\n[prompt]\nresponse=ok\n"
-	                               "[unlock-options]\nunlock-auto=1\n";
+	                               "[unlock-options]\nchoice=always\n";
 	gchar *value;
 
 	g_return_if_fail (password);
diff --git a/ui/gku-prompt.h b/ui/gku-prompt.h
index b230079..c4dea2a 100644
--- a/ui/gku-prompt.h
+++ b/ui/gku-prompt.h
@@ -34,10 +34,6 @@ typedef enum {
 	GKU_RESPONSE_OTHER        = 3,
 } GkuResponse;
 
-#define GKU_UNLOCK_AUTO       "unlock-auto"
-#define GKU_UNLOCK_IDLE       "unlock-idle"
-#define GKU_UNLOCK_TIMEOUT    "unlock-timeout"
-
 #define GKU_TYPE_PROMPT               (gku_prompt_get_type ())
 #define GKU_PROMPT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKU_TYPE_PROMPT, GkuPrompt))
 #define GKU_PROMPT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GKU_TYPE_PROMPT, GkuPromptClass))
@@ -116,13 +112,20 @@ gboolean            gku_prompt_get_transport_password (GkuPrompt *self,
                                                        gpointer *value,
                                                        gsize *n_value);
 
-gboolean            gku_prompt_get_unlock_option      (GkuPrompt *self,
-                                                       const gchar *option,
-                                                       gint *value);
+const gchar*        gku_prompt_get_unlock_choice      (GkuPrompt *self);
+
+void                gku_prompt_set_unlock_choice      (GkuPrompt *self,
+                                                       const gchar *option);
 
-void                gku_prompt_set_unlock_option      (GkuPrompt *self,
+void                gku_prompt_set_unlock_sensitive   (GkuPrompt *self,
                                                        const gchar *option,
-                                                       gint value);
+                                                       gboolean sensitive,
+                                                       const gchar *reason);
+
+guint               gku_prompt_get_unlock_ttl         (GkuPrompt *self);
+
+void                gku_prompt_set_unlock_ttl         (GkuPrompt *self,
+                                                       guint ttl);
 
 void                gku_prompt_set_unlock_label       (GkuPrompt *self,
                                                        const gchar *option,
diff --git a/ui/gku-prompt.ui b/ui/gku-prompt.ui
index a480f64..f8a3d9a 100644
--- a/ui/gku-prompt.ui
+++ b/ui/gku-prompt.ui
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
@@ -84,7 +84,7 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="visibility">False</property>
-                                <property name="invisible_char">&#x2022;</property>
+                                <property name="invisible_char">â?¢</property>
                                 <property name="activates_default">True</property>
                               </object>
                               <packing>
@@ -116,7 +116,7 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="visibility">False</property>
-                                <property name="invisible_char">&#x2022;</property>
+                                <property name="invisible_char">â?¢</property>
                                 <property name="activates_default">True</property>
                               </object>
                               <packing>
@@ -148,7 +148,7 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="visibility">False</property>
-                                <property name="invisible_char">&#x2022;</property>
+                                <property name="invisible_char">â?¢</property>
                                 <property name="activates_default">True</property>
                               </object>
                               <packing>
@@ -184,7 +184,7 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="visibility">False</property>
-                                    <property name="invisible_char">&#x2022;</property>
+                                    <property name="invisible_char">â?¢</property>
                                     <property name="activates_default">True</property>
                                   </object>
                                   <packing>
@@ -258,35 +258,10 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
                         <property name="visible">True</property>
                         <property name="spacing">6</property>
                         <child>
-                          <object class="GtkVBox" id="lock_area">
-                            <property name="spacing">6</property>
+                          <object class="GtkAlignment" id="options_area">
+                            <property name="left_padding">18</property>
                             <child>
-                              <object class="GtkAlignment" id="auto_area">
-                                <property name="visible">True</property>
-                                <child>
-                                  <object class="GtkCheckButton" id="auto_unlock_check">
-                                    <property name="label" translatable="yes">Automatically unlock this keyring whenever I'm logged in</property>
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="receives_default">False</property>
-                                    <property name="draw_indicator">True</property>
-                                  </object>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <object class="GtkAlignment" id="options_area">
-                                <property name="left_padding">18</property>
-                                <child>
-                                  <placeholder/>
-                                </child>
-                              </object>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
+                              <placeholder/>
                             </child>
                           </object>
                           <packing>
@@ -373,11 +348,11 @@ An application wants access to the keyring 'xxx', but it is locked.</property>
   </object>
   <object class="GtkSizeGroup" id="prompt_label_sizegroup">
     <widgets>
-      <widget name="strength_label"/>
-      <widget name="confirm_label"/>
-      <widget name="password_label"/>
-      <widget name="original_label"/>
       <widget name="name_label"/>
+      <widget name="original_label"/>
+      <widget name="password_label"/>
+      <widget name="confirm_label"/>
+      <widget name="strength_label"/>
     </widgets>
   </object>
 </interface>
diff --git a/ui/tests/test-data/prompt-empty b/ui/tests/test-data/prompt-empty
index 8945ea2..825111e 100644
--- a/ui/tests/test-data/prompt-empty
+++ b/ui/tests/test-data/prompt-empty
@@ -1,2 +1,4 @@
+[prompt]
+primary=The primary text.
 
 [visibility]
diff --git a/ui/tests/test-data/prompt-full b/ui/tests/test-data/prompt-full
index ab20a18..ad50490 100644
--- a/ui/tests/test-data/prompt-full
+++ b/ui/tests/test-data/prompt-full
@@ -6,10 +6,10 @@ window-id=
 
 [visibility]
 name_area=false
-original_area=false
+password_area=true
 confirm_area=true
 details_area=true
-lock_area=true
+options_area=true
 
 [transport]
 prime=00E9991CBC77057BEB3E8165025E8338722BDB00297A910EA441129EA84ED091AF9DA55681A192E7E7C283FF6FA9EC5A81E03A8C0999F66B19DF80BE867D0A79B1DB3E42AE7EC1FCA057889F3ED666E86C3C248AA47C8E699997183C7A8093242C0D741CE5D4E1BA99CB5ACE895C53B92D9B9FE6B0D8203B5A8286567B8E9C2A33
diff --git a/ui/tests/test-data/prompt-test b/ui/tests/test-data/prompt-test
index 5fe0f9d..c00e826 100644
--- a/ui/tests/test-data/prompt-test
+++ b/ui/tests/test-data/prompt-test
@@ -1,6 +1,7 @@
 
 [prompt]
 title = Test Prompt
+primary = Test Prompt
 
 [visibility]
 name_area = FALSE



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