[seahorse] Add SeahorseLockable for locking/unlocking places



commit 612e23b4b4af0bc57694f714d262d45472486f64
Author: Stef Walter <stefw collabora co uk>
Date:   Mon Dec 12 14:53:52 2011 +0100

    Add SeahorseLockable for locking/unlocking places
    
     * Generic interface doing what we were already doing in various places
       in the code.
     * Simplifies sidebar lock/unlock icon code.
     * In the future will be used to build the context menu on the sidebar

 gkr/seahorse-gkr-keyring.c                     |  106 +++++++-
 libseahorse/Makefile.am                        |    2 +
 {pkcs11 => libseahorse}/seahorse-interaction.c |    0
 {pkcs11 => libseahorse}/seahorse-interaction.h |    0
 libseahorse/seahorse-lockable.c                |  143 ++++++++++
 libseahorse/seahorse-lockable.h                |   89 ++++++
 pkcs11/Makefile.am                             |    1 -
 pkcs11/seahorse-pkcs11-actions.c               |   13 +-
 pkcs11/seahorse-token.c                        |  351 ++++++++++++------------
 pkcs11/seahorse-token.h                        |   20 --
 src/seahorse-sidebar.c                         |  171 +++++++-----
 11 files changed, 615 insertions(+), 281 deletions(-)
---
diff --git a/gkr/seahorse-gkr-keyring.c b/gkr/seahorse-gkr-keyring.c
index 98eacd3..db936b6 100644
--- a/gkr/seahorse-gkr-keyring.c
+++ b/gkr/seahorse-gkr-keyring.c
@@ -23,6 +23,7 @@
 #include "config.h"
 
 #include "seahorse-gkr.h"
+#include "seahorse-gkr-backend.h"
 #include "seahorse-gkr-dialogs.h"
 #include "seahorse-gkr-keyring-deleter.h"
 #include "seahorse-gkr-keyring.h"
@@ -31,9 +32,10 @@
 
 #include "seahorse-action.h"
 #include "seahorse-deletable.h"
-#include "seahorse-viewable.h"
+#include "seahorse-lockable.h"
 #include "seahorse-progress.h"
 #include "seahorse-util.h"
+#include "seahorse-viewable.h"
 
 #include <gcr/gcr.h>
 
@@ -48,6 +50,8 @@ enum {
 	PROP_URI,
 	PROP_ACTIONS,
 	PROP_LOCKED,
+	PROP_LOCKABLE,
+	PROP_UNLOCKABLE
 };
 
 struct _SeahorseGkrKeyringPrivate {
@@ -68,12 +72,15 @@ static void     seahorse_keyring_collection_iface   (GcrCollectionIface *iface);
 
 static void     seahorse_keyring_deletable_iface    (SeahorseDeletableIface *iface);
 
+static void     seahorse_keyring_lockable_iface     (SeahorseLockableIface *iface);
+
 static void     seahorse_keyring_viewable_iface     (SeahorseViewableIface *iface);
 
 G_DEFINE_TYPE_WITH_CODE (SeahorseGkrKeyring, seahorse_gkr_keyring, SEAHORSE_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_keyring_collection_iface);
                          G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_keyring_place_iface);
                          G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_DELETABLE, seahorse_keyring_deletable_iface);
+                         G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_LOCKABLE, seahorse_keyring_lockable_iface);
                          G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_VIEWABLE, seahorse_keyring_viewable_iface);
 );
 
@@ -450,6 +457,12 @@ seahorse_gkr_keyring_get_property (GObject *obj, guint prop_id, GValue *value,
 	case PROP_LOCKED:
 		g_value_set_boolean (value, seahorse_gkr_keyring_get_locked (self));
 		break;
+	case PROP_LOCKABLE:
+		g_value_set_boolean (value, !seahorse_gkr_keyring_get_locked (self));
+		break;
+	case PROP_UNLOCKABLE:
+		g_value_set_boolean (value, seahorse_gkr_keyring_get_locked (self));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 		break;
@@ -488,6 +501,8 @@ seahorse_gkr_keyring_class_init (SeahorseGkrKeyringClass *klass)
 	           g_param_spec_boolean ("locked", "Locked", "Keyring is locked?",
 	                                 FALSE, G_PARAM_READABLE));
 
+	g_object_class_override_property (gobject_class, PROP_LOCKABLE, "lockable");
+	g_object_class_override_property (gobject_class, PROP_UNLOCKABLE, "unlockable");
 }
 
 static void
@@ -545,6 +560,95 @@ seahorse_keyring_deletable_iface (SeahorseDeletableIface *iface)
 }
 
 static void
