seahorse r2683 - in trunk: . gkr libseahorse pgp pkcs11 src ssh



Author: nnielsen
Date: Wed Dec 17 01:15:16 2008
New Revision: 2683
URL: http://svn.gnome.org/viewvc/seahorse?rev=2683&view=rev

Log:
	* libseahorse/seahorse-object.c:
	* gkr/seahorse-gkr-item.c:
	* gkr/seahorse-gkr-keyring.c: 
	* pgp/seahorse-pgp-uid.c: Allow 'tag' property to be directly set.
	This is useful for matching in predicates.
	
	* gkr/seahorse-gkr-item-commands.c:
	* gkr/seahorse-gkr-keyring-commands.c:
	* libseahorse/seahorse-types.h:
	* libseahorse/seahorse-view.c:
	* libseahorse/seahorse-view.h:
	* pgp/seahorse-pgp-commands.c:
	* pkcs11/seahorse-pkcs11-commands.c:
	* src/seahorse-key-manager.c:
	* src/seahorse-viewer.c:
	* src/seahorse-viewer.h:
	* ssh/seahorse-ssh-commansd.c: Use predicates to enable and disable 
	commands in the view. Fine tune exporting and deleting based on exportable and 
	deletable flags. Select objects being operated on, when not all 
	objects apply for the current operation. Hide commands that are not
	applicable for the currently selected objects. 
	

Modified:
   trunk/ChangeLog
   trunk/gkr/seahorse-gkr-item-commands.c
   trunk/gkr/seahorse-gkr-item.c
   trunk/gkr/seahorse-gkr-keyring-commands.c
   trunk/gkr/seahorse-gkr-keyring.c
   trunk/libseahorse/seahorse-object.c
   trunk/libseahorse/seahorse-types.h
   trunk/libseahorse/seahorse-view.c
   trunk/libseahorse/seahorse-view.h
   trunk/pgp/seahorse-pgp-commands.c
   trunk/pgp/seahorse-pgp-uid.c
   trunk/pkcs11/seahorse-pkcs11-commands.c
   trunk/src/seahorse-key-manager.c
   trunk/src/seahorse-viewer.c
   trunk/src/seahorse-viewer.h
   trunk/ssh/seahorse-ssh-commands.c

Modified: trunk/gkr/seahorse-gkr-item-commands.c
==============================================================================
--- trunk/gkr/seahorse-gkr-item-commands.c	(original)
+++ trunk/gkr/seahorse-gkr-item-commands.c	Wed Dec 17 01:15:16 2008
@@ -36,6 +36,8 @@
 
 G_DEFINE_TYPE (SeahorseGkrItemCommands, seahorse_gkr_item_commands, SEAHORSE_TYPE_COMMANDS);
 
+static SeahorseObjectPredicate commands_predicate = { 0, };
+
 /* -----------------------------------------------------------------------------
  * INTERNAL 
  */
@@ -102,7 +104,7 @@
 		base = SEAHORSE_COMMANDS (obj);
 		view = seahorse_commands_get_view (base);
 		g_return_val_if_fail (view, NULL);
-		seahorse_view_register_commands (view, base, SEAHORSE_TYPE_GKR_ITEM);
+		seahorse_view_register_commands (view, &commands_predicate, base);
 	}
 	
 	return obj;
@@ -126,6 +128,9 @@
 
 	cmd_class->show_properties = seahorse_gkr_item_commands_show_properties;
 	cmd_class->delete_objects = seahorse_gkr_item_commands_delete_objects;
+	
+	/* Setup the predicate that matches our commands */
+	commands_predicate.type = SEAHORSE_TYPE_GKR_ITEM;
 
 	/* Register this class as a commands */
 	seahorse_registry_register_type (seahorse_registry_get (), SEAHORSE_TYPE_GKR_ITEM_COMMANDS, 

Modified: trunk/gkr/seahorse-gkr-item.c
==============================================================================
--- trunk/gkr/seahorse-gkr-item.c	(original)
+++ trunk/gkr/seahorse-gkr-item.c	Wed Dec 17 01:15:16 2008
@@ -31,6 +31,7 @@
 #include "seahorse-util.h"
 #include "seahorse-secure-memory.h"
 
+#include "seahorse-gkr.h"
 #include "seahorse-gkr-item.h"
 #include "seahorse-gkr-operation.h"
 
@@ -540,7 +541,7 @@
 seahorse_gkr_item_init (SeahorseGkrItem *self)
 {
 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_GKR_ITEM, SeahorseGkrItemPrivate);
-	g_object_set (self, "usage", SEAHORSE_USAGE_CREDENTIALS, NULL);
+	g_object_set (self, "usage", SEAHORSE_USAGE_CREDENTIALS, "tag", SEAHORSE_GKR_TYPE, NULL);
 }
 
 static GObject* 

Modified: trunk/gkr/seahorse-gkr-keyring-commands.c
==============================================================================
--- trunk/gkr/seahorse-gkr-keyring-commands.c	(original)
+++ trunk/gkr/seahorse-gkr-keyring-commands.c	Wed Dec 17 01:15:16 2008
@@ -40,6 +40,8 @@
 
 G_DEFINE_TYPE (SeahorseGkrKeyringCommands, seahorse_gkr_keyring_commands, SEAHORSE_TYPE_COMMANDS);
 
+static SeahorseObjectPredicate commands_predicate = { 0, };
+
 /* -----------------------------------------------------------------------------
  * INTERNAL 
  */
@@ -101,7 +103,7 @@
 		base = SEAHORSE_COMMANDS (obj);
 		view = seahorse_commands_get_view (base);
 		g_return_val_if_fail (view, NULL);
-		seahorse_view_register_commands (view, base, SEAHORSE_TYPE_GKR_KEYRING);
+		seahorse_view_register_commands (view, &commands_predicate, base);
 	}
 	
 	return obj;
@@ -114,28 +116,6 @@
 }
 
 static void
-seahorse_gkr_keyring_commands_set_property (GObject *obj, guint prop_id, const GValue *value, 
-                           GParamSpec *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
-		break;
-	}
-}
-
-static void
-seahorse_gkr_keyring_commands_get_property (GObject *obj, guint prop_id, GValue *value, 
-                         	  GParamSpec *pspec)
-{
-	switch (prop_id) {
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
-		break;
-	}
-}
-
-static void
 seahorse_gkr_keyring_commands_class_init (SeahorseGkrKeyringCommandsClass *klass)
 {
 	GtkActionGroup *actions;
@@ -149,11 +129,13 @@
 	cmd_class->show_properties = seahorse_gkr_keyring_commands_show_properties;
 	cmd_class->delete_objects = seahorse_gkr_keyring_commands_delete_objects;
 
+	/* Setup the predicate for these commands */
+	commands_predicate.type = SEAHORSE_TYPE_GKR_KEYRING;
+	
 	/* Register this class as a commands */
 	seahorse_registry_register_type (seahorse_registry_get (), SEAHORSE_TYPE_GKR_KEYRING_COMMANDS, 
 	                                 SEAHORSE_GKR_TYPE_STR, "commands", NULL, NULL);
 	
-	
 	/* Register this as a generator */
 	actions = gtk_action_group_new ("gkr-generate");
 	gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);