+on_keyring_xlock_done (GnomeKeyringResult result,
+                       gpointer user_data)
+{
+	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+	GError *error = NULL;
+
+	if (seahorse_gkr_propagate_error (result, &error))
+		g_simple_async_result_take_error (res, error);
+
+	seahorse_gkr_backend_load_async (NULL, NULL, NULL, NULL);
+	g_simple_async_result_complete_in_idle (res);
+}
+
+static void
+seahorse_gkr_keyring_lock_async (SeahorseLockable *lockable,
+                                 GTlsInteraction *interaction,
+                                 GCancellable *cancellable,
+                                 GAsyncReadyCallback callback,
+                                 gpointer user_data)
+{
+	SeahorseGkrKeyring *keyring = SEAHORSE_GKR_KEYRING (lockable);
+	GSimpleAsyncResult *res;
+
+	res = g_simple_async_result_new (G_OBJECT (lockable), callback, user_data,
+	                                 seahorse_gkr_keyring_lock_async);
+
+	gnome_keyring_lock (seahorse_gkr_keyring_get_name (keyring),
+	                    on_keyring_xlock_done, g_object_ref (res), g_object_unref);
+
+	g_object_unref (res);
+}
+
+static gboolean
+seahorse_gkr_keyring_lock_finish (SeahorseLockable *lockable,
+                                  GAsyncResult *result,
+                                  GError **error)
+{
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (lockable),
+	                      seahorse_gkr_keyring_lock_async), FALSE);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+seahorse_gkr_keyring_unlock_async (SeahorseLockable *lockable,
+                                   GTlsInteraction *interaction,
+                                   GCancellable *cancellable,
+                                   GAsyncReadyCallback callback,
+                                   gpointer user_data)
+{
+	SeahorseGkrKeyring *keyring = SEAHORSE_GKR_KEYRING (lockable);
+	GSimpleAsyncResult *res;
+
+	res = g_simple_async_result_new (G_OBJECT (lockable), callback, user_data,
+	                                 seahorse_gkr_keyring_unlock_async);
+
+	gnome_keyring_unlock (seahorse_gkr_keyring_get_name (keyring), NULL,
+	                      on_keyring_xlock_done, g_object_ref (res), g_object_unref);
+
+	g_object_unref (res);
+}
+
+static gboolean
+seahorse_gkr_keyring_unlock_finish (SeahorseLockable *lockable,
+                                    GAsyncResult *result,
+                                    GError **error)
+{
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (lockable),
+	                      seahorse_gkr_keyring_unlock_async), FALSE);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+seahorse_keyring_lockable_iface (SeahorseLockableIface *iface)
+{
+	iface->lock_async = seahorse_gkr_keyring_lock_async;
+	iface->lock_finish = seahorse_gkr_keyring_lock_finish;
+	iface->unlock_async = seahorse_gkr_keyring_unlock_async;
+	iface->unlock_finish = seahorse_gkr_keyring_unlock_finish;
+}
+
+static void
 seahorse_gkr_keyring_show_viewer (SeahorseViewable *viewable,
                                   GtkWindow *parent)
 {
diff --git a/libseahorse/Makefile.am b/libseahorse/Makefile.am
index 668fa17..be5db0d 100644
--- a/libseahorse/Makefile.am
+++ b/libseahorse/Makefile.am
@@ -43,7 +43,9 @@ libseahorse_la_SOURCES = \
 	seahorse-exportable.c seahorse-exportable.h \
 	seahorse-exporter.c seahorse-exporter.h \
 	seahorse-icons.c seahorse-icons.h \
+	seahorse-interaction.c seahorse-interaction.h \
 	seahorse-key-manager-store.c seahorse-key-manager-store.h \
+	seahorse-lockable.c seahorse-lockable.h \
 	seahorse-object.c seahorse-object.h \
 	seahorse-object-list.c seahorse-object-list.h \
 	seahorse-object-model.c seahorse-object-model.h \
diff --git a/pkcs11/seahorse-interaction.c b/libseahorse/seahorse-interaction.c
similarity index 100%
rename from pkcs11/seahorse-interaction.c
rename to libseahorse/seahorse-interaction.c
diff --git a/pkcs11/seahorse-interaction.h b/libseahorse/seahorse-interaction.h
similarity index 100%
rename from pkcs11/seahorse-interaction.h
rename to libseahorse/seahorse-interaction.h
diff --git a/libseahorse/seahorse-lockable.c b/libseahorse/seahorse-lockable.c
new file mode 100644
index 0000000..dae6bbb
--- /dev/null
+++ b/libseahorse/seahorse-lockable.c
@@ -0,0 +1,143 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2004,2005 Stefan Walter
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "seahorse-lockable.h"
+
+typedef SeahorseLockableIface SeahorseLockableInterface;
+
+G_DEFINE_INTERFACE (SeahorseLockable, seahorse_lockable, G_TYPE_OBJECT);
+
+static void
+seahorse_lockable_default_init (SeahorseLockableIface *iface)
+{
+	static gboolean initialized = FALSE;
+	if (!initialized) {
+		initialized = TRUE;
+
+		g_object_interface_install_property (iface,
+		               g_param_spec_boolean ("lockable", "Lockable", "Is actually lockable",
+		                                      FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+		g_object_interface_install_property (iface,
+		               g_param_spec_boolean ("unlockable", "Unlockable", "Is actually unlockable",
+		                                      FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+	}
+}
+
+void
+seahorse_lockable_lock_async (SeahorseLockable *lockable,
+                              GTlsInteraction *interaction,
+                              GCancellable *cancellable,
+                              GAsyncReadyCallback callback,
+                              gpointer user_data)
+{
+	SeahorseLockableIface *iface;
+
+	g_return_if_fail (SEAHORSE_IS_LOCKABLE (lockable));
+	g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+	iface = SEAHORSE_LOCKABLE_GET_INTERFACE (lockable);
+	g_return_if_fail (iface->lock_async != NULL);
+
+	(iface->lock_async) (lockable, interaction, cancellable, callback, user_data);
+}
+
+gboolean
+seahorse_lockable_lock_finish (SeahorseLockable *lockable,
+                               GAsyncResult *result,
+                               GError **error)
+{
+	SeahorseLockableIface *iface;
+
+	g_return_val_if_fail (SEAHORSE_IS_LOCKABLE (lockable), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	iface = SEAHORSE_LOCKABLE_GET_INTERFACE (lockable);
+	g_return_val_if_fail (iface->lock_finish != NULL, FALSE);
+
+	return (iface->lock_finish) (lockable, result, error);
+}
+
+
+void
+seahorse_lockable_unlock_async (SeahorseLockable *lockable,
+                                GTlsInteraction *interaction,
+                                GCancellable *cancellable,
+                                GAsyncReadyCallback callback,
+                                gpointer user_data)
+{
+	SeahorseLockableIface *iface;
+
+	g_return_if_fail (SEAHORSE_IS_LOCKABLE (lockable));
+	g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+	iface = SEAHORSE_LOCKABLE_GET_INTERFACE (lockable);
+	g_return_if_fail (iface->unlock_async != NULL);
+
+	(iface->unlock_async) (lockable, interaction, cancellable, callback, user_data);
+}
+
+gboolean
+seahorse_lockable_unlock_finish (SeahorseLockable *lockable,
+                                 GAsyncResult *result,
+                                 GError **error)
+{
+	SeahorseLockableIface *iface;
+
+	g_return_val_if_fail (SEAHORSE_IS_LOCKABLE (lockable), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	iface = SEAHORSE_LOCKABLE_GET_INTERFACE (lockable);
+	g_return_val_if_fail (iface->unlock_finish != NULL, FALSE);
+
+	return (iface->unlock_finish) (lockable, result, error);
+}
+
+gboolean
+seahorse_lockable_can_unlock (gpointer object)
+{
+	gboolean unlockable;
+
+	if (!SEAHORSE_IS_LOCKABLE (object))
+		return FALSE;
+
+	g_object_get (object, "unlockable", &unlockable, NULL);
+	return unlockable;
+}
+
+gboolean
+seahorse_lockable_can_lock (gpointer object)
+{
+	gboolean lockable;
+
+	if (!SEAHORSE_IS_LOCKABLE (object))
+		return FALSE;
+
+	g_object_get (object, "lockable", &lockable, NULL);
+	return lockable;
+}
diff --git a/libseahorse/seahorse-lockable.h b/libseahorse/seahorse-lockable.h
new file mode 100644
index 0000000..14cbfa2
--- /dev/null
+++ b/libseahorse/seahorse-lockable.h
@@ -0,0 +1,89 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef __SEAHORSE_LOCKABLE_H__
+#define __SEAHORSE_LOCKABLE_H__
+
+#include <gio/gio.h>
+
+#include <gtk/gtk.h>
+
+#define SEAHORSE_TYPE_LOCKABLE                (seahorse_lockable_get_type ())
+#define SEAHORSE_LOCKABLE(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_LOCKABLE, SeahorseLockable))
+#define SEAHORSE_IS_LOCKABLE(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_LOCKABLE))
+#define SEAHORSE_LOCKABLE_GET_INTERFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SEAHORSE_TYPE_LOCKABLE, SeahorseLockableIface))
+
+typedef struct _SeahorseLockable SeahorseLockable;
+typedef struct _SeahorseLockableIface SeahorseLockableIface;
+
+struct _SeahorseLockableIface {
+	GTypeInterface parent;
+
+	void        (* lock_async)         (SeahorseLockable *lockable,
+	                                    GTlsInteraction *interaction,
+	                                    GCancellable *cancellable,
+	                                    GAsyncReadyCallback callback,
+	                                    gpointer user_data);
+
+	gboolean    (* lock_finish)        (SeahorseLockable *lockable,
+	                                    GAsyncResult *result,
+	                                    GError **error);
+
+	void        (* unlock_async)       (SeahorseLockable *lockable,
+	                                    GTlsInteraction *interaction,
+	                                    GCancellable *cancellable,
+	                                    GAsyncReadyCallback callback,
+	                                    gpointer user_data);
+
+	gboolean    (* unlock_finish)      (SeahorseLockable *lockable,
+	                                    GAsyncResult *result,
+	                                    GError **error);
+};
+
+GType              seahorse_lockable_get_type               (void) G_GNUC_CONST;
+
+void               seahorse_lockable_lock_async             (SeahorseLockable *lockable,
+                                                             GTlsInteraction *interaction,
+                                                             GCancellable *cancellable,
+                                                             GAsyncReadyCallback callback,
+                                                             gpointer user_data);
+
+gboolean           seahorse_lockable_lock_finish            (SeahorseLockable *lockable,
+                                                             GAsyncResult *result,
+                                                             GError **error);
+
+void               seahorse_lockable_unlock_async           (SeahorseLockable *lockable,
+                                                             GTlsInteraction *interaction,
+                                                             GCancellable *cancellable,
+                                                             GAsyncReadyCallback callback,
+                                                             gpointer user_data);
+
+gboolean           seahorse_lockable_unlock_finish          (SeahorseLockable *lockable,
+                                                             GAsyncResult *result,
+                                                             GError **error);
+
+gboolean           seahorse_lockable_can_lock               (gpointer object);
+
+gboolean           seahorse_lockable_can_unlock             (gpointer object);
+
+#endif /* __SEAHORSE_LOCKABLE_H__ */
diff --git a/pkcs11/Makefile.am b/pkcs11/Makefile.am
index 7c07782..844aac9 100644
--- a/pkcs11/Makefile.am
+++ b/pkcs11/Makefile.am
@@ -17,7 +17,6 @@ noinst_LTLIBRARIES = libseahorse-pkcs11.la
 libseahorse_pkcs11_la_SOURCES = \
 	seahorse-certificate.c seahorse-certificate.h \
 	seahorse-certificate-der-exporter.c seahorse-certificate-der-exporter.h \
-	seahorse-interaction.c seahorse-interaction.h \
 	seahorse-pkcs11-actions.c seahorse-pkcs11-actions.h \
 	seahorse-pkcs11-backend.c seahorse-pkcs11-backend.h \
 	seahorse-pkcs11-deleter.c seahorse-pkcs11-deleter.h \
diff --git a/pkcs11/seahorse-pkcs11-actions.c b/pkcs11/seahorse-pkcs11-actions.c
index 6deae7b..859c8cf 100644
--- a/pkcs11/seahorse-pkcs11-actions.c
+++ b/pkcs11/seahorse-pkcs11-actions.c
@@ -33,6 +33,7 @@
 #include "seahorse-action.h"
 #include "seahorse-actions.h"
 #include "seahorse-delete-dialog.h"
+#include "seahorse-lockable.h"
 #include "seahorse-object-list.h"
 #include "seahorse-progress.h"
 #include "seahorse-registry.h"
@@ -63,7 +64,7 @@ on_token_locked (GObject *source,
 	GtkWindow *window = GTK_WINDOW (user_data);
 	GError *error = NULL;
 
-	seahorse_token_lock_finish (SEAHORSE_TOKEN (source), result, &error);
+	seahorse_lockable_lock_finish (SEAHORSE_LOCKABLE (source), result, &error);
 	if (error != NULL) {
 		if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
 		    !g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
@@ -84,8 +85,8 @@ on_token_lock (GtkAction *action,
 	window = seahorse_action_get_window (action);
 	interaction = seahorse_interaction_new (window);
 
-	seahorse_token_lock_async (SEAHORSE_TOKEN (user_data), interaction, NULL,
-	                           on_token_locked, g_object_ref (window));
+	seahorse_lockable_lock_async (SEAHORSE_LOCKABLE (user_data), interaction, NULL,
+	                              on_token_locked, g_object_ref (window));
 
 	g_object_unref (interaction);
 }
@@ -99,7 +100,7 @@ on_token_unlocked (GObject *source,
 	GtkWindow *window = GTK_WINDOW (user_data);
 	GError *error = NULL;
 
-	seahorse_token_unlock_finish (SEAHORSE_TOKEN (source), result, &error);
+	seahorse_lockable_unlock_finish (SEAHORSE_LOCKABLE (source), result, &error);
 	if (error != NULL) {
 		if (!g_error_matches (error, GCK_ERROR, CKR_FUNCTION_CANCELED) ||
 		    !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
@@ -122,8 +123,8 @@ on_token_unlock (GtkAction *action,
 	window = seahorse_action_get_window (action);
 	interaction = seahorse_interaction_new (window);
 
-	seahorse_token_unlock_async (SEAHORSE_TOKEN (user_data), interaction, NULL,
-	                             on_token_unlocked, g_object_ref (window));
+	seahorse_lockable_unlock_async (SEAHORSE_LOCKABLE (user_data), interaction, NULL,
+	                                on_token_unlocked, g_object_ref (window));
 
 	g_object_unref (interaction);
 }
diff --git a/pkcs11/seahorse-token.c b/pkcs11/seahorse-token.c
index 893671a..c4128ca 100644
--- a/pkcs11/seahorse-token.c
+++ b/pkcs11/seahorse-token.c
@@ -35,6 +35,7 @@
 #include "seahorse-private-key.h"
 #include "seahorse-token.h"
 
+#include "seahorse-lockable.h"
 #include "seahorse-place.h"
 #include "seahorse-registry.h"
 #include "seahorse-util.h"
@@ -71,9 +72,12 @@ static void          seahorse_token_place_iface          (SeahorsePlaceIface *if
 
 static void          seahorse_token_collection_iface     (GcrCollectionIface *iface);
 
+static void          seahorse_token_lockable_iface       (SeahorseLockableIface *iface);
+
 G_DEFINE_TYPE_EXTENDED (SeahorseToken, seahorse_token, G_TYPE_OBJECT, 0,
                         G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_token_collection_iface);
                         G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_token_place_iface);
+                        G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_LOCKABLE, seahorse_token_lockable_iface);
 );
 
 static void
@@ -759,9 +763,177 @@ seahorse_token_collection_iface (GcrCollectionIface *iface)
 	iface->contains = seahorse_token_contains;
 }
 
-/* --------------------------------------------------------------------------
- * PUBLIC
- */
+static gboolean
+is_session_logged_in (GckSession *session)
+{
+	GckSessionInfo *info;
+	gboolean logged_in;
+
+	if (session == NULL)
+		return FALSE;
+
+	info = gck_session_get_info (session);
+	logged_in = (info != NULL) &&
+	            (info->state == CKS_RW_USER_FUNCTIONS ||
+	             info->state == CKS_RO_USER_FUNCTIONS ||
+	             info->state == CKS_RW_SO_FUNCTIONS);
+	gck_session_info_free (info);
+
+	return logged_in;
+}
+
+static void
+on_session_logout (GObject *source,
+                   GAsyncResult *result,
+                   gpointer user_data)
+{
+	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+	SeahorseToken *self = SEAHORSE_TOKEN (g_async_result_get_source_object (user_data));
+	GError *error = NULL;
+
+	gck_session_logout_finish (GCK_SESSION (source), result, &error);
+	if (error == NULL)
+		seahorse_token_refresh_async (self, NULL, NULL, NULL);
+	else
+		g_simple_async_result_take_error (res, error);
+
+	g_simple_async_result_complete (res);
+	g_object_unref (self);
+	g_object_unref (res);
+}
+
+static void
+on_login_interactive (GObject *source,
+                      GAsyncResult *result,
+                      gpointer user_data)
+{
+	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+	SeahorseToken *self = SEAHORSE_TOKEN (g_async_result_get_source_object (user_data));
+	GError *error = NULL;
+
+	gck_session_logout_finish (GCK_SESSION (source), result, &error);
+	if (error == NULL)
+		seahorse_token_refresh_async (self, NULL, NULL, NULL);
+	else
+		g_simple_async_result_take_error (res, error);
+
+	g_simple_async_result_complete (res);
+	g_object_unref (self);
+	g_object_unref (res);
+}
+
+static void
+on_session_login_open (GObject *source,
+                       GAsyncResult *result,
+                       gpointer user_data)
+{
+	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+	SeahorseToken *self = SEAHORSE_TOKEN (g_async_result_get_source_object (user_data));
+	GckSession *session;
+	GError *error = NULL;
+
+	session = gck_session_open_finish (result, &error);
+	if (error == NULL) {
+		seahorse_token_set_session (self, session);
+		seahorse_token_refresh_async (self, NULL, NULL, NULL);
+		g_object_unref (session);
+	} else {
+		g_simple_async_result_take_error (res, error);
+	}
+
+	g_simple_async_result_complete (res);
+	g_object_unref (self);
+	g_object_unref (res);
+}
+
+static void
+seahorse_token_lock_async (SeahorseLockable *lockable,
+                           GTlsInteraction *interaction,
+                           GCancellable *cancellable,
+                           GAsyncReadyCallback callback,
+                           gpointer user_data)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (lockable);
+	GSimpleAsyncResult *res;
+
+	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+	                                 seahorse_token_lock_async);
+
+	if (is_session_logged_in (self->pv->session))
+		gck_session_logout_async (self->pv->session, cancellable,
+		                          on_session_logout, g_object_ref (res));
+	else
+		g_simple_async_result_complete_in_idle (res);
+
+	g_object_unref (res);
+}
+
+static gboolean
+seahorse_token_lock_finish (SeahorseLockable *lockable,
+                            GAsyncResult *result,
+                            GError **error)
+{
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (lockable),
+	                      seahorse_token_lock_async), FALSE);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+seahorse_token_unlock_async (SeahorseLockable *lockable,
+                             GTlsInteraction *interaction,
+                             GCancellable *cancellable,
+                             GAsyncReadyCallback callback,
+                             gpointer user_data)
+{
+	SeahorseToken *self = SEAHORSE_TOKEN (lockable);
+	GSimpleAsyncResult *res;
+	GckSessionOptions options;
+
+	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+	                                 seahorse_token_unlock_async);
+
+	if (is_session_logged_in (self->pv->session)) {
+		g_simple_async_result_complete_in_idle (res);
+
+	} else if (self->pv->session) {
+		gck_session_login_interactive_async (self->pv->session, CKU_USER,
+		                                     interaction, NULL, on_login_interactive,
+		                                     g_object_ref (res));
+	} else {
+		options = calculate_session_options (self);
+		gck_session_open_async (self->pv->slot, options | GCK_SESSION_LOGIN_USER, interaction,
+		                        NULL, on_session_login_open, g_object_ref (res));
+	}
+
+	g_object_unref (res);
+}
+
+static gboolean
+seahorse_token_unlock_finish (SeahorseLockable *lockable,
+                              GAsyncResult *result,
+                              GError **error)
+{
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (lockable),
+	                      seahorse_token_unlock_async), FALSE);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+		return FALSE;
+
+	return TRUE;
+}
+
+static void
+seahorse_token_lockable_iface (SeahorseLockableIface *iface)
+{
+	iface->lock_async = seahorse_token_lock_async;
+	iface->lock_finish = seahorse_token_lock_finish;
+	iface->unlock_async = seahorse_token_unlock_async;
+	iface->unlock_finish = seahorse_token_unlock_finish;
+}
 
 SeahorseToken *
 seahorse_token_new (GckSlot *slot)
@@ -818,25 +990,6 @@ seahorse_token_get_info (SeahorseToken *self)
 	return self->pv->info;
 }
 
-static gboolean
-is_session_logged_in (GckSession *session)
-{
-	GckSessionInfo *info;
-	gboolean logged_in;
-
-	if (session == NULL)
-		return FALSE;
-
-	info = gck_session_get_info (session);
-	logged_in = (info != NULL) &&
-	            (info->state == CKS_RW_USER_FUNCTIONS ||
-	             info->state == CKS_RO_USER_FUNCTIONS ||
-	             info->state == CKS_RW_SO_FUNCTIONS);
-	gck_session_info_free (info);
-
-	return logged_in;
-}
-
 gboolean
 seahorse_token_get_lockable (SeahorseToken *self)
 {
@@ -913,160 +1066,6 @@ seahorse_token_remove_object (SeahorseToken *self,
 	g_list_free_full (objects, g_object_unref);
 }
 
-static void
-on_session_logout (GObject *source,
-                   GAsyncResult *result,
-                   gpointer user_data)
-{
-	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
-	SeahorseToken *self = SEAHORSE_TOKEN (g_async_result_get_source_object (user_data));
-	GError *error = NULL;
-
-	gck_session_logout_finish (GCK_SESSION (source), result, &error);
-	if (error == NULL)
-		seahorse_token_refresh_async (self, NULL, NULL, NULL);
-	else
-		g_simple_async_result_take_error (res, error);
-
-	g_simple_async_result_complete (res);
-	g_object_unref (self);
-	g_object_unref (res);
-}
-
-void
-seahorse_token_lock_async (SeahorseToken *self,
-                           GTlsInteraction *interaction,
-                           GCancellable *cancellable,
-                           GAsyncReadyCallback callback,
-                           gpointer user_data)
-{
-	GSimpleAsyncResult *res;
-
-	g_return_if_fail (SEAHORSE_IS_TOKEN (self));
-	g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
-	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
-	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
-	                                 seahorse_token_lock_async);
-
-	if (is_session_logged_in (self->pv->session))
-		gck_session_logout_async (self->pv->session, cancellable,
-		                          on_session_logout, g_object_ref (res));
-	else
-		g_simple_async_result_complete_in_idle (res);
-
-	g_object_unref (res);
-}
-
-gboolean
-seahorse_token_lock_finish (SeahorseToken *self,
-                            GAsyncResult *result,
-                            GError **error)
-{
-	g_return_val_if_fail (SEAHORSE_IS_TOKEN (self), FALSE);
-	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
-	                      seahorse_token_lock_async), FALSE);
-
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
-		return FALSE;
-
-	return TRUE;
-}
-
-static void
-on_login_interactive (GObject *source,
-                      GAsyncResult *result,
-                      gpointer user_data)
-{
-	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
-	SeahorseToken *self = SEAHORSE_TOKEN (g_async_result_get_source_object (user_data));
-	GError *error = NULL;
-
-	gck_session_logout_finish (GCK_SESSION (source), result, &error);
-	if (error == NULL)
-		seahorse_token_refresh_async (self, NULL, NULL, NULL);
-	else
-		g_simple_async_result_take_error (res, error);
-
-	g_simple_async_result_complete (res);
-	g_object_unref (self);
-	g_object_unref (res);
-}
-
-static void
-on_session_login_open (GObject *source,
-                       GAsyncResult *result,
-                       gpointer user_data)
-{
-	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
-	SeahorseToken *self = SEAHORSE_TOKEN (g_async_result_get_source_object (user_data));
-	GckSession *session;
-	GError *error = NULL;
-
-	session = gck_session_open_finish (result, &error);
-	if (error == NULL) {
-		seahorse_token_set_session (self, session);
-		seahorse_token_refresh_async (self, NULL, NULL, NULL);
-		g_object_unref (session);
-	} else {
-		g_simple_async_result_take_error (res, error);
-	}
-
-	g_simple_async_result_complete (res);
-	g_object_unref (self);
-	g_object_unref (res);
-}
-
-void
-seahorse_token_unlock_async (SeahorseToken *self,
-                             GTlsInteraction *interaction,
-                             GCancellable *cancellable,
-                             GAsyncReadyCallback callback,
-                             gpointer user_data)
-{
-	GSimpleAsyncResult *res;
-	GckSessionOptions options;
-
-	g_return_if_fail (SEAHORSE_IS_TOKEN (self));
-	g_return_if_fail (interaction == NULL || G_IS_TLS_INTERACTION (interaction));
-	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
-	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
-	                                 seahorse_token_unlock_async);
-
-	if (is_session_logged_in (self->pv->session)) {
-		g_simple_async_result_complete_in_idle (res);
-
-	} else if (self->pv->session) {
-		gck_session_login_interactive_async (self->pv->session, CKU_USER,
-		                                     interaction, NULL, on_login_interactive,
-		                                     g_object_ref (res));
-	} else {
-		options = calculate_session_options (self);
-		gck_session_open_async (self->pv->slot, options | GCK_SESSION_LOGIN_USER, interaction,
-		                        NULL, on_session_login_open, g_object_ref (res));
-	}
-
-	g_object_unref (res);
-}
-
-gboolean
-seahorse_token_unlock_finish (SeahorseToken *self,
-                              GAsyncResult *result,
-                              GError **error)
-{
-	g_return_val_if_fail (SEAHORSE_IS_TOKEN (self), FALSE);
-	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
-	                      seahorse_token_unlock_async), FALSE);
-
-	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
-		return FALSE;
-
-	return TRUE;
-}
-
 gboolean
 seahorse_token_is_deletable (SeahorseToken *self,
                              GckObject *object)