Modified: trunk/gkr/seahorse-gkr-keyring.c
==============================================================================
--- trunk/gkr/seahorse-gkr-keyring.c	(original)
+++ trunk/gkr/seahorse-gkr-keyring.c	Wed Dec 17 01:15:16 2008
@@ -420,6 +420,7 @@
 seahorse_gkr_keyring_init (SeahorseGkrKeyring *self)
 {
 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_GKR_KEYRING, SeahorseGkrKeyringPrivate);
+	g_object_set (self, "tag", SEAHORSE_GKR_TYPE, NULL);
 }
 
 static void

Modified: trunk/libseahorse/seahorse-object.c
==============================================================================
--- trunk/libseahorse/seahorse-object.c	(original)
+++ trunk/libseahorse/seahorse-object.c	Wed Dec 17 01:15:16 2008
@@ -52,6 +52,7 @@
 struct _SeahorseObjectPrivate {
 	GQuark id;
 	GQuark tag;
+	gboolean tag_explicit;
 
 	SeahorseSource *source;
 	SeahorseContext *context;
@@ -154,7 +155,7 @@
 
 	/* No id, clear any tag and auto generated identifer */
 	if (!self->pv->id) {
-		if (self->pv->tag != 0) {
+		if (!self->pv->tag_explicit) {
 			self->pv->tag = 0;
 			g_object_notify (G_OBJECT (self), "tag");
 		}
@@ -170,13 +171,15 @@
 		len = strlen (str);
 		at = strchr (str, ':');
 		
-		result = g_strndup (str, at ? at - str : len);
-		tag = g_quark_from_string (result);
-		g_free (result);
-
-		if (tag != self->pv->tag) {
-			self->pv->tag = tag;
-			g_object_notify (G_OBJECT (self), "tag");
+		if (!self->pv->tag_explicit) {
+			result = g_strndup (str, at ? at - str : len);
+			tag = g_quark_from_string (result);
+			g_free (result);
+			
+			if (tag != self->pv->tag) {
+				self->pv->tag = tag;
+				g_object_notify (G_OBJECT (self), "tag");
+			}
 		}
 		
 		if (!self->pv->identifier_explicit) {
@@ -399,7 +402,7 @@
 	SeahorseLocation loc;
 	SeahorseUsage usage;
 	guint flags;
-	GQuark id;
+	GQuark quark;
 	
 	switch (prop_id) {
 	case PROP_CONTEXT:
@@ -420,15 +423,23 @@
 		seahorse_object_set_parent (self, SEAHORSE_OBJECT (g_value_get_object (value)));
 		break;
 	case PROP_ID:
-		id = g_value_get_uint (value);
-		if (id != self->pv->id) {
-			self->pv->id = id;
+		quark = g_value_get_uint (value);
+		if (quark != self->pv->id) {
+			self->pv->id = quark;
 			g_object_freeze_notify (obj);
 			g_object_notify (obj, "id");
 			recalculate_id (self);
 			g_object_thaw_notify (obj);
 		}
 		break;
+	case PROP_TAG:
+		quark = g_value_get_uint (value);
+		if (quark != self->pv->tag) {
+			self->pv->tag = quark;
+			self->pv->tag_explicit = TRUE;
+			g_object_notify (obj, "tag");
+		}
+		break;
 	case PROP_LABEL:
 		if (set_string_storage (g_value_get_string (value), &self->pv->label)) {
 			g_object_freeze_notify (obj);
@@ -484,7 +495,9 @@
 		break;
 	case PROP_FLAGS:
 		flags = g_value_get_uint (value);
-		if (!SEAHORSE_OBJECT_GET_CLASS (obj)->delete)
+		if (SEAHORSE_OBJECT_GET_CLASS (obj)->delete)
+			flags |= SEAHORSE_FLAG_DELETABLE;
+		else 
 			flags &= ~SEAHORSE_FLAG_DELETABLE;
 		if (flags != self->pv->flags) {
 			self->pv->flags = flags;
@@ -555,7 +568,7 @@
 	
 	g_object_class_install_property (gobject_class, PROP_TAG,
 	           g_param_spec_uint ("tag", "Object Type Tag", "This object's type tag.", 
-	                              0, G_MAXUINT, 0, G_PARAM_READABLE));
+	                              0, G_MAXUINT, 0, G_PARAM_READWRITE));
 	
 	g_object_class_install_property (gobject_class, PROP_LABEL,
 	           g_param_spec_string ("label", "Object Display Label", "This object's displayable label.", 

Modified: trunk/libseahorse/seahorse-types.h
==============================================================================
--- trunk/libseahorse/seahorse-types.h	(original)
+++ trunk/libseahorse/seahorse-types.h	Wed Dec 17 01:15:16 2008
@@ -70,7 +70,7 @@
 	SEAHORSE_FLAG_DISABLED =    CRYPTUI_FLAG_DISABLED,
 	SEAHORSE_FLAG_TRUSTED =     CRYPTUI_FLAG_TRUSTED,
 	SEAHORSE_FLAG_EXPORTABLE =  CRYPTUI_FLAG_EXPORTABLE,
-	SEAHORSE_FLAG_DELETABLE = 1000
+	SEAHORSE_FLAG_DELETABLE = 0x10000000
 } SeahorseKeyFlags;
 
 #define SEAHORSE_TAG_INVALID               0

Modified: trunk/libseahorse/seahorse-view.c
==============================================================================
--- trunk/libseahorse/seahorse-view.c	(original)
+++ trunk/libseahorse/seahorse-view.c	Wed Dec 17 01:15:16 2008
@@ -37,6 +37,13 @@
 }
 
 
+GList*
+seahorse_view_get_selected_matching (SeahorseView *self, SeahorseObjectPredicate *pred)
+{
+	g_return_val_if_fail (SEAHORSE_VIEW_GET_INTERFACE (self)->get_selected_matching, NULL);
+	return SEAHORSE_VIEW_GET_INTERFACE (self)->get_selected_matching (self, pred);
+}
+
 SeahorseObject* 
 seahorse_view_get_selected (SeahorseView* self) 
 {
@@ -69,19 +76,19 @@
 }
 
 void
-seahorse_view_register_commands (SeahorseView *self, SeahorseCommands *commands, 
-                                 GType for_type)
+seahorse_view_register_commands (SeahorseView *self, SeahorseObjectPredicate *pred,
+                                 SeahorseCommands *commands)
 {
 	g_return_if_fail (SEAHORSE_VIEW_GET_INTERFACE (self)->register_commands);
-	return SEAHORSE_VIEW_GET_INTERFACE (self)->register_commands (self, commands, for_type);
+	return SEAHORSE_VIEW_GET_INTERFACE (self)->register_commands (self, pred, commands);
 }
 
 void
-seahorse_view_register_ui (SeahorseView *self, const gchar *ui_definition, 
-                           GtkActionGroup *actions)
+seahorse_view_register_ui (SeahorseView *self, SeahorseObjectPredicate *pred, 
+                           const gchar *ui_definition, GtkActionGroup *actions)
 {
 	g_return_if_fail (SEAHORSE_VIEW_GET_INTERFACE (self)->register_ui);
-	return SEAHORSE_VIEW_GET_INTERFACE (self)->register_ui (self, ui_definition, actions);
+	return SEAHORSE_VIEW_GET_INTERFACE (self)->register_ui (self, pred, ui_definition, actions);
 }
 
 static void 
@@ -126,6 +133,3 @@
 	return seahorse_view_type_id;
 }
 
-
-
-

Modified: trunk/libseahorse/seahorse-view.h
==============================================================================
--- trunk/libseahorse/seahorse-view.h	(original)
+++ trunk/libseahorse/seahorse-view.h	Wed Dec 17 01:15:16 2008
@@ -44,20 +44,28 @@
 	/* virtual metdods */
 	GList*          (*get_selected_objects)   (SeahorseView *self);
 	
-	void            (*set_selected_objects)   (SeahorseView *self, GList *objects);
+	void            (*set_selected_objects)   (SeahorseView *self, 
+	                                           GList *objects);
+	
+	GList*          (*get_selected_matching)  (SeahorseView *self, 
+	                                           SeahorseObjectPredicate *pred);
 	
 	SeahorseObject* (*get_selected)           (SeahorseView *self);
 	
-	void            (*set_selected)           (SeahorseView *self, SeahorseObject *value);
+	void            (*set_selected)           (SeahorseView *self, 
+	                                           SeahorseObject *value);
 	
 	SeahorseSet*    (*get_current_set)        (SeahorseView *self);
 	
 	GtkWindow*      (*get_window)             (SeahorseView *self);
 	
-	void            (*register_commands)      (SeahorseView *self, SeahorseCommands *commands,
-	                                           GType for_type);
-	
-	void            (*register_ui)            (SeahorseView *self, const gchar *ui_definition,
+	void            (*register_commands)      (SeahorseView *self, 
+	                                           SeahorseObjectPredicate *pred,
+	                                           SeahorseCommands *commands);
+	
+	void            (*register_ui)            (SeahorseView *self, 
+	                                           SeahorseObjectPredicate *pred, 
+	                                           const gchar *ui_definition, 
 	                                           GtkActionGroup *actions);
 };
 
@@ -66,22 +74,28 @@
 
 GList*            seahorse_view_get_selected_objects        (SeahorseView *self);
 
-void              seahorse_view_set_selected_objects        (SeahorseView *self, GList *objects);
+void              seahorse_view_set_selected_objects        (SeahorseView *self, 
+                                                             GList *objects);
+
+GList*            seahorse_view_get_selected_matching       (SeahorseView *self, 
+                                                             SeahorseObjectPredicate *pred);
 
 SeahorseObject*   seahorse_view_get_selected                (SeahorseView *self);
 
-void              seahorse_view_set_selected                (SeahorseView *self, SeahorseObject *value);
+void              seahorse_view_set_selected                (SeahorseView *self, 
+                                                             SeahorseObject *value);
 
 SeahorseSet*      seahorse_view_get_current_set             (SeahorseView *self);
 
 GtkWindow*        seahorse_view_get_window                  (SeahorseView *self);
 
 void              seahorse_view_register_ui                 (SeahorseView *self, 
+                                                             SeahorseObjectPredicate *pred,
                                                              const gchar *ui_definition,
                                                              GtkActionGroup *actions);
 
 void              seahorse_view_register_commands           (SeahorseView *self, 
-                                                             SeahorseCommands *commands,
-                                                             GType for_type);
+                                                             SeahorseObjectPredicate *pred,
+                                                             SeahorseCommands *commands);
 
 #endif

Modified: trunk/pgp/seahorse-pgp-commands.c
==============================================================================
--- trunk/pgp/seahorse-pgp-commands.c	(original)
+++ trunk/pgp/seahorse-pgp-commands.c	Wed Dec 17 01:15:16 2008
@@ -64,6 +64,9 @@
 "	</popup>"\
 "</ui>";
 
+static SeahorseObjectPredicate actions_predicate = { 0 };
+static SeahorseObjectPredicate commands_predicate = { 0 };
+
 /* -----------------------------------------------------------------------------
  * INTERNAL 
  */
@@ -71,46 +74,29 @@
 static void 
 on_key_sign (GtkAction* action, SeahorsePgpCommands* self) 
 {
-	SeahorseObject* key;
+	SeahorseView *view;
+	GtkWindow *window;
+	GList *keys;
 
 	g_return_if_fail (SEAHORSE_IS_PGP_COMMANDS (self));
 	g_return_if_fail (GTK_IS_ACTION (action));
 	
-	key = seahorse_view_get_selected (seahorse_commands_get_view (SEAHORSE_COMMANDS (self)));
+	view = seahorse_commands_get_view (SEAHORSE_COMMANDS (self));
+	keys = seahorse_view_get_selected_matching (view, &actions_predicate);
 	
-	if (key == NULL)
+	if (keys == NULL)
 		return;
 
-	if (G_TYPE_FROM_INSTANCE (key) == SEAHORSE_TYPE_GPGME_KEY) {
-		seahorse_gpgme_sign_prompt (SEAHORSE_GPGME_KEY (key), seahorse_commands_get_window (SEAHORSE_COMMANDS (self)));
-	} else if (G_TYPE_FROM_INSTANCE (key) == SEAHORSE_TYPE_GPGME_UID) {
-		seahorse_gpgme_sign_prompt_uid (SEAHORSE_GPGME_UID (key), seahorse_commands_get_window (SEAHORSE_COMMANDS (self)));
-	}
-}
+	/* Indicate what we're actually going to operate on */
+	seahorse_view_set_selected (view, keys->data);
 
-static void 
-on_view_selection_changed (SeahorseView* view, SeahorsePgpCommands* self) 
-{
-	GList* keys, *l;
-	gboolean enable;
+	window = seahorse_commands_get_window (SEAHORSE_COMMANDS (self));
 	
-	g_return_if_fail (SEAHORSE_IS_PGP_COMMANDS (self));
-	g_return_if_fail (SEAHORSE_IS_VIEW (view));
-	
-	keys = seahorse_view_get_selected_objects (view);
-	enable = (keys != NULL);
-
-	for (l = keys; l; l = g_list_next (l)) {
-		SeahorseObject* key = SEAHORSE_OBJECT (l->data);
-		if (G_OBJECT_TYPE (key) != SEAHORSE_TYPE_GPGME_KEY && 
-		    G_OBJECT_TYPE (key) != SEAHORSE_TYPE_GPGME_UID) {
-			enable = FALSE;
-			break;
-		}
+	if (G_TYPE_FROM_INSTANCE (keys->data) == SEAHORSE_TYPE_GPGME_KEY) {
+		seahorse_gpgme_sign_prompt (SEAHORSE_GPGME_KEY (keys->data), window);
+	} else if (G_TYPE_FROM_INSTANCE (keys->data) == SEAHORSE_TYPE_GPGME_UID) {
+		seahorse_gpgme_sign_prompt_uid (SEAHORSE_GPGME_UID (keys->data), window);
 	}
-
-	gtk_action_group_set_sensitive (self->pv->command_actions, enable);
-	g_list_free (keys);
 }
 
 static const GtkActionEntry COMMAND_ENTRIES[] = {
@@ -226,18 +212,14 @@
 	
 		view = seahorse_commands_get_view (base);
 		g_return_val_if_fail (view, NULL);
-		g_signal_connect (view, "selection-changed", G_CALLBACK (on_view_selection_changed), self);
 		
 		self->pv->command_actions = gtk_action_group_new ("pgp");
 		gtk_action_group_set_translation_domain (self->pv->command_actions, GETTEXT_PACKAGE);
 		gtk_action_group_add_actions (self->pv->command_actions, COMMAND_ENTRIES, 
 		                              G_N_ELEMENTS (COMMAND_ENTRIES), self);
 		
-		seahorse_view_register_commands (view, base, SEAHORSE_TYPE_PGP_KEY);
-		seahorse_view_register_commands (view, base, SEAHORSE_TYPE_PGP_UID);
-		seahorse_view_register_commands (view, base, SEAHORSE_TYPE_GPGME_KEY);
-		seahorse_view_register_commands (view, base, SEAHORSE_TYPE_GPGME_UID);
-		seahorse_view_register_ui (view, UI_DEFINITION, self->pv->command_actions);
+		seahorse_view_register_commands (view, &commands_predicate, base);
+		seahorse_view_register_ui (view, &actions_predicate, UI_DEFINITION, self->pv->command_actions);
 	}
 	
 	return obj;
@@ -311,6 +293,11 @@
 	SEAHORSE_COMMANDS_CLASS (klass)->show_properties = seahorse_pgp_commands_show_properties;
 	SEAHORSE_COMMANDS_CLASS (klass)->delete_objects = seahorse_pgp_commands_delete_objects;
 	
+	/* Setup predicate for matching entries for these commands */
+	commands_predicate.tag = SEAHORSE_PGP_TYPE;
+	actions_predicate.tag = SEAHORSE_PGP_TYPE;
+	actions_predicate.location = SEAHORSE_LOCATION_LOCAL;
+
 	/* Register this class as a commands */
 	seahorse_registry_register_type (seahorse_registry_get (), SEAHORSE_TYPE_PGP_COMMANDS, 
 	                                 SEAHORSE_PGP_TYPE_STR, "commands", NULL, NULL);

Modified: trunk/pgp/seahorse-pgp-uid.c
==============================================================================
--- trunk/pgp/seahorse-pgp-uid.c	(original)
+++ trunk/pgp/seahorse-pgp-uid.c	Wed Dec 17 01:15:16 2008
@@ -221,6 +221,7 @@
 {
 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_PGP_UID, SeahorsePgpUidPrivate);
 	g_object_set (self, "icon", "", "usage", SEAHORSE_USAGE_IDENTITY, NULL);
+	g_object_set (self, "tag", SEAHORSE_PGP_TYPE, NULL);
 }
 
 static void

Modified: trunk/pkcs11/seahorse-pkcs11-commands.c
==============================================================================
--- trunk/pkcs11/seahorse-pkcs11-commands.c	(original)
+++ trunk/pkcs11/seahorse-pkcs11-commands.c	Wed Dec 17 01:15:16 2008
@@ -47,6 +47,8 @@
 #define SEAHORSE_PKCS11_COMMANDS_GET_PRIVATE(o) \
 	(G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_TYPE_COMMANDS, SeahorsePkcs11CommandsPrivate))
 
+static SeahorseObjectPredicate commands_predicate = { 0, };
+
 /* -----------------------------------------------------------------------------
  * INTERNAL 
  */
@@ -106,7 +108,7 @@
 		display = seahorse_object_get_label (SEAHORSE_OBJECT (objects->data));
 		prompt = g_strdup_printf (_("Are you sure you want to delete the certificate '%s'?"), display);
 	} else {
-		prompt = g_strdup_printf (_("Are you sure you want to delete %d secure shell keys?"), num);
+		prompt = g_strdup_printf (_("Are you sure you want to delete %d certificates?"), num);
 	}
 	
 	ret = seahorse_util_prompt_delete (prompt, GTK_WIDGET (seahorse_view_get_window (seahorse_commands_get_view (cmds))));
@@ -135,8 +137,8 @@
 		view = seahorse_commands_get_view (base);
 		g_return_val_if_fail (view, NULL);
 		
-		seahorse_view_register_commands (view, base, SEAHORSE_PKCS11_TYPE_CERTIFICATE);
-		seahorse_view_register_ui (view, "", pv->action_group);
+		seahorse_view_register_commands (view, &commands_predicate, base);
+		seahorse_view_register_ui (view, &commands_predicate, "", pv->action_group);
 	}
 	
 	return obj;
@@ -215,6 +217,8 @@
 
 	slot_certificate_window = g_quark_from_static_string ("seahorse-pkcs11-commands-window");
 
+	commands_predicate.type = SEAHORSE_PKCS11_TYPE_CERTIFICATE;
+		
 	/* Register this as a source of commands */
 	seahorse_registry_register_type (seahorse_registry_get (), SEAHORSE_PKCS11_TYPE_COMMANDS, 
 	                                 SEAHORSE_PKCS11_TYPE_STR, "commands", NULL);

Modified: trunk/src/seahorse-key-manager.c
==============================================================================
--- trunk/src/seahorse-key-manager.c	(original)
+++ trunk/src/seahorse-key-manager.c	Wed Dec 17 01:15:16 2008
@@ -33,6 +33,8 @@
 #include "seahorse-progress.h"
 #include "seahorse-util.h"
 
+#include "gkr/seahorse-gkr.h"
+
 #include <glib/gi18n.h>
 
 enum {
@@ -70,7 +72,7 @@
 	TAB_NUM_TABS
 } SeahorseKeyManagerTabs;
 
-static const SeahorseObjectPredicate PRED_PUBLIC = {
+static SeahorseObjectPredicate pred_public = {
 	0, 
 	0, 
 	0, 
@@ -81,7 +83,7 @@
 	NULL 
 };
 
-static const SeahorseObjectPredicate PRED_TRUSTED = {
+static SeahorseObjectPredicate pred_trusted = {
 	0, 
 	0, 
 	0, 
@@ -92,7 +94,7 @@
 	NULL
 };
 
-static const SeahorseObjectPredicate PRED_PRIVATE = {
+static SeahorseObjectPredicate pred_private = {
 	0, 
 	0, 
 	0, 
@@ -103,12 +105,12 @@
 	NULL
 };
 
-static const SeahorseObjectPredicate PRED_PASSWORD = {
-	0, 
+static SeahorseObjectPredicate pred_password = {
 	0, 
+	0, /* Tag filled in later */ 
 	0, 
 	SEAHORSE_LOCATION_LOCAL, 
-	SEAHORSE_USAGE_CREDENTIALS, 
+	0, 
 	0, 
 	0, 
 	NULL
@@ -967,10 +969,11 @@
 	                         G_CALLBACK (on_filter_changed), self, 0);
 	
 	/* Initialize the tabs, and associate them up */
-	initialize_tab (self, "pub-key-tab", TAB_PUBLIC, "pub-key-list", &PRED_PUBLIC);
-	initialize_tab (self, "trust-key-tab", TAB_TRUSTED, "trust-key-list", &PRED_TRUSTED);
-	initialize_tab (self, "sec-key-tab", TAB_PRIVATE, "sec-key-list", &PRED_PRIVATE);
-	initialize_tab (self, "password-tab", TAB_PASSWORD, "password-list", &PRED_PASSWORD);
+	initialize_tab (self, "pub-key-tab", TAB_PUBLIC, "pub-key-list", &pred_public);
+	initialize_tab (self, "trust-key-tab", TAB_TRUSTED, "trust-key-list", &pred_trusted);
+	initialize_tab (self, "sec-key-tab", TAB_PRIVATE, "sec-key-list", &pred_private);
+	pred_password.tag = SEAHORSE_GKR_TYPE;
+	initialize_tab (self, "password-tab", TAB_PASSWORD, "password-list", &pred_password);
 	
 	/* Set focus to the current key list */
 	widget = GTK_WIDGET (get_current_view (self));

Modified: trunk/src/seahorse-viewer.c
==============================================================================
--- trunk/src/seahorse-viewer.c	(original)
+++ trunk/src/seahorse-viewer.c	Wed Dec 17 01:15:16 2008
@@ -42,12 +42,19 @@
 	PROP_WINDOW
 };
 
+typedef struct _ViewerPredicate {
+	SeahorseObjectPredicate pred;
+	gboolean is_commands;
+	GObject *commands_or_actions;
+} ViewerPredicate;
+
 struct _SeahorseViewerPrivate {
 	GtkUIManager *ui_manager;
 	GtkActionGroup *object_actions;
 	GtkActionGroup *export_actions;
+	GtkAction *delete_action;
+	GArray *predicates;
 	GList *all_commands;
-	GHashTable *commands;
 };
 
 static void seahorse_viewer_implement_view (SeahorseViewIface *iface);
@@ -59,10 +66,35 @@
 
 static gboolean about_initialized = FALSE;
 
+/* Predicates which control export and delete commands, inited in class_init */
+static SeahorseObjectPredicate exportable_predicate = { 0, };
+static SeahorseObjectPredicate deletable_predicate = { 0, };
+
 /* -----------------------------------------------------------------------------
  * INTERNAL 
  */
 
+typedef gboolean (*ForEachCommandsFunc) (SeahorseViewer *self, SeahorseCommands *commands, 
+                                         SeahorseObjectPredicate *predicate, gpointer user_data);
+
+static void
+for_each_commands (SeahorseViewer *self, ForEachCommandsFunc func, gpointer user_data)
+{
+	SeahorseViewerPrivate *pv = SEAHORSE_VIEWER_GET_PRIVATE (self);
+	ViewerPredicate *predicate;
+	guint i;
+	
+	for (i = 0; i < pv->predicates->len; ++i)
+	{
+		predicate = &g_array_index (pv->predicates, ViewerPredicate, i);
+		if (predicate->is_commands) {
+			if (!(func) (self, SEAHORSE_COMMANDS (predicate->commands_or_actions), 
+			            &predicate->pred, user_data))
+				return;
+		}
+	}
+}
+
 static void 
 on_app_preferences (GtkAction* action, SeahorseViewer* self) 
 {
@@ -194,6 +226,48 @@
 	return exportable;
 }
 
+static GList*
+filter_matching_objects (SeahorseObjectPredicate *pred, GList** all_objects)
+{
+	GList *results, *next, *here;
+	SeahorseObject *object;
+	
+	results = NULL;
+	
+	next = *all_objects;
+	while ((here = next) != NULL) {
+		g_return_val_if_fail (SEAHORSE_IS_OBJECT (here->data), NULL);
+		object = SEAHORSE_OBJECT (here->data);
+		next = g_list_next (here);
+
+		/* If it matches then separate it */
+		if (seahorse_object_predicate_match (pred, object)) {
+			results = g_list_append (results, object);
+			*all_objects = g_list_delete_link (*all_objects, here);
+		}
+	}
+	
+	return results;
+}
+
+static gboolean
+has_matching_objects (SeahorseObjectPredicate *pred, GList *objects)
+{
+	SeahorseObject *object;
+	GList *l;
+
+	for (l = objects; l; l = g_list_next (l)) {
+		g_return_val_if_fail (SEAHORSE_IS_OBJECT (l->data), FALSE);
+		object = SEAHORSE_OBJECT (l->data);
+
+		/* If it matches then separate it */
+		if (seahorse_object_predicate_match (pred, object)) 
+			return TRUE;
+	}
+	
+	return FALSE;
+}
+
 static void 
 on_export_done (SeahorseOperation* op, SeahorseViewer* self) 
 {
@@ -310,26 +384,6 @@
 	g_object_unref (op);
 }
 
-static gint 
-compare_by_tag (SeahorseObject* one, SeahorseObject* two, SeahorseViewer* self) 
-{
-	GQuark kone;
-	GQuark ktwo;
-	
-	g_return_val_if_fail (SEAHORSE_IS_VIEWER (self), 0);
-	g_return_val_if_fail (SEAHORSE_IS_OBJECT (one), 0);
-	g_return_val_if_fail (SEAHORSE_IS_OBJECT (two), 0);
-	
-	kone = seahorse_object_get_tag (one);
-	ktwo = seahorse_object_get_tag (two);
-	
-	if (kone < ktwo)
-		return -1;
-	if (kone > ktwo)
-		return 1;
-	return 0;
-}
-
 static void 
 on_delete_complete (SeahorseOperation* op, SeahorseViewer* self) 
 {
@@ -341,48 +395,57 @@
 		                                  GTK_WIDGET (seahorse_view_get_window (SEAHORSE_VIEW (self))));
 }
 
-static void 
-delete_object_batch (SeahorseViewer* self, GList* objects) 
+static gboolean
+delete_objects_for_selected (SeahorseViewer *self, SeahorseCommands *commands, 
+                             SeahorseObjectPredicate *pred, gpointer user_data)
 {
-	SeahorseViewerPrivate *pv = SEAHORSE_VIEWER_GET_PRIVATE (self);
-	SeahorseCommands* commands;
 	SeahorseOperation* op;
-
-	g_return_if_fail (SEAHORSE_IS_VIEWER (self));
-	g_return_if_fail (objects != NULL);
-	g_assert (objects != NULL);
+	GList **all_objects;
+	GList *objects;
+	
+	all_objects = (GList**)user_data;
+	
+	/* Stop the enumeration if nothing still selected */
+	if (!*all_objects)
+		return FALSE;
+	
+	objects = filter_matching_objects (pred, all_objects);
+	
+	/* No objects matched this predicate? */
+	if (!objects) 
+		return TRUE;
+	
+	/* Indicate to our users what is being operated on */
+	seahorse_viewer_set_selected_objects (self, objects);
 	
-	commands = g_hash_table_lookup (pv->commands, GINT_TO_POINTER (G_OBJECT_TYPE (objects->data)));
-	if (commands == NULL)
-		return;
-
 	op = seahorse_commands_delete_objects (commands, objects);
-	if (op != NULL) {
-		seahorse_progress_show (op, _ ("Deleting..."), TRUE);
-		seahorse_operation_watch (op, (SeahorseDoneFunc)on_delete_complete, self, NULL, NULL);
-		g_object_unref (op);
-	}
+	g_list_free (objects);
+	
+	/* Did the user cancel? */
+	if (op == NULL)
+		return FALSE;
+
+	seahorse_progress_show (op, _ ("Deleting..."), TRUE);
+	seahorse_operation_watch (op, (SeahorseDoneFunc)on_delete_complete, self, NULL, NULL);
+	g_object_unref (op);
+	
+	return TRUE;
 }
 
 static void
 on_key_delete (GtkAction* action, SeahorseViewer* self) 
 {
 	GList *objects = NULL;
-	GList *batch = NULL;
-	GQuark ktype = 0;
+	GList *all_objects = NULL;
 	GList *l;
 	guint num;
 
 	g_return_if_fail (SEAHORSE_IS_VIEWER (self));
 	g_return_if_fail (GTK_IS_ACTION (action));
-	
-	/* Get the selected objects and sort them by ktype */
-	objects = seahorse_viewer_get_selected_objects (self);
-	objects = g_list_sort (objects, (GCompareFunc)compare_by_tag);
-	
-	num = g_list_length (objects);
-	if (num == 0)
-		return;
+
+	all_objects = seahorse_viewer_get_selected_objects (self);
+	objects = filter_matching_objects (&deletable_predicate, &all_objects);
+	g_list_free (all_objects);
 
 	/* Check for private objects */
 	for (l = objects; l; l = g_list_next (l)) {
@@ -404,32 +467,31 @@
 		}
 	}
 	
-	batch = NULL;
-	for (l = objects; l; l = g_list_next (l)) {
-		SeahorseObject* object = SEAHORSE_OBJECT (l->data);
-
-		/* Process that batch */
-		if (ktype != seahorse_object_get_tag (object) && batch != NULL) {
-			delete_object_batch (self, batch);
-			g_list_free (batch);
-			batch = NULL;
-		}
-		
-		/* Add to the batch */
-		batch = g_list_prepend (batch, object);
-	}
-
-	/* Process last batch */
-	if (batch != NULL)
-		delete_object_batch (self, batch);
+	/* Go through the list of predicates, and call each one */
+	for_each_commands (self, delete_objects_for_selected, &objects);
 
 	g_list_free (objects);
-	g_list_free (batch);
+}
+
+static gboolean
+show_properties_for_selected (SeahorseViewer *self, SeahorseCommands *commands, 
+                              SeahorseObjectPredicate *pred, gpointer user_data)
+{
+	g_return_val_if_fail (SEAHORSE_IS_OBJECT (user_data), FALSE);
+	
+	/* If not mactched, then continue enumeration */
+	if (!seahorse_object_predicate_match (pred, user_data))
+		return TRUE;
+	
+	seahorse_commands_show_properties (commands, user_data);
+	
+	/* Stop enumeration */
+	return FALSE;
 }
 		
 static const GtkActionEntry KEY_ENTRIES[] = {
 	{ "show-properties", GTK_STOCK_PROPERTIES, N_("P_roperties"), NULL,
-	  N_("Show properties"), G_CALLBACK (on_key_properties) }, 
+	  N_("Show properties"), G_CALLBACK (on_key_properties) },
 	{ "edit-delete", GTK_STOCK_DELETE, N_("_Delete"), NULL,
 	  N_("Delete selected items"), G_CALLBACK (on_key_delete) }
 };
@@ -461,6 +523,9 @@
 	/* Mark the properties toolbar button as important */
 	g_object_set (gtk_action_group_get_action (pv->object_actions, "show-properties"), "is-important", TRUE, NULL);
 	seahorse_viewer_include_actions (self, pv->object_actions);
+	pv->delete_action = gtk_action_group_get_action (pv->object_actions, "edit-delete");
+	g_return_if_fail (pv->delete_action);
+	g_object_ref (pv->delete_action);
 	
 	pv->export_actions = gtk_action_group_new ("export");
 	gtk_action_group_set_translation_domain (pv->export_actions, GETTEXT_PACKAGE);
@@ -472,8 +537,9 @@
 on_selection_changed (SeahorseView* view, SeahorseViewer* self) 
 {
 	SeahorseViewerPrivate *pv = SEAHORSE_VIEWER_GET_PRIVATE (self);
-	gboolean exportable = FALSE;
+	ViewerPredicate *predicate;
 	GList *objects;
+	guint i;
 	
 	g_return_if_fail (SEAHORSE_IS_VIEWER (self));
 	g_return_if_fail (SEAHORSE_IS_VIEW (view));
@@ -482,12 +548,25 @@
 	gtk_action_group_set_sensitive (pv->object_actions, seahorse_view_get_selected (view) != NULL);
 	
 	objects = seahorse_viewer_get_selected_objects (self);
-	objects = objects_prune_non_exportable (objects);
-	exportable = (objects != NULL);
-	g_list_free (objects);
 	
 	/* Enable if any exportable objects are selected */
-	gtk_action_group_set_sensitive (pv->export_actions, exportable);
+	gtk_action_group_set_sensitive (pv->export_actions, 
+	                                has_matching_objects (&exportable_predicate, objects));
+	
+	/* Enable if any deletable objects are selected */
+	gtk_action_set_sensitive (pv->delete_action, 
+	                          has_matching_objects (&deletable_predicate, objects));
+	
+	/* Go through the list of actions and disable all those which have no matches */
+	for (i = 0; i < pv->predicates->len; ++i) {
+		predicate = &g_array_index (pv->predicates, ViewerPredicate, i);
+		if (predicate->is_commands)
+			continue;
+		gtk_action_group_set_visible (GTK_ACTION_GROUP (predicate->commands_or_actions),
+		                              has_matching_objects (&predicate->pred, objects));
+	}
+	
+	g_list_free (objects);
 }
 
 static void 
@@ -519,6 +598,22 @@
  * OBJECT 
  */
 
+static GList*
+seahorse_viewer_get_selected_matching (SeahorseView *base, SeahorseObjectPredicate *pred)
+{
+	GList *all_objects;
+	GList *objects;
+	
+	g_return_val_if_fail (SEAHORSE_IS_VIEW (base), NULL);
+	g_return_val_if_fail (pred, NULL);
+	
+	all_objects = seahorse_view_get_selected_objects (base);
+	objects = filter_matching_objects (pred, &all_objects);
+	g_list_free (all_objects);
+	
+	return objects;
+}
+
 static GObject* 
 seahorse_viewer_constructor (GType type, guint n_props, GObjectConstructParam *props) 
 {
@@ -579,14 +674,16 @@
 	pv->ui_manager = gtk_ui_manager_new ();
 	g_signal_connect (pv->ui_manager, "add-widget", G_CALLBACK (on_add_widget), self);
 
-	pv->commands = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);	
+	pv->predicates = g_array_new (FALSE, TRUE, sizeof (ViewerPredicate));
 }
 
 static void
 seahorse_viewer_dispose (GObject *obj)
 {
 	SeahorseViewerPrivate *pv = SEAHORSE_VIEWER_GET_PRIVATE (obj);
-
+	ViewerPredicate *predicate;
+	guint i;
+	
 	if (pv->ui_manager)
 		g_object_unref (pv->ui_manager);
 	pv->ui_manager = NULL;
@@ -599,9 +696,15 @@
 		g_object_unref (pv->export_actions);
 	pv->export_actions = NULL;
 	
-	if (pv->commands)
-		g_hash_table_destroy (pv->commands);
-	pv->commands = NULL;
+	if (pv->delete_action)
+		g_object_unref (pv->delete_action);
+	pv->delete_action = NULL;
+
+	for (i = 0; i < pv->predicates->len; ++i) {
+		predicate = &g_array_index (pv->predicates, ViewerPredicate, i);
+		g_object_unref (predicate->commands_or_actions);
+	}
+	g_array_set_size (pv->predicates, 0);
 	
 	seahorse_object_list_free (pv->all_commands);
 	pv->all_commands = NULL;
@@ -616,8 +719,10 @@
 	
 	g_assert (pv->object_actions == NULL);
 	g_assert (pv->export_actions == NULL);
-	g_assert (pv->commands == NULL);
+	g_assert (pv->delete_action == NULL);
+	g_assert (pv->all_commands == NULL);
 	g_assert (pv->ui_manager == NULL);
+	g_array_free (pv->predicates, TRUE);
 
 	G_OBJECT_CLASS (seahorse_viewer_parent_class)->finalize (obj);
 }
@@ -685,6 +790,9 @@
 	g_object_class_install_property (gobject_class, PROP_CURRENT_SET,
 	           g_param_spec_object ("current-set", "Current Set", "Currently visible set of objects",
 	                                SEAHORSE_TYPE_SET, G_PARAM_READABLE));
+	
+	exportable_predicate.flags = SEAHORSE_FLAG_EXPORTABLE;
+	deletable_predicate.flags = SEAHORSE_FLAG_DELETABLE;
 }
 
 static void 
@@ -694,6 +802,7 @@
 	iface->set_selected_objects = (gpointer)seahorse_viewer_set_selected_objects;
 	iface->get_selected = (gpointer)seahorse_viewer_get_selected;
 	iface->set_selected = (gpointer)seahorse_viewer_set_selected;
+	iface->get_selected_matching = (gpointer)seahorse_viewer_get_selected_matching;
 	iface->get_current_set = (gpointer)seahorse_viewer_get_current_set;
 	iface->get_window = (gpointer)seahorse_viewer_get_window;
 	iface->register_ui = (gpointer)seahorse_viewer_register_ui;
@@ -768,15 +877,10 @@
 void
 seahorse_viewer_show_properties (SeahorseViewer* self, SeahorseObject* obj)
 {
-	SeahorseViewerPrivate *pv = SEAHORSE_VIEWER_GET_PRIVATE (self);
-	SeahorseCommands* commands;
-
 	g_return_if_fail (SEAHORSE_IS_VIEWER (self));
 	g_return_if_fail (SEAHORSE_IS_OBJECT (obj));
 	
-	commands = SEAHORSE_COMMANDS (g_hash_table_lookup (pv->commands, GINT_TO_POINTER (G_OBJECT_TYPE (obj))));
-	if (commands != NULL)
-		seahorse_commands_show_properties (commands, obj);
+	for_each_commands (self, show_properties_for_selected, obj);
 }
 
 void