diff --git a/pkcs11/seahorse-token.h b/pkcs11/seahorse-token.h
index 0b25027..bf3a64c 100644
--- a/pkcs11/seahorse-token.h
+++ b/pkcs11/seahorse-token.h
@@ -73,26 +73,6 @@ void                   seahorse_token_remove_object     (SeahorseToken *self,
 gboolean               seahorse_token_is_deletable      (SeahorseToken *self,
                                                          GckObject *object);
 
-void                   seahorse_token_lock_async        (SeahorseToken *self,
-                                                         GTlsInteraction *interaction,
-                                                         GCancellable *cancellable,
-                                                         GAsyncReadyCallback callback,
-                                                         gpointer user_data);
-
-gboolean               seahorse_token_lock_finish       (SeahorseToken *self,
-                                                         GAsyncResult *result,
-                                                         GError **error);
-
-void                   seahorse_token_unlock_async      (SeahorseToken *self,
-                                                         GTlsInteraction *interaction,
-                                                         GCancellable *cancellable,
-                                                         GAsyncReadyCallback callback,
-                                                         gpointer user_data);
-
-gboolean               seahorse_token_unlock_finish     (SeahorseToken *self,
-                                                         GAsyncResult *result,
-                                                         GError **error);
-
 void                   seahorse_token_refresh_async     (SeahorseToken *self,
                                                          GCancellable *cancellable,
                                                          GAsyncReadyCallback callback,
diff --git a/src/seahorse-sidebar.c b/src/seahorse-sidebar.c
index 65e9e5c..58d791c 100644
--- a/src/seahorse-sidebar.c
+++ b/src/seahorse-sidebar.c
@@ -26,8 +26,11 @@
 #include "seahorse-action.h"
 #include "seahorse-actions.h"
 #include "seahorse-backend.h"
+#include "seahorse-interaction.h"
+#include "seahorse-lockable.h"
 #include "seahorse-place.h"
 #include "seahorse-registry.h"
+#include "seahorse-util.h"
 
 #include "gkr/seahorse-gkr.h"
 #include "pgp/seahorse-pgp.h"
@@ -92,7 +95,6 @@ enum {
 	SIDEBAR_CATEGORY,
 	SIDEBAR_COLLECTION,
 	SIDEBAR_URI,
-	SIDEBAR_ACTIONS,
 	SIDEBAR_N_COLUMNS
 };
 
@@ -104,8 +106,7 @@ static GType column_types[] = {
 	G_TYPE_BOOLEAN,
 	G_TYPE_STRING,
 	0 /* later */,
-	G_TYPE_STRING,
-	0 /* later */
+	G_TYPE_STRING
 };
 
 enum {
@@ -123,7 +124,6 @@ seahorse_sidebar_init (SeahorseSidebar *self)
 	g_assert (SIDEBAR_N_COLUMNS == G_N_ELEMENTS (column_types));
 	column_types[SIDEBAR_ICON] = G_TYPE_ICON;
 	column_types[SIDEBAR_COLLECTION] = GCR_TYPE_COLLECTION;
-	column_types[SIDEBAR_ACTIONS] = GTK_TYPE_ACTION_GROUP;
 	self->store = gtk_list_store_newv (SIDEBAR_N_COLUMNS, column_types);
 
 	self->backends = g_ptr_array_new_with_free_func (g_object_unref);
@@ -288,13 +288,11 @@ update_backend (SeahorseSidebar *self,
 {
 	GList *collections, *l;
 	GtkActionGroup *actions;
-	GtkActionGroup *cloned;
 	GParamSpec *spec;
 	gchar *category;
 	gchar *tooltip;
 	gchar *label;
 	GIcon *icon = NULL;
-	GList *objects;
 	gchar *uri;
 
 	collections = gcr_collection_get_objects (backend);
@@ -332,14 +330,6 @@ update_backend (SeahorseSidebar *self,
 		              "actions", &actions,
 		              NULL);
 
-		cloned = NULL;
-		if (actions) {
-			objects = g_list_append (NULL, l->data);
-			cloned = seahorse_actions_clone_for_objects (actions, objects);
-			g_list_free (objects);
-			g_object_unref (actions);
-		}
-
 		spec = g_object_class_find_property (G_OBJECT_GET_CLASS (l->data), "label");
 		g_return_if_fail (spec != NULL);
 
@@ -352,10 +342,8 @@ update_backend (SeahorseSidebar *self,
 		                    SIDEBAR_ICON, icon,
 		                    SIDEBAR_EDITABLE, (spec->flags & G_PARAM_WRITABLE) ? TRUE : FALSE,
 		                    SIDEBAR_COLLECTION, l->data,
-		                    SIDEBAR_ACTIONS, cloned,
 		                    SIDEBAR_URI, uri,
 		                    -1);
-		g_clear_object (&cloned);
 		g_clear_object (&icon);
 		g_free (label);
 		g_free (tooltip);
@@ -537,41 +525,25 @@ update_places_later (SeahorseSidebar *self)
 		self->update_places_sig = g_idle_add (on_idle_update_places, self);
 }
 
-static GtkAction *
-lookup_relevant_action_for_iter (GtkTreeModel *model,
-                                 GtkTreeIter *iter,
-                                 gboolean *is_lock)
+static SeahorseLockable *
+lookup_lockable_for_iter (GtkTreeModel *model,
+                          GtkTreeIter *iter)
 {
-	GtkActionGroup *actions = NULL;
-	GtkAction *action;
+	GcrCollection *collection;
 
 	gtk_tree_model_get (model, iter,
-	                    SIDEBAR_ACTIONS, &actions,
+	                    SIDEBAR_COLLECTION, &collection,
 	                    -1);
 
-	if (!actions)
+	if (collection == NULL)
 		return NULL;
 
-	action = gtk_action_group_get_action (actions, "unlock");
-	if (action != NULL &&
-	    gtk_action_is_visible (action) &&
-	    gtk_action_is_sensitive (action)) {
-		*is_lock = FALSE;
-	} else {
-		action = gtk_action_group_get_action (actions, "lock");
-		if (action != NULL &&
-		    gtk_action_is_visible (action) &&
-		    gtk_action_is_sensitive (action)) {
-			*is_lock = TRUE;
-		} else {
-			action = NULL;
-		}
+	if (!SEAHORSE_IS_LOCKABLE (collection)) {
+		g_object_unref (collection);
+		return NULL;
 	}
 
-	if (action)
-		g_object_ref (action);
-	g_object_unref (actions);
-	return action;
+	return SEAHORSE_LOCKABLE (collection);
 }
 
 static void
@@ -585,41 +557,46 @@ on_cell_renderer_action_icon (GtkTreeViewColumn *column,
 	gboolean highlight = FALSE;
 	GtkTreePath *path;
 	GdkPixbuf *pixbuf = NULL;
-	GtkAction *action;
-	gboolean is_lock = FALSE;
+	SeahorseLockable *lockable;
+	gboolean can_lock = FALSE;
+	gboolean can_unlock = FALSE;
 
-	action = lookup_relevant_action_for_iter (model, iter, &is_lock);
+	lockable = lookup_lockable_for_iter (model, iter);
 
-	if (action == NULL) {
-		g_object_set (cell,
-		              "visible", FALSE,
-		              "pixbuf", NULL,
-		              NULL);
-		return;
+	if (lockable) {
+		can_lock = seahorse_lockable_can_lock (lockable);
+		can_unlock = seahorse_lockable_can_unlock (lockable);
 	}
 
-	ensure_sidebar_pixbufs (self);
+	if (can_lock || can_unlock) {
+		ensure_sidebar_pixbufs (self);
 
-	pixbuf = NULL;
-	highlight = FALSE;
+		pixbuf = NULL;
+		highlight = FALSE;
 
-	if (self->action_highlight_path) {
-		path = gtk_tree_model_get_path (model, iter);
-		highlight = gtk_tree_path_compare (path, self->action_highlight_path) == 0;
-		gtk_tree_path_free (path);
-	}
+		if (self->action_highlight_path) {
+			path = gtk_tree_model_get_path (model, iter);
+			highlight = gtk_tree_path_compare (path, self->action_highlight_path) == 0;
+			gtk_tree_path_free (path);
+		}
 
-	if (is_lock)
-		pixbuf = highlight ? self->pixbuf_unlock : self->pixbuf_unlock_l;
-	else
-		pixbuf = highlight ? self->pixbuf_lock : self->pixbuf_lock_l;
+		if (can_lock)
+			pixbuf = highlight ? self->pixbuf_unlock : self->pixbuf_unlock_l;
+		else
+			pixbuf = highlight ? self->pixbuf_lock : self->pixbuf_lock_l;
 
-	g_object_set (cell,
-	              "visible", TRUE,
-	              "pixbuf", pixbuf,
-	              NULL);
+		g_object_set (cell,
+		              "visible", TRUE,
+		              "pixbuf", pixbuf,
+		              NULL);
+	} else {
+		g_object_set (cell,
+		              "visible", FALSE,
+		              "pixbuf", NULL,
+		              NULL);
+	}
 
-	g_object_unref (action);
+	g_clear_object (&lockable);
 }
 
 static void
@@ -963,19 +940,48 @@ on_tree_view_button_press_event (GtkWidget *widget,
 	return TRUE;
 }
 
+static void
+on_place_lock (GObject *source,
+               GAsyncResult *result,
+               gpointer user_data)
+{
+	GtkWindow *parent = GTK_WINDOW (user_data);
+	GError *error = NULL;
+
+	if (!seahorse_lockable_lock_finish (SEAHORSE_LOCKABLE (source), result, &error))
+		seahorse_util_handle_error (&error, parent, _("Couldn't lock"));
+
+	g_object_unref (parent);
+}
+
+static void
+on_place_unlock (GObject *source,
+                 GAsyncResult *result,
+                 gpointer user_data)
+{
+	GtkWindow *parent = GTK_WINDOW (user_data);
+	GError *error = NULL;
+
+	if (!seahorse_lockable_unlock_finish (SEAHORSE_LOCKABLE (source), result, &error))
+		seahorse_util_handle_error (&error, parent, _("Couldn't unlock"));
+
+	g_object_unref (parent);
+}
+
 static gboolean
 on_tree_view_button_release_event (GtkWidget *widget,
                                    GdkEventButton *event,
                                    gpointer user_data)
 {
 	SeahorseSidebar *self = SEAHORSE_SIDEBAR (user_data);
+	GTlsInteraction *interaction;
+	GCancellable *cancellable;
+	SeahorseLockable *lockable;
 	GtkTreePath *path;
-	GtkAction *action;
 	GtkTreeModel *model;
+	GtkWidget *window;
 	GtkTreeIter iter;
-	gboolean is_lock;
 	gboolean ret;
-	GtkWidget *window;
 
 	if (event->type != GDK_BUTTON_RELEASE)
 		return TRUE;
@@ -991,13 +997,24 @@ on_tree_view_button_release_event (GtkWidget *widget,
 	if (!ret)
 		return FALSE;
 
-	action = lookup_relevant_action_for_iter (model, &iter, &is_lock);
-	if (action == NULL)
-		return FALSE;
-
 	window = gtk_widget_get_toplevel (widget);
-	seahorse_action_activate_with_window (action, GTK_WINDOW (window));
-	g_object_unref (action);
+	cancellable = g_cancellable_new ();
+	interaction = seahorse_interaction_new (GTK_WINDOW (window));
+	ret = FALSE;
+
+	lockable = lookup_lockable_for_iter (model, &iter);
+	if (lockable) {
+		if (seahorse_lockable_can_lock (lockable)) {
+			seahorse_lockable_lock_async (lockable, interaction, cancellable,
+			                              on_place_lock, g_object_ref (window));
+		} else if (seahorse_lockable_can_unlock (lockable)) {
+			seahorse_lockable_unlock_async (lockable, interaction, cancellable,
+			                                on_place_unlock, g_object_ref (window));
+		}
+	}
+
+	g_object_unref (cancellable);
+	g_object_unref (interaction);
 
 	return TRUE;
 }



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