@@ -844,15 +948,27 @@
 }
 
 void
-seahorse_viewer_register_ui (SeahorseViewer *self, const gchar *uidef, GtkActionGroup *actions)
+seahorse_viewer_register_ui (SeahorseViewer *self, SeahorseObjectPredicate *pred,
+                             const gchar *uidef, GtkActionGroup *actions)
 {
 	SeahorseViewerPrivate *pv = SEAHORSE_VIEWER_GET_PRIVATE (self);
 	GError *error = NULL;
+	ViewerPredicate predicate;
 	
 	g_return_if_fail (SEAHORSE_IS_VIEWER (self));
 
-	if (actions != NULL)
+	if (actions != NULL) {
 		seahorse_viewer_include_actions (self, actions);
+		
+		/* Add this to the list */
+		memset (&predicate, 0, sizeof (predicate));
+		if (pred)
+			predicate.pred = *pred;
+		predicate.is_commands = FALSE;
+		predicate.commands_or_actions = G_OBJECT (actions);
+		g_object_ref (actions);
+		g_array_append_val (pv->predicates, predicate);
+	}
 	
 	if (uidef && uidef[0]) {
 		if (!gtk_ui_manager_add_ui_from_string (pv->ui_manager, uidef, -1, &error)) {
@@ -863,10 +979,21 @@
 }
 
 void
-seahorse_viewer_register_commands (SeahorseViewer *self, SeahorseCommands *commands, GType for_type)
+seahorse_viewer_register_commands (SeahorseViewer *self, SeahorseObjectPredicate *pred, 
+                                   SeahorseCommands *commands)
 {
 	SeahorseViewerPrivate *pv = SEAHORSE_VIEWER_GET_PRIVATE (self);
+	ViewerPredicate predicate;
+	
 	g_return_if_fail (SEAHORSE_IS_VIEWER (self));
 	g_return_if_fail (SEAHORSE_IS_COMMANDS (commands));
-	g_hash_table_insert (pv->commands, GUINT_TO_POINTER (for_type), g_object_ref (commands));
+
+	/* Add this to the list of commands */
+	memset (&predicate, 0, sizeof (predicate));
+	if (pred)
+		predicate.pred = *pred;
+	predicate.is_commands = TRUE;
+	predicate.commands_or_actions = G_OBJECT (commands);
+	g_object_ref (commands);
+	g_array_append_val (pv->predicates, predicate);
 }

Modified: trunk/src/seahorse-viewer.h
==============================================================================
--- trunk/src/seahorse-viewer.h	(original)
+++ trunk/src/seahorse-viewer.h	Wed Dec 17 01:15:16 2008
@@ -105,11 +105,12 @@
 GtkWindow*          seahorse_viewer_get_window                      (SeahorseViewer* self);
 
 void                seahorse_viewer_register_ui                     (SeahorseViewer *self, 
+                                                                     SeahorseObjectPredicate *pred,
                                                                      const gchar *uidef, 
                                                                      GtkActionGroup *actions);
 
 void                seahorse_viewer_register_commands               (SeahorseViewer *self, 
-                                                                     SeahorseCommands *commands, 
-                                                                     GType for_type);
+                                                                     SeahorseObjectPredicate *pred,
+                                                                     SeahorseCommands *commands);
 
 #endif /* __SEAHORSE_VIEWER_H__ */

Modified: trunk/ssh/seahorse-ssh-commands.c
==============================================================================
--- trunk/ssh/seahorse-ssh-commands.c	(original)
+++ trunk/ssh/seahorse-ssh-commands.c	Wed Dec 17 01:15:16 2008
@@ -54,6 +54,7 @@
 "	</popup>"\
 "</ui>";
 
+static SeahorseObjectPredicate commands_predicate = { 0, };
 
 /* -----------------------------------------------------------------------------
  * INTERNAL 
@@ -62,49 +63,22 @@
 static void 
 on_ssh_upload (GtkAction* action, SeahorseSshCommands* self) 
 {
+	SeahorseView *view;
 	GList* ssh_keys;
-	GList* keys, *l;
 
 	g_return_if_fail (SEAHORSE_IS_SSH_COMMANDS (self));
 	g_return_if_fail (GTK_IS_ACTION (action));
 	
-	ssh_keys = NULL;
-	keys = seahorse_view_get_selected_objects (seahorse_commands_get_view (SEAHORSE_COMMANDS (self)));
+	view = seahorse_commands_get_view (SEAHORSE_COMMANDS (self));
+	ssh_keys = seahorse_view_get_selected_matching (view, &commands_predicate);
+	if (ssh_keys == NULL)
+		return;
 	
-	for (l = keys; l; l = g_list_next (l)) {
-		SeahorseObject* key = SEAHORSE_OBJECT (l->data);
-		if (seahorse_object_get_tag (key) == SEAHORSE_SSH_TYPE && 
-		    seahorse_object_get_usage (key) == SEAHORSE_USAGE_PRIVATE_KEY) 
-			ssh_keys = g_list_append (ssh_keys, SEAHORSE_SSH_KEY (key));
-	}
-
-	seahorse_ssh_upload_prompt (ssh_keys, seahorse_commands_get_window (SEAHORSE_COMMANDS (self)));
-	g_list_free (keys);
-}
-
-static void 
-on_view_selection_changed (SeahorseView* view, SeahorseSshCommands* self) 
-{
-	GList* keys, *l;
-	gboolean enable;
+	/* Indicate what we're actually going to operate on */
+	seahorse_view_set_selected_objects (view, ssh_keys);
 	
-	g_return_if_fail (SEAHORSE_IS_SSH_COMMANDS (self));
-	g_return_if_fail (SEAHORSE_IS_VIEW (view));
-	
-	keys = seahorse_view_get_selected_objects (view);
-	enable = (keys != NULL);
-
-	for (l = keys; l; l = g_list_next (l)) {
-		SeahorseObject* key = SEAHORSE_OBJECT (l->data);
-		if (seahorse_object_get_tag (key) != SEAHORSE_SSH_TYPE ||
-		    seahorse_object_get_usage (key) != SEAHORSE_USAGE_PRIVATE_KEY) {
-			enable = FALSE;
-			break;
-		}
-	}
-
-	gtk_action_group_set_sensitive (self->pv->command_actions, enable);
-	g_list_free (keys);
+	seahorse_ssh_upload_prompt (ssh_keys, seahorse_commands_get_window (SEAHORSE_COMMANDS (self)));
+	g_list_free (ssh_keys);
 }
 
 static const GtkActionEntry COMMAND_ENTRIES[] = {
@@ -165,15 +139,14 @@
 	
 		view = seahorse_commands_get_view (SEAHORSE_COMMANDS (self));
 		g_return_val_if_fail (view, NULL);
-		g_signal_connect (view, "selection-changed", G_CALLBACK (on_view_selection_changed), self);
 		
 		self->pv->command_actions = gtk_action_group_new ("ssh");
 		gtk_action_group_set_translation_domain (self->pv->command_actions, GETTEXT_PACKAGE);
 		gtk_action_group_add_actions (self->pv->command_actions, COMMAND_ENTRIES, 
 		                              G_N_ELEMENTS (COMMAND_ENTRIES), self);
 		
-		seahorse_view_register_commands (view, base, SEAHORSE_TYPE_SSH_KEY);
-		seahorse_view_register_ui (view, UI_DEFINITION, self->pv->command_actions);
+		seahorse_view_register_commands (view, &commands_predicate, base);
+		seahorse_view_register_ui (view, &commands_predicate, UI_DEFINITION, self->pv->command_actions);
 	}
 	
 	return obj;
@@ -247,6 +220,9 @@
 	SEAHORSE_COMMANDS_CLASS (klass)->show_properties = seahorse_ssh_commands_show_properties;
 	SEAHORSE_COMMANDS_CLASS (klass)->delete_objects = seahorse_ssh_commands_delete_objects;
 
+	commands_predicate.type = SEAHORSE_TYPE_SSH_KEY;
+	commands_predicate.usage = SEAHORSE_USAGE_PRIVATE_KEY;
+	
 	/* Register this class as a commands */
 	seahorse_registry_register_type (seahorse_registry_get (), SEAHORSE_TYPE_SSH_COMMANDS, 
 	                                 SEAHORSE_SSH_TYPE_STR, "commands", NULL, NULL);



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