seahorse r2651 - in trunk: . common daemon libseahorse pgp po src



Author: nnielsen
Date: Fri Dec 12 23:54:26 2008
New Revision: 2651
URL: http://svn.gnome.org/viewvc/seahorse?rev=2651&view=rev

Log:
	* common/seahorse-object-list.c: (added)
	* common/seahorse-object-list.h: (added)
	* common/Makefile.am: Aded utility functions for managing lists of objects.
	
	* libseahorse/seahorse-object.c:
	* libseahorse/seahorse-object-model.c:
	* libseahorse/seahorse-set-model.c: 
	* src/seahorse-key-manager-store.c: Various object and model fixes
	to patch corner cases with objects going away.
	
	* daemon/seahorse-service-crypto.c: 
	* pgp/libseahorse-pgp-c.vapi:
	* pgp/Makefile.am:
	* pgp/seahorse-expires.glade:
	* pgp/seahorse-gpgmex.h:
	* pgp/seahorse-gpgmex-util.c:
	* pgp/seahorse-hkp-source.c:
	* pgp/seahorse-ldap-source.c:
	* pgp/seahorse-pgp.c:
	* pgp/seahorse-pgp.h:
	* pgp/seahorse-pgp.vala: (removed)
	* pgp/seahorse-pgp-add-subkey.c:
	* pgp/seahorse-pgp-add-uid.c:
	* pgp/seahorse-pgp-commands.c:
	* pgp/seahorse-pgp-commands.vala:
	* pgp/seahorse-pgp-dialogs.h:
	* pgp/seahorse-pgp-expires.c:
	* pgp/seahorse-pgp-generator.c:
	* pgp/seahorse-pgp-key.c: 
	* pgp/seahorse-pgp-key.h:
	* pgp/seahorse-pgp-key-op.c:
	* pgp/seahorse-pgp-key-op.h:
	* pgp/seahorse-pgp-key-properties.c:
	* pgp/seahorse-pgp-photo.c: (added)
	* pgp/seahorse-pgp-photo.c: (added)
	* pgp/seahorse-pgp-revoke.c: 
	* pgp/seahorse-pgp-sign.c:
	* pgp/seahorse-pgp-source.c:
	* pgp/seahorse-pgp-sign.c:
	* pgp/seahorse-pgp-source.c:
	* pgp/seahorse-pgp-subkey.c: (added)
	* pgp/seahorse-pgp-subkey.h: (added)
	* pgp/seahorse-pgp-uid.c:
	* pgp/seahorse-pgp-uid.h:
	* pgp/seahorse-server-source.c:
	* pgp/seahorse-signer.c: Refactored how the PGP code works with regard
	to UIDs and subkeys. These are now separate objects, and keep track of 
	their own indexes etc.. Operations can be done directly with these objects
	(ie: sign, revoke etc...)

Added:
   trunk/common/seahorse-object-list.c
   trunk/common/seahorse-object-list.h
   trunk/pgp/seahorse-pgp-photo.c
   trunk/pgp/seahorse-pgp-photo.h
   trunk/pgp/seahorse-pgp-subkey.c
   trunk/pgp/seahorse-pgp-subkey.h
Removed:
   trunk/pgp/seahorse-pgp.vala
Modified:
   trunk/ChangeLog
   trunk/common/Makefile.am
   trunk/daemon/seahorse-service-crypto.c
   trunk/libseahorse/seahorse-object-model.c
   trunk/libseahorse/seahorse-object.c
   trunk/libseahorse/seahorse-set-model.c
   trunk/pgp/   (props changed)
   trunk/pgp/Makefile.am
   trunk/pgp/libseahorse-pgp-c.vapi
   trunk/pgp/seahorse-expires.glade
   trunk/pgp/seahorse-gpgmex-util.c
   trunk/pgp/seahorse-gpgmex.h
   trunk/pgp/seahorse-hkp-source.c
   trunk/pgp/seahorse-ldap-source.c
   trunk/pgp/seahorse-pgp-add-subkey.c
   trunk/pgp/seahorse-pgp-add-uid.c
   trunk/pgp/seahorse-pgp-commands.c
   trunk/pgp/seahorse-pgp-commands.vala
   trunk/pgp/seahorse-pgp-dialogs.h
   trunk/pgp/seahorse-pgp-expires.c
   trunk/pgp/seahorse-pgp-generator.c
   trunk/pgp/seahorse-pgp-key-op.c
   trunk/pgp/seahorse-pgp-key-op.h
   trunk/pgp/seahorse-pgp-key-properties.c
   trunk/pgp/seahorse-pgp-key.c
   trunk/pgp/seahorse-pgp-key.h
   trunk/pgp/seahorse-pgp-photos.c
   trunk/pgp/seahorse-pgp-revoke.c
   trunk/pgp/seahorse-pgp-sign.c
   trunk/pgp/seahorse-pgp-source.c
   trunk/pgp/seahorse-pgp-uid.c
   trunk/pgp/seahorse-pgp-uid.h
   trunk/pgp/seahorse-pgp.c
   trunk/pgp/seahorse-pgp.h
   trunk/pgp/seahorse-server-source.c
   trunk/pgp/seahorse-signer.c
   trunk/pgp/vala-build.stamp
   trunk/po/POTFILES.in
   trunk/po/POTFILES.skip
   trunk/src/seahorse-key-manager-store.c

Modified: trunk/common/Makefile.am
==============================================================================
--- trunk/common/Makefile.am	(original)
+++ trunk/common/Makefile.am	Fri Dec 12 23:54:26 2008
@@ -10,5 +10,6 @@
 libseahorse_common_la_SOURCES = \
 	seahorse-bind.c seahorse-bind.h \
 	seahorse-cleanup.c seahorse-cleanup.h \
+	seahorse-object-list.c seahorse-object-list.h \
 	seahorse-registry.c seahorse-registry.h
 	
\ No newline at end of file

Added: trunk/common/seahorse-object-list.c
==============================================================================
--- (empty file)
+++ trunk/common/seahorse-object-list.c	Fri Dec 12 23:54:26 2008
@@ -0,0 +1,84 @@
+/* 
+ * Seahorse
+ * 
+ * Copyright (C) 2008 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.  
+ */
+
+#include "seahorse-object-list.h"
+
+GList*
+seahorse_object_list_append (GList *original, gpointer object)
+{
+	g_return_val_if_fail (G_IS_OBJECT (object), original);
+	return g_list_append (original, g_object_ref (object));
+}
+
+GList*
+seahorse_object_list_prepend (GList *original, gpointer object)
+{
+	g_return_val_if_fail (G_IS_OBJECT (object), original);
+	return g_list_prepend (original, g_object_ref (object));	
+}
+
+GList*
+seahorse_object_list_remove (GList *original, gpointer object)
+{
+	GList *at;
+	
+	g_return_val_if_fail (G_IS_OBJECT (object), original);
+	
+	at = g_list_find (original, object);
+	if (at != NULL) {
+		g_object_unref (object);
+		return g_list_delete_link (original, at); 
+	}
+	
+	return original;
+}
+
+GList*
+seahorse_object_list_copy (GList *original)
+{
+	GList *l, *copy;
+	
+	copy = g_list_copy (original);
+	for (l = copy; l; l = g_list_next (l))
+		g_object_ref (l->data);
+	
+	return copy;
+}
+
+void
+seahorse_object_list_free (GList *list)
+{
+	GList *l;
+	
+	for (l = list; l; l = g_list_next (l))
+		g_object_unref (l->data);
+}
+
+GType
+seahorse_object_list_type (void)
+{
+	static GType type = 0;
+	if (!type)
+		type = g_boxed_type_register_static ("GList_GObject", 
+		                                     (GBoxedCopyFunc)seahorse_object_list_copy,
+		                                     (GBoxedFreeFunc)seahorse_object_list_free);
+	return type;
+}

Added: trunk/common/seahorse-object-list.h
==============================================================================
--- (empty file)
+++ trunk/common/seahorse-object-list.h	Fri Dec 12 23:54:26 2008
@@ -0,0 +1,42 @@
+/* 
+ * Seahorse
+ * 
+ * Copyright (C) 2008 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.  
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#ifndef SEAHORSEOBJECTLIST_H_
+#define SEAHORSEOBJECTLIST_H_
+
+#define    SEAHORSE_BOXED_OBJECT_LIST        (seahorse_object_list_type ())
+
+GType      seahorse_object_list_type         (void);
+
+GList*     seahorse_object_list_append       (GList *original, gpointer object);
+
+GList*     seahorse_object_list_prepend      (GList *original, gpointer object);
+
+GList*     seahorse_object_list_remove       (GList *original, gpointer object);
+
+GList*     seahorse_object_list_copy         (GList *original);
+
+void       seahorse_object_list_free         (GList *list);
+
+#endif /* SEAHORSEOBJECTLIST_H_ */

Modified: trunk/daemon/seahorse-service-crypto.c
==============================================================================
--- trunk/daemon/seahorse-service-crypto.c	(original)
+++ trunk/daemon/seahorse-service-crypto.c	Fri Dec 12 23:54:26 2008
@@ -114,7 +114,7 @@
 
 	for (i = 0; keys != NULL; keys = g_list_next (keys), i++) {
 		g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (keys->data), recips);
-		recips[i] = SEAHORSE_PGP_KEY (keys->data)->pubkey;
+		recips[i] = seahorse_pgp_key_get_public (keys->data);
 		gpgmex_key_ref (recips[i]);
 	}
 
@@ -306,7 +306,7 @@
     
     /* Do the encryption */
     if (signkey) {
-        gpgme_signers_add (pop->gctx, SEAHORSE_PGP_KEY (signkey)->seckey);
+        gpgme_signers_add (pop->gctx, seahorse_pgp_key_get_private (SEAHORSE_PGP_KEY (signkey)));
         gerr = gpgme_op_encrypt_sign_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST, 
                                             plain, cipher);
     } else {
@@ -372,7 +372,7 @@
     gpgme_set_armor (pop->gctx, TRUE);
 
     /* Do the signage */
-    gpgme_signers_add (pop->gctx, SEAHORSE_PGP_KEY (signkey)->seckey);
+    gpgme_signers_add (pop->gctx, seahorse_pgp_key_get_private (SEAHORSE_PGP_KEY (signkey)));
     gerr = gpgme_op_sign_start (pop->gctx, plain, cipher, GPGME_SIG_MODE_CLEAR);
 
     /* Frees cipher */

Modified: trunk/libseahorse/seahorse-object-model.c
==============================================================================
--- trunk/libseahorse/seahorse-object-model.c	(original)
+++ trunk/libseahorse/seahorse-object-model.c	Fri Dec 12 23:54:26 2008
@@ -95,6 +95,7 @@
 	SeahorseObjectRow *skrow = g_hash_table_lookup (pv->rows, was);
 	if (skrow) {
 		skrow->object = NULL;
+		skrow->binding = NULL;
 		g_hash_table_remove (pv->rows, was);
 	}
 }
@@ -153,7 +154,8 @@
         
     }
     
-    seahorse_bind_disconnect (skrow->binding);
+    if (skrow->binding)
+	    seahorse_bind_disconnect (skrow->binding);
     if (skrow->object)
 	    g_object_weak_unref (G_OBJECT (skrow->object), key_destroyed, skrow->self);
 

Modified: trunk/libseahorse/seahorse-object.c
==============================================================================
--- trunk/libseahorse/seahorse-object.c	(original)
+++ trunk/libseahorse/seahorse-object.c	Fri Dec 12 23:54:26 2008
@@ -75,6 +75,7 @@
 	guint flags;
 	
 	gboolean realized;
+	gboolean realizing;
 };
 
 G_DEFINE_TYPE (SeahorseObject, seahorse_object, G_TYPE_OBJECT);
@@ -837,9 +838,13 @@
 	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
 	if (self->pv->realized)
 		return;
+	if (self->pv->realizing)
+		return;
 	klass = SEAHORSE_OBJECT_GET_CLASS (self);
 	g_return_if_fail (klass->realize);
+	self->pv->realizing = TRUE;
 	(klass->realize) (self);
+	self->pv->realizing = FALSE;
 }
 
 void

Modified: trunk/libseahorse/seahorse-set-model.c
==============================================================================
--- trunk/libseahorse/seahorse-set-model.c	(original)
+++ trunk/libseahorse/seahorse-set-model.c	Fri Dec 12 23:54:26 2008
@@ -36,7 +36,7 @@
 	GType *column_types;
 } SeahorseSetModelPrivate;
 
-static void remove_object (SeahorseSetModel *smodel, SeahorseObject *sobj);
+static void remove_object (SeahorseSetModel *smodel, gpointer was_sobj);
 static GNode* add_object (SeahorseSetModel *smodel, SeahorseObject *sobj);
 static void seahorse_set_model_implement_tree_model (GtkTreeModelIface *iface);
 
@@ -76,6 +76,27 @@
 	iter->user_data2 = node;
 }
 
+static GtkTreePath*
+path_for_node (GNode *node)
+{
+	GtkTreePath *path;
+	gint index;
+
+	g_assert (node);
+	
+	path = gtk_tree_path_new ();
+	for (;;) {
+		if (!node->parent) 
+			break;
+		index = g_node_child_position (node->parent, node);
+		g_assert (index >= 0);
+		gtk_tree_path_prepend_index (path, index);
+		node = node->parent;
+	}
+	
+	return path;
+}
+
 static void
 key_hierarchy (SeahorseObject *sobj, GParamSpec *spec, SeahorseSetModel *smodel)
 {
@@ -89,6 +110,21 @@
 	add_object (smodel, sobj);
 }
 
+void
+gone_object (SeahorseSetModel *smodel, gpointer was_sobj)
+{
+	SeahorseSetModelPrivate *pv = SEAHORSE_SET_MODEL_GET_PRIVATE (smodel);
+	GNode *node;
+	
+	node = g_hash_table_lookup (pv->object_to_node, was_sobj);
+	g_assert (node);
+	
+	/* Mark this object as gone */
+	node->data = NULL;
+	
+	remove_object (smodel, was_sobj);
+}
+
 static GNode*
 add_object (SeahorseSetModel *smodel, SeahorseObject *sobj)
 {
@@ -122,6 +158,7 @@
 	g_return_val_if_fail (parent_node, NULL);
 	had = parent_node->children ? TRUE : FALSE;
 	node = g_node_append_data (parent_node, sobj);
+	g_object_weak_ref (G_OBJECT (sobj), (GWeakNotify)gone_object, smodel);
 	g_hash_table_insert (pv->object_to_node, sobj, node);
 	g_signal_connect (sobj, "notify::parent", G_CALLBACK (key_hierarchy), smodel);
 
@@ -169,18 +206,23 @@
 	if (node == pv->root_node)
 		return FALSE;
 	
-	g_assert (SEAHORSE_IS_OBJECT (node->data));
-	g_assert (g_hash_table_lookup (pv->object_to_node, node->data) == node);
+	/* This can be NULL of the object was finalized */
+	if (node->data != NULL) {
+		g_assert (SEAHORSE_IS_OBJECT (node->data));
+		g_assert (g_hash_table_lookup (pv->object_to_node, node->data) == node);
+	}
 
 	/* Create the path for firing the event */
-	iter_for_node (pv, node, &iter);
-	path = gtk_tree_model_get_path (GTK_TREE_MODEL (smodel), &iter);
+	path = path_for_node (node);
 	g_return_val_if_fail (path, TRUE);
 
 	/* Remove the actual node */
 	parent_node = node->parent;
-	g_hash_table_remove (pv->object_to_node, node->data);
-	g_signal_handlers_disconnect_by_func (node->data, key_hierarchy, smodel);
+	if(node->data) {
+		g_hash_table_remove (pv->object_to_node, node->data);
+		g_signal_handlers_disconnect_by_func (node->data, key_hierarchy, smodel);
+		g_object_weak_unref (G_OBJECT (node->data), (GWeakNotify)gone_object, smodel);
+	}
 	g_node_destroy (node);
 
 	/* Fire signal for this removed row */
@@ -202,17 +244,22 @@
 }
 
 static void 
-remove_object (SeahorseSetModel *smodel, SeahorseObject *sobj)
+remove_object (SeahorseSetModel *smodel, gpointer was_sobj)
 {
 	SeahorseSetModelPrivate *pv = SEAHORSE_SET_MODEL_GET_PRIVATE (smodel);
 	GNode *node;
 	GNode *parent;
 	SeahorseObject *parent_obj;
 
-	node = g_hash_table_lookup (pv->object_to_node, sobj);
+	node = g_hash_table_lookup (pv->object_to_node, was_sobj);
 	g_assert (node);
 	g_assert (node != pv->root_node);
-	g_assert (node->data == sobj);
+	
+	/* 
+	 * If the object has already dissappeared, then this will be 
+	 * set to null by gone_object().
+	 */
+	g_assert (node->data == was_sobj || node->data == NULL);
 	
 	parent = node->parent;
 	g_assert (parent);
@@ -226,7 +273,7 @@
 	 * just added for the sake of holding the child (see add_object above)
 	 */
 	if (parent != pv->root_node && g_node_n_children (parent) == 0) {
-		parent_obj = seahorse_object_get_parent (sobj);
+		parent_obj = SEAHORSE_OBJECT (parent->data);
 		g_return_if_fail (parent_obj);
 		if (!seahorse_set_has_object (smodel->set, parent_obj))
 			remove_object (smodel, parent_obj);
@@ -353,24 +400,12 @@
 seahorse_set_model_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter)
 {
 	SeahorseSetModelPrivate *pv = SEAHORSE_SET_MODEL_GET_PRIVATE (tree_model);
-	GtkTreePath *path;
 	GNode *node;
-	gint index;
 
 	g_return_val_if_fail (SEAHORSE_SET_MODEL (tree_model), NULL);
 	node = node_for_iter (pv, iter);
 	g_return_val_if_fail (node != NULL, NULL);
-	path = gtk_tree_path_new ();
-	for (;;) {
-		if (!node->parent) 
-			break;
-		index = g_node_child_position (node->parent, node);
-		g_assert (index >= 0);
-		gtk_tree_path_prepend_index (path, index);
-		node = node->parent;
-	}
-
-	return path;
+	return path_for_node (node);
 }
 
 static void
@@ -381,6 +416,7 @@
 	SeahorseObject *sobj;
 	const gchar *property;
 	GParamSpec *spec;
+	GValue original;
 	GType type;
 
 	g_return_if_fail (SEAHORSE_SET_MODEL (tree_model));
@@ -397,19 +433,35 @@
 	/* Lookup the property on the object */
 	spec = g_object_class_find_property (G_OBJECT_GET_CLASS (sobj), property);
 	if (spec) {
-		if (spec->value_type != type) {
-			g_warning ("%s property of %s class was of type %s instead of type %s", 
-			           property, G_OBJECT_TYPE_NAME (sobj), 
-			           g_type_name (spec->value_type), g_type_name (type));
-			return;
+		
+		/* Simple, no transformation necessary */
+		if (spec->value_type == type) {
+			g_object_get_property (G_OBJECT (sobj), property, value);
+
+		/* Not the same type, try to transform */
+		} else {
+
+			memset (&original, 0, sizeof (original));
+			g_value_init (&original, spec->value_type);
+			
+			g_object_get_property (G_OBJECT (sobj), property, &original);
+			if (!g_value_transform (&original, value)) { 
+				g_warning ("%s property of %s class was of type %s instead of type %s"
+				           " and cannot be converted", property, G_OBJECT_TYPE_NAME (sobj), 
+				           g_type_name (spec->value_type), g_type_name (type));
+				spec = NULL;
+			}
 		}
 
-		g_object_get_property (G_OBJECT (sobj), property, value);
-
-	} else if (type == G_TYPE_STRING) {
-
+	
+	} 
+	
+	/* No property present */
+	if (spec == NULL) {
+		
 		/* All the number types have sane defaults */
-		g_value_set_string (value, "");
+		if (type == G_TYPE_STRING)
+			g_value_set_string (value, "");
 	}
 }
 

Modified: trunk/pgp/Makefile.am
==============================================================================
--- trunk/pgp/Makefile.am	(original)
+++ trunk/pgp/Makefile.am	Fri Dec 12 23:54:26 2008
@@ -18,7 +18,6 @@
 	-DGETTEXT_PACKAGE=\""seahorse\""
 
 VALA_SRCS = \
-	seahorse-pgp.vala \
 	seahorse-pgp-commands.vala \
 	seahorse-pgp-generator.vala
 
@@ -64,6 +63,7 @@
 	seahorse-gpgme-io.c seahorse-gpgme-io.h \
 	seahorse-gpgmex.h seahorse-gpgmex-op.c seahorse-gpgmex-util.c \
 	seahorse-gpg-options.c seahorse-gpg-options.h \
+	seahorse-pgp.c seahorse-pgp.h \
 	seahorse-pgp-add-subkey.c \
 	seahorse-pgp-add-uid.c \
 	seahorse-pgp-error.c \
@@ -74,11 +74,13 @@
 	seahorse-pgp-key-properties.c \
 	seahorse-pgp-keysets.c seahorse-pgp-keysets.h \
 	seahorse-pgp-operation.c seahorse-pgp-operation.h \
+	seahorse-pgp-photo.c seahorse-pgp-photo.h \
 	seahorse-pgp-photos.c \
 	seahorse-pgp-module.c seahorse-pgp-module.h \
 	seahorse-pgp-revoke.c \
 	seahorse-pgp-source.c seahorse-pgp-source.h \
 	seahorse-pgp-sign.c \
+	seahorse-pgp-subkey.c seahorse-pgp-subkey.h \
 	seahorse-pgp-uid.c seahorse-pgp-uid.h \
 	seahorse-signer.c seahorse-pgp-dialogs.h \
 	$(VALA_CFILES) $(VALA_HFILES) \

Modified: trunk/pgp/libseahorse-pgp-c.vapi
==============================================================================
--- trunk/pgp/libseahorse-pgp-c.vapi	(original)
+++ trunk/pgp/libseahorse-pgp-c.vapi	Fri Dec 12 23:54:26 2008
@@ -19,12 +19,17 @@
  * 02111-1307, USA.  
  */
  
-[CCode (cprefix = "SeahorsePGP", lower_case_cprefix = "seahorse_pgp_")]
+[CCode (cprefix = "SeahorsePGP", lower_case_cprefix = "seahorse_pgp_", cheader_filename = "seahorse-pgp.h")]
 namespace Seahorse.Pgp {
 	
+	public static const string TYPE_STR;
+	public static const GLib.Quark TYPE;
+	public static const string STOCK_ICON;	
+	
         [CCode (cheader_filename = "seahorse-pgp-dialogs.h")]
         public class Sign : GLib.Object {
-		public static void prompt (Key key, uint uid, Gtk.Window parent);
+		public static void prompt (Key key, Gtk.Window parent);
+		public static void prompt_uid (Uid uid, Gtk.Window parent);
         }
 
         [CCode (cheader_filename = "seahorse-pgp-dialogs.h")]

Modified: trunk/pgp/seahorse-expires.glade
==============================================================================
--- trunk/pgp/seahorse-expires.glade	(original)
+++ trunk/pgp/seahorse-expires.glade	Fri Dec 12 23:54:26 2008
@@ -23,7 +23,7 @@
   <signal name="delete_event" handler="delete_event" last_modification_time="Fri, 31 Jan 2003 22:20:04 GMT"/>
 
   <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
+    <widget class="GtkVBox" id="all-controls">
       <property name="visible">True</property>
       <property name="homogeneous">False</property>
       <property name="spacing">2</property>

Modified: trunk/pgp/seahorse-gpgmex-util.c
==============================================================================
--- trunk/pgp/seahorse-gpgmex-util.c	(original)
+++ trunk/pgp/seahorse-gpgmex-util.c	Fri Dec 12 23:54:26 2008
@@ -58,6 +58,7 @@
     		             gpgme_strerror (gerr));
     	}
 }
+
 /* -----------------------------------------------------------------------------
  * DATA
  */
@@ -380,15 +381,16 @@
     add_uid_to_key (key, u);
 }
 
-void        
+gpgme_key_t
 gpgmex_key_ref (gpgme_key_t key)
 {
-    g_return_if_fail (key != NULL);
+    g_return_val_if_fail (key != NULL, NULL);
     
     if (key->keylist_mode & SEAHORSE_KEYLIST_MODE) 
         ((sukey*)key)->refs++;
     else
         gpgme_key_ref (key);
+    return key;
 }
     
 void        
@@ -499,34 +501,6 @@
 	g_free (keys);
 }
 
-gpgmex_photo_id_t 
-gpgmex_photo_id_alloc (guint uid)
-{
-    gpgmex_photo_id_t photoid = g_new0 (struct _gpgmex_photo_id, 1);
-    photoid->uid = uid;
-    return photoid;
-}
-
-void        
-gpgmex_photo_id_free (gpgmex_photo_id_t photoid)
-{
-    if (photoid) {
-        if (photoid->photo)
-            g_object_unref (photoid->photo);
-        g_free (photoid);
-    }
-}
-
-void 
-gpgmex_photo_id_free_all (gpgmex_photo_id_t photoid)
-{
-    while (photoid) {
-        gpgmex_photo_id_t next = photoid->next;
-        gpgmex_photo_id_free (photoid);
-        photoid = next;
-    }
-}
-
 /* -----------------------------------------------------------------------------
  * OTHER MISC FUNCTIONS
  */

Modified: trunk/pgp/seahorse-gpgmex.h
==============================================================================
--- trunk/pgp/seahorse-gpgmex.h	(original)
+++ trunk/pgp/seahorse-gpgmex.h	Fri Dec 12 23:54:26 2008
@@ -83,14 +83,6 @@
     GPGMEX_KEY_DISABLED = 0x02
 };
 
-/* A photo id from a key */
-typedef struct _gpgmex_photo_id {
-    struct _gpgmex_photo_id *next;
-    
-    guint uid;            /* The actual uid used with gpgpme_op_edit */
-    GdkPixbuf *photo;     /* The photo itself */
-} *gpgmex_photo_id_t;
-    
 gpgme_key_t gpgmex_key_alloc         ();
 
 void        gpgmex_key_add_subkey    (gpgme_key_t key,
@@ -113,7 +105,7 @@
                                       
 int         gpgmex_key_is_gpgme      (gpgme_key_t key);
 
-void        gpgmex_key_ref           (gpgme_key_t key);
+gpgme_key_t gpgmex_key_ref           (gpgme_key_t key);
 
 void        gpgmex_key_unref         (gpgme_key_t key);
 
@@ -121,14 +113,6 @@
 
 void        gpgmex_free_keys         (gpgme_key_t* keys);
 
-gpgmex_photo_id_t 
-            gpgmex_photo_id_alloc    (guint uid);
-            
-void        gpgmex_photo_id_free     (gpgmex_photo_id_t photoid);
-
-void        gpgmex_photo_id_free_all (gpgmex_photo_id_t photoid);
-
-
 /* -----------------------------------------------------------------------------
  * EXTRA FUNCTIONALITY
  */

Modified: trunk/pgp/seahorse-hkp-source.c
==============================================================================
--- trunk/pgp/seahorse-hkp-source.c	(original)
+++ trunk/pgp/seahorse-hkp-source.c	Fri Dec 12 23:54:26 2008
@@ -505,15 +505,17 @@
 add_key (SeahorseHKPSource *ssrc, gpgme_key_t key)
 {
     SeahorseObject *prev;
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
     GQuark keyid;
        
-    keyid = seahorse_pgp_key_get_cannonical_id (seahorse_pgp_key_get_id (key, 0));
+    g_return_if_fail (key && key->subkeys && key->subkeys->keyid);
+
+    keyid = seahorse_pgp_key_get_cannonical_id (key->subkeys->keyid);
     prev = seahorse_context_get_object (SCTX_APP (), SEAHORSE_SOURCE (ssrc), keyid);
     
     if (prev != NULL) {
         g_return_if_fail (SEAHORSE_IS_PGP_KEY (prev));
-        gpgmex_combine_keys (SEAHORSE_PGP_KEY (prev)->pubkey, key);
+        gpgmex_combine_keys (seahorse_pgp_key_get_public (SEAHORSE_PGP_KEY (prev)), key);
         return;
     }
 

Modified: trunk/pgp/seahorse-ldap-source.c
==============================================================================
--- trunk/pgp/seahorse-ldap-source.c	(original)
+++ trunk/pgp/seahorse-ldap-source.c	Fri Dec 12 23:54:26 2008
@@ -751,16 +751,18 @@
 add_key (SeahorseLDAPSource *ssrc, gpgme_key_t key)
 {
     SeahorseObject *prev;
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
     GQuark keyid;
-       
-    keyid = seahorse_pgp_key_get_cannonical_id (seahorse_pgp_key_get_id (key, 0));
+
+    g_return_if_fail (key && key->subkeys && key->subkeys->keyid);
+
+    keyid = seahorse_pgp_key_get_cannonical_id (key->subkeys->keyid);
     prev = seahorse_context_get_object (SCTX_APP (), SEAHORSE_SOURCE (ssrc), keyid);
     
     /* TODO: This function needs reworking after we get more key types */
     if (prev != NULL) {
         g_return_if_fail (SEAHORSE_IS_PGP_KEY (prev));
-        gpgmex_combine_keys (SEAHORSE_PGP_KEY (prev)->pubkey, key);
+        gpgmex_combine_keys (seahorse_pgp_key_get_public (SEAHORSE_PGP_KEY (prev)), key);
         return;
     }
 

Modified: trunk/pgp/seahorse-pgp-add-subkey.c
==============================================================================
--- trunk/pgp/seahorse-pgp-add-subkey.c	(original)
+++ trunk/pgp/seahorse-pgp-add-subkey.c	Fri Dec 12 23:54:26 2008
@@ -158,8 +158,8 @@
 	
 	widget = glade_xml_get_widget (swidget->xml, swidget->name);
 	gtk_widget_set_sensitive (widget, FALSE);
-	err = seahorse_pgp_key_pair_op_add_subkey (SEAHORSE_PGP_KEY (skwidget->object), 
-                                           real_type, length, expires);
+	err = seahorse_pgp_key_op_add_subkey (SEAHORSE_PGP_KEY (skwidget->object), 
+	                                      real_type, length, expires);
 	gtk_widget_set_sensitive (widget, TRUE);
 	
 	if (!GPG_IS_OK (err))
@@ -169,7 +169,7 @@
 }
 
 void
-seahorse_pgp_add_subkey_new (SeahorsePGPKey *pkey, GtkWindow *parent)
+seahorse_pgp_add_subkey_new (SeahorsePgpKey *pkey, GtkWindow *parent)
 {
 	SeahorseWidget *swidget;
 	GtkComboBox* combo;

Modified: trunk/pgp/seahorse-pgp-add-uid.c
==============================================================================
--- trunk/pgp/seahorse-pgp-add-uid.c	(original)
+++ trunk/pgp/seahorse-pgp-add-uid.c	Fri Dec 12 23:54:26 2008
@@ -79,8 +79,8 @@
 	comment = gtk_entry_get_text (GTK_ENTRY (
 		glade_xml_get_widget (swidget->xml, "comment")));
 	
-	err = seahorse_pgp_key_pair_op_add_uid (SEAHORSE_PGP_KEY (object),
-		                                name, email, comment);
+	err = seahorse_pgp_key_op_add_uid (SEAHORSE_PGP_KEY (object),
+	                                   name, email, comment);
 	if (!GPG_IS_OK (err))
 		seahorse_pgp_handle_gpgme_error (err, _("Couldn't add user id"));
 	else
@@ -94,7 +94,7 @@
  * Creates a new #SeahorseKeyWidget dialog for adding a user ID to @skey.
  **/
 void
-seahorse_pgp_add_uid_new (SeahorsePGPKey *pkey, GtkWindow *parent)
+seahorse_pgp_add_uid_new (SeahorsePgpKey *pkey, GtkWindow *parent)
 {
 	SeahorseWidget *swidget;
 	const gchar *userid;

Modified: trunk/pgp/seahorse-pgp-commands.c
==============================================================================
--- trunk/pgp/seahorse-pgp-commands.c	(original)
+++ trunk/pgp/seahorse-pgp-commands.c	Fri Dec 12 23:54:26 2008
@@ -21,14 +21,15 @@
 
 #include "seahorse-pgp-commands.h"
 #include <glib/gi18n-lib.h>
+#include <seahorse-pgp.h>
 #include <seahorse-pgp-dialogs.h>
 #include <seahorse-pgp-key.h>
 #include <seahorse-view.h>
 #include <seahorse-util.h>
 #include <seahorse-source.h>
+#include <seahorse-pgp-uid.h>
 #include <config.h>
 #include <common/seahorse-registry.h>
-#include "seahorse-pgp.h"
 
 
 
@@ -190,9 +191,17 @@
 	g_return_if_fail (GTK_IS_ACTION (action));
 	_tmp0 = NULL;
 	key = (_tmp0 = seahorse_view_get_selected (seahorse_commands_get_view (SEAHORSE_COMMANDS (self))), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
-	/* TODO: Make signing a specific UID work again */
-	if (key != NULL && seahorse_object_get_tag (key) == SEAHORSE_PGP_TYPE) {
-		seahorse_pgp_sign_prompt (SEAHORSE_PGP_KEY (key), ((guint) (0)), seahorse_view_get_window (seahorse_commands_get_view (SEAHORSE_COMMANDS (self))));
+	if (key == NULL) {
+		(key == NULL ? NULL : (key = (g_object_unref (key), NULL)));
+		return;
+	} else {
+		if (G_TYPE_FROM_INSTANCE (G_OBJECT (key)) == SEAHORSE_PGP_TYPE_KEY) {
+			seahorse_pgp_sign_prompt (SEAHORSE_PGP_KEY (key), seahorse_view_get_window (seahorse_commands_get_view (SEAHORSE_COMMANDS (self))));
+		} else {
+			if (G_TYPE_FROM_INSTANCE (G_OBJECT (key)) == SEAHORSE_PGP_TYPE_UID) {
+				seahorse_pgp_sign_prompt_uid (SEAHORSE_PGP_UID (key), seahorse_view_get_window (seahorse_commands_get_view (SEAHORSE_COMMANDS (self))));
+			}
+		}
 	}
 	(key == NULL ? NULL : (key = (g_object_unref (key), NULL)));
 }

Modified: trunk/pgp/seahorse-pgp-commands.vala
==============================================================================
--- trunk/pgp/seahorse-pgp-commands.vala	(original)
+++ trunk/pgp/seahorse-pgp-commands.vala	Fri Dec 12 23:54:26 2008
@@ -129,9 +129,12 @@
 
 		private void on_key_sign (Action action) {
 			var key = view.selected;
-			/* TODO: Make signing a specific UID work again */
-			if (key != null && key.tag == Seahorse.Pgp.TYPE)
-				Sign.prompt ((Pgp.Key)key, 0, view.window);
+			if (key == null)
+				return;
+			else if (key.get_type () == typeof (Pgp.Key))
+				Sign.prompt ((Pgp.Key)key, view.window);
+			else if (key.get_type () == typeof (Pgp.Uid))
+				Sign.prompt_uid ((Pgp.Uid)key, view.window);
 		}
 		
 		private void on_view_selection_changed (View view) {

Modified: trunk/pgp/seahorse-pgp-dialogs.h
==============================================================================
--- trunk/pgp/seahorse-pgp-dialogs.h	(original)
+++ trunk/pgp/seahorse-pgp-dialogs.h	Fri Dec 12 23:54:26 2008
@@ -20,54 +20,57 @@
  * Boston, MA 02111-1307, USA.
  */
 
-/**
- * Various UI elements and dialogs used in libseahorse.
+/*
+ * Various UI elements and dialogs used in pgp component.
  */
  
 #ifndef __SEAHORSE_PGP_DIALOGS_H__
 #define __SEAHORSE_PGP_DIALOGS_H__
 
-#include <gtk/gtk.h>
+#include <glib.h>
 
 #include "pgp/seahorse-pgp-key.h"
+#include "pgp/seahorse-pgp-photo.h"
+#include "pgp/seahorse-pgp-subkey.h"
+#include "pgp/seahorse-pgp-uid.h"
 
-void            seahorse_pgp_sign_prompt           (SeahorsePGPKey *pkey,
-                                                    guint uid,
+void            seahorse_pgp_sign_prompt           (SeahorsePgpKey *key,
                                                     GtkWindow *parent);
 
-SeahorsePGPKey* seahorse_signer_get                 (GtkWindow *parent);
+void            seahorse_pgp_sign_prompt_uid       (SeahorsePgpUid *uid,
+                                                    GtkWindow *parent);
+
+SeahorsePgpKey* seahorse_signer_get                 (GtkWindow *parent);
 
-void            seahorse_pgp_handle_gpgme_error     (gpgme_error_t err, const gchar* desc, ...);
+void            seahorse_pgp_handle_gpgme_error     (gpgme_error_t err, 
+                                                     const gchar* desc, ...);
 
-void            seahorse_pgp_key_properties_show    (SeahorsePGPKey *pkey,
+void            seahorse_pgp_key_properties_show    (SeahorsePgpKey *pkey,
                                                      GtkWindow *parent);
 
 void            seahorse_pgp_generate_show          (SeahorsePGPSource *sksrc,
                                                      GtkWindow *parent);
 
-void            seahorse_pgp_add_revoker_new        (SeahorsePGPKey *pkey,
+void            seahorse_pgp_add_revoker_new        (SeahorsePgpKey *pkey,
                                                      GtkWindow *parent);
 
-void            seahorse_pgp_expires_new            (SeahorsePGPKey *pkey,
-                                                     GtkWindow *parent,
-                                                     guint index);
+void            seahorse_pgp_expires_new            (SeahorsePgpSubkey *subkey,
+                                                     GtkWindow *parent);
 
-void            seahorse_pgp_add_subkey_new         (SeahorsePGPKey *pkey,
+void            seahorse_pgp_add_subkey_new         (SeahorsePgpKey *pkey,
                                                      GtkWindow *parent);
 
-void            seahorse_pgp_add_uid_new            (SeahorsePGPKey *pkey,
+void            seahorse_pgp_add_uid_new            (SeahorsePgpKey *pkey,
                                                      GtkWindow *parent);
 
-void            seahorse_pgp_revoke_new             (SeahorsePGPKey *pkey,
-                                                     GtkWindow *parent,
-                                                     guint index);
+void            seahorse_pgp_revoke_new             (SeahorsePgpSubkey *subkey,
+                                                     GtkWindow *parent);
 
-gboolean        seahorse_pgp_photo_add              (SeahorsePGPKey *pkey, 
+gboolean        seahorse_pgp_photo_add              (SeahorsePgpKey *pkey, 
                                                      GtkWindow *parent,
                                                      const gchar *path);
                                          
-gboolean        seahorse_pgp_photo_delete           (SeahorsePGPKey *pkey,
-                                                     GtkWindow *parent,
-                                                     gpgmex_photo_id_t photo);
+gboolean        seahorse_pgp_photo_delete           (SeahorsePgpPhoto *photo,
+                                                     GtkWindow *parent);
 
 #endif /* __SEAHORSE_PGP_DIALOGS_H__ */

Modified: trunk/pgp/seahorse-pgp-expires.c
==============================================================================
--- trunk/pgp/seahorse-pgp-expires.c	(original)
+++ trunk/pgp/seahorse-pgp-expires.c	Fri Dec 12 23:54:26 2008
@@ -35,39 +35,38 @@
 static void
 ok_clicked (GtkButton *button, SeahorseWidget *swidget)
 {
-	SeahorseObjectWidget *skwidget;
-	SeahorsePGPKey *pkey;
-	GtkWidget *w; 
-	gpgme_subkey_t subkey;
+	GtkWidget *widget; 
+	SeahorsePgpSubkey *subkey;
 	gpgme_error_t err;
-	guint index;
 	time_t expiry = 0;
 	struct tm t;
 	
-	skwidget = SEAHORSE_OBJECT_WIDGET (swidget);
-	pkey = SEAHORSE_PGP_KEY (skwidget->object);
-	index = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (skwidget), "index"));
+	subkey = SEAHORSE_PGP_SUBKEY (g_object_get_data (G_OBJECT (swidget), "subkey"));
 	
-	w = glade_xml_get_widget (swidget->xml, "expire");
-	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w))) {
+	widget = glade_xml_get_widget (swidget->xml, "expire");
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
 		
 		memset (&t, 0, sizeof(t));            
-		w = glade_xml_get_widget (swidget->xml, "calendar");
-		gtk_calendar_get_date (GTK_CALENDAR (w), (guint*)&(t.tm_year), 
-							   (guint*)&(t.tm_mon), (guint*)&(t.tm_mday));
+		widget = glade_xml_get_widget (swidget->xml, "calendar");
+		gtk_calendar_get_date (GTK_CALENDAR (widget), (guint*)&(t.tm_year), 
+		                       (guint*)&(t.tm_mon), (guint*)&(t.tm_mday));
 		t.tm_year -= 1900;
 		expiry = mktime (&t);
 	}
 	
-	subkey = seahorse_pgp_key_get_nth_subkey (pkey, index);    
-	g_return_if_fail (subkey != NULL);
-    
-	if (expiry != subkey->expires) {
-		err = seahorse_pgp_key_pair_op_set_expires (pkey, index, expiry);
+	widget = seahorse_widget_get_widget (swidget, "all-controls");
+	gtk_widget_set_sensitive (widget, FALSE);
+	g_object_ref (swidget);
+	g_object_ref (subkey);
+	
+	if (expiry != seahorse_pgp_subkey_get_expires (subkey)) {
+		err = seahorse_pgp_key_op_set_expires (subkey, expiry);
 		if (!GPG_IS_OK (err))
 			seahorse_pgp_handle_gpgme_error (err, _("Couldn't change expiry date"));
 	}
     
+	g_object_unref (subkey);
+	g_object_unref (swidget);
 	seahorse_widget_destroy (swidget);
 }
 
@@ -84,56 +83,50 @@
 }
 
 void
-seahorse_pgp_expires_new (SeahorsePGPKey *pkey, GtkWindow *parent, guint index)
+seahorse_pgp_expires_new (SeahorsePgpSubkey *subkey, GtkWindow *parent)
 {
 	SeahorseWidget *swidget;
-	gpgme_subkey_t subkey;
 	GtkWidget *date, *expire;
-	gchar *title;
-	const gchar *userid;
-	
-	g_return_if_fail (pkey != NULL && SEAHORSE_IS_PGP_KEY (pkey));
-	g_return_if_fail (index <= seahorse_pgp_key_get_num_subkeys (pkey));
+	gulong expires;
+	gchar *label, *title;
 	
-	swidget = seahorse_object_widget_new ("expires", parent, SEAHORSE_OBJECT (pkey));
+	g_return_if_fail (subkey != NULL && SEAHORSE_IS_PGP_SUBKEY (subkey));
+
+	swidget = seahorse_widget_new_allow_multiple ("expires", parent);
 	g_return_if_fail (swidget != NULL);
+	g_object_set_data_full (G_OBJECT (swidget), "subkey", subkey, g_object_unref);
 	
-	g_object_set_data (G_OBJECT (swidget), "index", GUINT_TO_POINTER (index));
 	glade_xml_signal_connect_data (swidget->xml, "on_calendar_change_button_clicked",
 	                               G_CALLBACK (ok_clicked), swidget);
     
 	date = glade_xml_get_widget (swidget->xml, "calendar");    
 	g_return_if_fail (date != NULL);
-    
-	subkey = seahorse_pgp_key_get_nth_subkey (pkey, index);
-	g_return_if_fail (subkey != NULL);
 
 	expire = glade_xml_get_widget (swidget->xml, "expire");
 	glade_xml_signal_connect_data (swidget->xml, "on_expire_toggled",
 	                               G_CALLBACK (expires_toggled), swidget);
-	if (!seahorse_pgp_key_get_expires (pkey)) {
-		gtk_toggle_button_set_active  (GTK_TOGGLE_BUTTON (expire), TRUE);
+	
+	expires = seahorse_pgp_subkey_get_expires (subkey); 
+	if (!expires) {
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (expire), TRUE);
 		gtk_widget_set_sensitive (date, FALSE);
 	} else {
-		gtk_toggle_button_set_active  (GTK_TOGGLE_BUTTON (expire), FALSE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (expire), FALSE);
 		gtk_widget_set_sensitive (date, TRUE);
 	}
     
-	if (subkey->expires) {
+	if (expires) {
 		struct tm t;
-		time_t time = (time_t)subkey->expires;
-		if (gmtime_r(&time, &t)) {
+		time_t time = (time_t)expires;
+		if (gmtime_r (&time, &t)) {
 			gtk_calendar_select_month (GTK_CALENDAR (date), t.tm_mon, t.tm_year + 1900);
 			gtk_calendar_select_day (GTK_CALENDAR (date), t.tm_mday);
 		}
 	}
 	
-	userid = seahorse_object_get_label (SEAHORSE_OBJECT (pkey));
-	if (index)
-		title = g_strdup_printf (_("Expiry for Subkey %d of %s"), index, userid);
-	else
-		title = g_strdup_printf (_("Expiry for %s"), userid);
-   
-	gtk_window_set_title (GTK_WINDOW (glade_xml_get_widget (swidget->xml,
-		              swidget->name)), title);
+	label = seahorse_pgp_subkey_get_description (subkey);
+	title = g_strdup_printf (_("Expiry: %s"), label);
+	gtk_window_set_title (GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)), title);
+	g_free (title);
+	g_free (label);
 }

Modified: trunk/pgp/seahorse-pgp-generator.c
==============================================================================
--- trunk/pgp/seahorse-pgp-generator.c	(original)
+++ trunk/pgp/seahorse-pgp-generator.c	Fri Dec 12 23:54:26 2008
@@ -20,6 +20,7 @@
  */
 
 #include "seahorse-pgp-generator.h"
+#include <seahorse-pgp.h>
 #include <glib/gi18n-lib.h>
 #include <stdlib.h>
 #include <string.h>
@@ -30,7 +31,6 @@
 #include <seahorse-pgp-source.h>
 #include <config.h>
 #include <common/seahorse-registry.h>
-#include "seahorse-pgp.h"
 
 
 

Modified: trunk/pgp/seahorse-pgp-key-op.c
==============================================================================
--- trunk/pgp/seahorse-pgp-key-op.c	(original)
+++ trunk/pgp/seahorse-pgp-key-op.c	Fri Dec 12 23:54:26 2008
@@ -33,6 +33,8 @@
 #include "seahorse-util.h"
 #include "seahorse-libdialogs.h"
 
+#include "common/seahorse-object-list.h"
+
 #include "pgp/seahorse-gpgmex.h"
 #include "pgp/seahorse-pgp-key-op.h"
 #include "pgp/seahorse-pgp-operation.h"
@@ -159,45 +161,37 @@
 
 /* helper function for deleting @skey */
 static gpgme_error_t
-op_delete (SeahorsePGPKey *pkey, gboolean secret)
+op_delete (SeahorsePgpKey *pkey, gboolean secret)
 {
-    SeahorsePGPSource *psrc;
+	SeahorsePGPSource *psrc;
 	gpgme_error_t err;
+	gpgme_key_t key;
     
-    psrc = SEAHORSE_PGP_SOURCE (seahorse_object_get_source (SEAHORSE_OBJECT (pkey)));
-    g_return_val_if_fail (psrc && SEAHORSE_IS_PGP_SOURCE (psrc), GPG_E (GPG_ERR_INV_KEYRING));
+	psrc = SEAHORSE_PGP_SOURCE (seahorse_object_get_source (SEAHORSE_OBJECT (pkey)));
+	g_return_val_if_fail (psrc && SEAHORSE_IS_PGP_SOURCE (psrc), GPG_E (GPG_ERR_INV_KEYRING));
+	
+	g_object_ref (pkey);
 	
-	err = gpgme_op_delete (psrc->gctx, pkey->pubkey, secret);
+	seahorse_util_wait_until ((key = seahorse_pgp_key_get_public (pkey)) != NULL);
+	
+	err = gpgme_op_delete (psrc->gctx, key, secret);
 	if (GPG_IS_OK (err))
              seahorse_context_remove_object (SCTX_APP (), SEAHORSE_OBJECT (pkey));
 	
+	g_object_unref (pkey);
+	
 	return err;
 }
 
-/**
- * seahorse_pgp_key_op_delete:
- * @skey: #SeahorseKey to delete
- *
- * Tries to delete the key @skey.
- *
- * Returns: gpgme_error_t
- **/
 gpgme_error_t
-seahorse_pgp_key_op_delete (SeahorsePGPKey *pkey)
+seahorse_pgp_key_op_delete (SeahorsePgpKey *pkey)
 {
 	return op_delete (pkey, FALSE);
 }
 
-/**
- * seahorse_pgp_key_pair_op_delete:
- * @skpair: #SeahorsePGPKey to delete
- *
- * Tries to delete the key pair @pkey.
- *
- * Returns: gpgme_error_t
- **/
+
 gpgme_error_t
-seahorse_pgp_key_pair_op_delete (SeahorsePGPKey *pkey)
+seahorse_pgp_key_op_delete_pair (SeahorsePgpKey *pkey)
 {
 	return op_delete (pkey, TRUE);
 }
@@ -274,37 +268,68 @@
 
 /* Common edit operation */
 static gpgme_error_t
-edit_gpgme_key (SeahorsePGPSource *psrc, gpgme_key_t key, SeahorseEditParm *parms)
+edit_gpgme_key (gpgme_ctx_t ctx, gpgme_key_t key, SeahorseEditParm *parms)
 {
-    gpgme_data_t out;
-    gpgme_error_t err;
+	gboolean own_context = FALSE;
+	gpgme_data_t out;
+	gpgme_error_t gerr;
     
-    g_assert (psrc && SEAHORSE_IS_PGP_SOURCE (psrc));
+	g_assert (key);
+	g_assert (parms);
+	
+	gpgme_key_ref (key);
     
-    out = gpgmex_data_new ();
+	if (!ctx) {
+		ctx = seahorse_pgp_source_new_context ();
+		g_return_val_if_fail (ctx, GPG_E (GPG_ERR_GENERAL));
+		own_context = TRUE;
+	}
+    
+	out = gpgmex_data_new ();
     
-    /* do edit callback, release data */
-    err = gpgme_op_edit (psrc->gctx, key, seahorse_pgp_key_op_edit, parms, out);
-    gpgmex_data_release (out);
+	/* do edit callback, release data */
+	gerr = gpgme_op_edit (ctx, key, seahorse_pgp_key_op_edit, parms, out);
+	gpgmex_data_release (out);
     
-    return err;
+	if (own_context)
+		gpgme_release (ctx);
+	
+	gpgme_key_unref (key);
+	
+	return gerr;
 }
 
 static gpgme_error_t
-edit_key (SeahorsePGPKey *pkey, SeahorseEditParm *parms)
+edit_refresh_gpgme_key (gpgme_ctx_t ctx, gpgme_key_t key, SeahorseEditParm *parms)
 {
-    SeahorsePGPSource *psrc;
-    gpgme_error_t err;
+	gpgme_error_t gerr;
+	
+	gerr = edit_gpgme_key (ctx, key, parms);
+	if (GPG_IS_OK (gerr))
+		seahorse_pgp_key_refresh_matching (key);
+	
+	return gerr;
+}
+
+static gpgme_error_t
+edit_key (SeahorsePgpKey *pkey, SeahorseEditParm *parms)
+{
+	SeahorsePGPSource *psrc;
+	gpgme_error_t err;
+	gpgme_key_t key;
     
-    psrc = SEAHORSE_PGP_SOURCE (seahorse_object_get_source (SEAHORSE_OBJECT (pkey)));
-    g_return_val_if_fail (psrc && SEAHORSE_IS_PGP_SOURCE (psrc), GPG_E (GPG_ERR_INV_KEYRING));
+	psrc = SEAHORSE_PGP_SOURCE (seahorse_object_get_source (SEAHORSE_OBJECT (pkey)));
+	g_return_val_if_fail (psrc && SEAHORSE_IS_PGP_SOURCE (psrc), GPG_E (GPG_ERR_INV_KEYRING));
+
+	g_object_ref (pkey);
+	
+	seahorse_util_wait_until ((key = seahorse_pgp_key_get_public (pkey)) != NULL);
   
-    err = edit_gpgme_key (psrc, pkey->pubkey, parms);
+	err = edit_refresh_gpgme_key (psrc->gctx, key, parms);
 
-    if (GPG_IS_OK (err))
-	seahorse_pgp_key_reload (pkey);
+	g_object_unref (pkey);
     
-    return err;
+	return err;
 }
 
 typedef struct
@@ -471,68 +496,86 @@
 	return next_state;
 }
 
-/**
- * seahorse_pgp_key_op_sign:
- * @skey: #SeahorseKey to sign
- * @index: User ID to sign, 0 is all user IDs
- * @check: #SeahorseSignCheck
- * @options: #SeahorseSignOptions
- *
- * Tries to sign user ID @index of @skey with the default key and the given options.
- *
- * Returns: Error value
- **/
+static gpgme_error_t
+sign_process (gpgme_key_t signed_key, gpgme_key_t signing_key, guint sign_index, 
+              SeahorseSignCheck check, SeahorseSignOptions options)
+{
+	SeahorseEditParm *parms;
+	SignParm sign_parm;
+	gpgme_ctx_t ctx;
+	gpgme_error_t gerr;
+
+	ctx = seahorse_pgp_source_new_context ();
+	g_return_val_if_fail (ctx, GPG_E (GPG_ERR_GENERAL));
+	
+        gerr = gpgme_signers_add (ctx, signing_key);
+        if (!GPG_IS_OK (gerr))
+        	return gerr;
+	
+	sign_parm.index = sign_index;
+	sign_parm.expire = ((options & SIGN_EXPIRES) != 0);
+	sign_parm.check = check;
+	sign_parm.command = g_strdup_printf ("%s%ssign", 
+	                                     (options & SIGN_NO_REVOKE) ? "nr" : "",
+	                                     (options & SIGN_LOCAL) ? "l" : "");
+
+	parms = seahorse_edit_parm_new (SIGN_START, sign_action, sign_transit, &sign_parm);
+
+	gerr =  edit_refresh_gpgme_key (ctx, signed_key, parms);
+	g_free (sign_parm.command);
+	g_free (parms);
+	 
+	gpgme_release (ctx);
+	
+	/* If it was already signed then it's not an error */
+	if (gpgme_err_code (gerr) == GPG_ERR_EALREADY)
+		gerr = GPG_OK;
+	    
+	return gerr;
+}
+
 gpgme_error_t
-seahorse_pgp_key_op_sign (SeahorsePGPKey *pkey, SeahorsePGPKey *signer, 
-                          const guint index, SeahorseSignCheck check, 
-                          SeahorseSignOptions options)
-{
-    SeahorseSource *sksrc;
-    SignParm *sign_parm;
-    SeahorseEditParm *parms;
-    gpgme_error_t err;
-    guint real_index = seahorse_pgp_key_get_actual_uid(pkey, index);
-    guint num_userids = seahorse_pgp_key_get_num_uids (pkey);
-    guint num_photoids = seahorse_pgp_key_get_num_photoids (pkey);
-    
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-    DEBUG_OPERATION(("SignKey: index = %i,real_index = %i, num_userids = %i, num_photoids = %i\n", index, real_index, num_userids, num_photoids));
-    g_return_val_if_fail (real_index <= (num_userids + num_photoids), GPG_E (GPG_ERR_INV_VALUE));
-    
-    sign_parm = g_new (SignParm, 1);
-    sign_parm->index = real_index;
-    sign_parm->expire = ((options & SIGN_EXPIRES) != 0);
-    sign_parm->check = check;
-
-    sign_parm->command = g_strdup_printf ("%s%ssign", 
-                                (options & SIGN_NO_REVOKE) ? "nr" : "",
-                                (options & SIGN_LOCAL) ? "l" : "");
-    
-    if (signer) {
-        sksrc = seahorse_object_get_source (SEAHORSE_OBJECT (pkey));
-        
-        g_assert (SEAHORSE_IS_PGP_SOURCE (sksrc));
-        g_assert (SEAHORSE_PGP_SOURCE (sksrc)->gctx);
-        
-        gpgme_signers_clear (SEAHORSE_PGP_SOURCE (sksrc)->gctx);
+seahorse_pgp_key_op_sign_uid (SeahorsePgpUid *uid,  SeahorsePgpKey *signer, 
+                              SeahorseSignCheck check, SeahorseSignOptions options)
+{
+	gpgme_key_t signing_key;
+	gpgme_key_t signed_key;
+	guint sign_index;
+	
+	seahorse_pgp_key_get_private (signer);
 
-        g_return_val_if_fail (signer->seckey != NULL, GPG_E (GPG_ERR_INV_VALUE));
-        err = gpgme_signers_add (SEAHORSE_PGP_SOURCE (sksrc)->gctx, signer->seckey);
-        if (!GPG_IS_OK (err))
-            return err;
-    }
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (signer), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	
+	signing_key = seahorse_pgp_key_get_private (signer);
+	g_return_val_if_fail (signing_key, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	
+	signed_key = seahorse_pgp_uid_get_pubkey (uid);
+	g_return_val_if_fail (signing_key, GPG_E (GPG_ERR_INV_VALUE));
+	
+	sign_index = seahorse_pgp_uid_get_gpgme_index (uid) + 1;
+	
+	return sign_process (signed_key, signing_key, sign_index, check, options);
+}
 
-    
-    parms = seahorse_edit_parm_new (SIGN_START, sign_action, sign_transit, sign_parm);
-    
-    err =  edit_key (pkey, parms);
-    g_free (sign_parm->command);
- 
-    /* If it was already signed then it's not an error */
-    if (!GPG_IS_OK (err) && gpgme_err_code (err) == GPG_ERR_EALREADY)
-        err = GPG_OK;
-    
-    return err;
+gpgme_error_t
+seahorse_pgp_key_op_sign (SeahorsePgpKey *pkey, SeahorsePgpKey *signer, 
+                          SeahorseSignCheck check, SeahorseSignOptions options)
+{
+	gpgme_key_t signing_key;
+	gpgme_key_t signed_key;
+	
+	seahorse_pgp_key_get_private (signer);
+
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (signer), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	
+	signing_key = seahorse_pgp_key_get_private (signer);
+	g_return_val_if_fail (signing_key, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	
+	signed_key = seahorse_pgp_key_get_public (pkey);
+
+	return sign_process (signed_key, signing_key, 0, check, options);
 }
 
 typedef enum {
@@ -640,16 +683,8 @@
     return next_state;
 }
 
-/**
- * seahorse_pgp_key_pair_op_change_pass:
- * @skpair: #SeahorseKeyPair whose passphrase to change
- *
- * Tries to change the passphrase of @pkey. 
- *
- * Returns: Error value
- **/
 gpgme_error_t
-seahorse_pgp_key_pair_op_change_pass (SeahorsePGPKey *pkey)
+seahorse_pgp_key_op_change_pass (SeahorsePgpKey *pkey)
 {
 	SeahorseEditParm *parms;
 	gpgme_error_t err;
@@ -788,7 +823,7 @@
  * Returns: Error value
  **/
 gpgme_error_t
-seahorse_pgp_key_op_set_trust (SeahorsePGPKey *pkey, SeahorseValidity trust)
+seahorse_pgp_key_op_set_trust (SeahorsePgpKey *pkey, SeahorseValidity trust)
 {
 	SeahorseEditParm *parms;
 	gint menu_choice;
@@ -909,14 +944,13 @@
  * Returns: Error value
  **/
 gpgme_error_t
-seahorse_pgp_key_op_set_disabled (SeahorsePGPKey *pkey, gboolean disabled)
+seahorse_pgp_key_op_set_disabled (SeahorsePgpKey *pkey, gboolean disabled)
 {
 	gchar *command;
 	SeahorseEditParm *parms;
 	
 	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-	/* Make sure changing disabled */
-	g_return_val_if_fail (disabled != pkey->pubkey->disabled, GPG_E (GPG_ERR_INV_VALUE));
+	
 	/* Get command and op */
 	if (disabled)
 		command = "disable";
@@ -1048,39 +1082,26 @@
 	return next_state;
 }
 
-/**
- * seahorse_pgp_key_pair_op_set_expires:
- * @skpair: #SeahorseKeyPair whose expiration date to change
- * @index: Index of key to change, 0 being the primary key
- * @expires: New expiration date, 0 being never
- *
- * Tries to change the expiration date of the key at @index of @skpair to @expires.
- *
- * Returns: Error value
- **/
 gpgme_error_t
-seahorse_pgp_key_pair_op_set_expires (SeahorsePGPKey *pkey,
-				  const guint index, const time_t expires)
+seahorse_pgp_key_op_set_expires (SeahorsePgpSubkey *subkey, const time_t expires)
 {
-	ExpireParm *exp_parm;
+	ExpireParm exp_parm;
 	SeahorseEditParm *parms;
-	gpgme_subkey_t subkey;
+	gpgme_key_t key;
+	gpgme_error_t gerr;
 	
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));    
-    g_return_val_if_fail (seahorse_object_get_usage (SEAHORSE_OBJECT (pkey)) == SEAHORSE_USAGE_PRIVATE_KEY, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-
-	subkey = seahorse_pgp_key_get_nth_subkey (pkey, index);
-
-	/* Make sure changing expires */
-	g_return_val_if_fail (subkey != NULL && expires != subkey->expires, FALSE);
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (subkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (expires != seahorse_pgp_subkey_get_expires (subkey), GPG_E (GPG_ERR_INV_VALUE));
 	
-	exp_parm = g_new (ExpireParm, 1);
-	exp_parm->index = index;
-	exp_parm->expires = expires;
+	key = seahorse_pgp_subkey_get_pubkey (subkey);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
 	
-	parms = seahorse_edit_parm_new (EXPIRE_START, edit_expire_action, edit_expire_transit, exp_parm);
+	exp_parm.index = seahorse_pgp_subkey_get_index (subkey); 
+	exp_parm.expires = expires;
 	
-	return edit_key (pkey, parms);
+	parms = seahorse_edit_parm_new (EXPIRE_START, edit_expire_action, edit_expire_transit, &exp_parm);
+	
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }
 
 typedef enum {
@@ -1189,26 +1210,22 @@
 	return next_state;
 }
 
-/**
- * seahorse_pgp_key_pair_op_add_revoker:
- * @skpair: #SeahorseKeyPair to add a revoker to
- *
- * Tries to add the default key as a revoker for @skpair.
- *
- * Returns: Error value
- **/
 gpgme_error_t
-seahorse_pgp_key_pair_op_add_revoker (SeahorsePGPKey *pkey, SeahorsePGPKey *revoker)
+seahorse_pgp_key_op_add_revoker (SeahorsePgpKey *pkey, SeahorsePgpKey *revoker)
 {
 	SeahorseEditParm *parms;
+	GQuark id;
 	
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));    
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (revoker), GPG_E (GPG_ERR_WRONG_KEY_USAGE));    
-    g_return_val_if_fail (seahorse_object_get_usage (SEAHORSE_OBJECT (pkey)) == SEAHORSE_USAGE_PRIVATE_KEY, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-    g_return_val_if_fail (seahorse_object_get_usage (SEAHORSE_OBJECT (revoker)) == SEAHORSE_USAGE_PRIVATE_KEY, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));    
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (revoker), GPG_E (GPG_ERR_WRONG_KEY_USAGE));    
+	g_return_val_if_fail (seahorse_object_get_usage (SEAHORSE_OBJECT (pkey)) == SEAHORSE_USAGE_PRIVATE_KEY, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (seahorse_object_get_usage (SEAHORSE_OBJECT (revoker)) == SEAHORSE_USAGE_PRIVATE_KEY, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
 
+	id = seahorse_object_get_id (SEAHORSE_OBJECT (revoker));
+	g_return_val_if_fail (id, GPG_E (GPG_ERR_INV_VALUE));
+	
 	parms = seahorse_edit_parm_new (ADD_REVOKER_START, add_revoker_action,
-		add_revoker_transit, (gpointer)seahorse_pgp_key_get_id (revoker->pubkey, 0));
+	                                add_revoker_transit, (gpointer)seahorse_pgp_key_get_rawid (id));
 	
 	return edit_key (pkey, parms);
 }
@@ -1337,20 +1354,9 @@
 	return next_state;
 }
 
-/**
- * seahorse_pgp_key_pair_op_add_uid:
- * @skpair: #SeahorseKeyPair to add a user ID to
- * @name: New user ID name. Must be at least 5 characters long
- * @email: Optional email address
- * @comment: Optional comment
- *
- * Tries to add a new user ID to @skpair with the given @name, @email, and @comment.
- *
- * Returns: Error value
- **/
 gpgme_error_t
-seahorse_pgp_key_pair_op_add_uid (SeahorsePGPKey *pkey, const gchar *name, 
-                              const gchar *email, const gchar *comment)
+seahorse_pgp_key_op_add_uid (SeahorsePgpKey *pkey, const gchar *name, 
+                             const gchar *email, const gchar *comment)
 {
 	SeahorseEditParm *parms;
 	UidParm *uid_parm;
@@ -1481,20 +1487,9 @@
 	return next_state;
 }
 
-/**
- * seahorse_pgp_key_pair_op_add_subkey:
- * @skpair: #SeahorseKeyPair to add a subkey to
- * @type: #SeahorseKeyType of new subkey, must be DSA, ELGAMAL, or an RSA type
- * @length: Length of new subkey, must be within #SeahorseKeyLength ranges for @type
- * @expires: Expiration date of new subkey, 0 being never
- *
- * Tries to add a new subkey to @skpair given @type, @length, and @expires.
- *
- * Returns: Error value
- **/
 gpgme_error_t
-seahorse_pgp_key_pair_op_add_subkey (SeahorsePGPKey *pkey, const SeahorseKeyEncType type, 
-                                 const guint length, const time_t expires)
+seahorse_pgp_key_op_add_subkey (SeahorsePgpKey *pkey, const SeahorseKeyEncType type, 
+                                const guint length, const time_t expires)
 {
 	SeahorseEditParm *parms;
 	SubkeyParm *key_parm;
@@ -1631,27 +1626,23 @@
 	return next_state;
 }
 
-/**
- * seahorse_pgp_key_op_del_subkey:
- * @skey: #SeahorseKey whose subkey to delete
- * @index: Index of subkey to delete, must be at least 1
- *
- * Tries to delete subkey @index from @skey.
- *
- * Returns: Error value
- **/
 gpgme_error_t
-seahorse_pgp_key_op_del_subkey (SeahorsePGPKey *pkey, const guint index)
+seahorse_pgp_key_op_del_subkey (SeahorsePgpSubkey *subkey)
 {
 	SeahorseEditParm *parms;
+	gpgme_key_t key;
+	int index;
 	
-	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-	g_return_val_if_fail (index >= 1 && index <= seahorse_pgp_key_get_num_subkeys (pkey), GPG_E (GPG_ERR_INV_VALUE));
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (subkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
 	
+	key = seahorse_pgp_subkey_get_pubkey (subkey);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
+	
+	index = seahorse_pgp_subkey_get_index (subkey);
 	parms = seahorse_edit_parm_new (DEL_KEY_START, del_key_action,
-		del_key_transit, (gpointer)index);
+	                                del_key_transit, GUINT_TO_POINTER (index));
 	
-	return edit_key (pkey, parms);
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }
 
 typedef struct
@@ -1807,41 +1798,31 @@
 	return next_state;
 }
 
-/**
- * seahorse_pgp_key_op_revoke_subkey:
- * @skey: #SeahorseKey whose subkey to revoke
- * @index: Index of subkey to revoke, must be at least 1
- * @reason: #SeahorseRevokeReason for revoking the key
- * @description: Optional description of revocation
- *
- * Tries to revoke subkey @index of @skey given @reason and @description.
- *
- * Returns: Error value
- **/
 gpgme_error_t
-seahorse_pgp_key_op_revoke_subkey (SeahorsePGPKey *pkey, guint index,
-			                   SeahorseRevokeReason reason, const gchar *description)
+seahorse_pgp_key_op_revoke_subkey (SeahorsePgpSubkey *subkey, SeahorseRevokeReason reason, 
+                                   const gchar *description)
 {
-	RevSubkeyParm *rev_parm;
+	RevSubkeyParm rev_parm;
 	SeahorseEditParm *parms;
-	gpgme_subkey_t subkey;
+	gpgme_subkey_t gsubkey;
+	gpgme_key_t key;
 	
-	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-	/* Check index range */
-	g_return_val_if_fail (index >= 1 && index <= seahorse_pgp_key_get_num_subkeys (pkey), GPG_E (GPG_ERR_INV_VALUE));
-	/* Make sure not revoked */
-	subkey = seahorse_pgp_key_get_nth_subkey (pkey, index);
-	g_return_val_if_fail (subkey != NULL && !subkey->revoked, GPG_E (GPG_ERR_INV_VALUE));
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (subkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	
+	gsubkey = seahorse_pgp_subkey_get_subkey (subkey);
+	g_return_val_if_fail (!gsubkey->revoked, GPG_E (GPG_ERR_INV_VALUE));
 	
-	rev_parm = g_new0 (RevSubkeyParm, 1);
-	rev_parm->index = index;
-	rev_parm->reason = reason;
-	rev_parm->description = description;
+	key = seahorse_pgp_subkey_get_pubkey (subkey);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
+	
+	rev_parm.index = seahorse_pgp_subkey_get_index (subkey);
+	rev_parm.reason = reason;
+	rev_parm.description = description;
 	
 	parms = seahorse_edit_parm_new (REV_SUBKEY_START, rev_subkey_action,
-		rev_subkey_transit, rev_parm);
+	                                rev_subkey_transit, &rev_parm);
 	
-	return edit_key (pkey, parms);
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }
 
 typedef struct {
@@ -1953,30 +1934,29 @@
 }
                 
 gpgme_error_t   
-seahorse_pgp_key_op_primary_uid (SeahorsePGPKey *pkey, const guint index)
+seahorse_pgp_key_op_primary_uid (SeahorsePgpUid *uid)
 {
-    PrimaryParm *pri_parm;
-    SeahorseEditParm *parms;
-    SeahorsePGPUid *uid;
-    guint real_index = seahorse_pgp_key_get_actual_uid(pkey, index);
-    
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-    
-    /* Check index range */
-    g_return_val_if_fail (real_index >= 1 && real_index <= (seahorse_pgp_key_get_num_uids (pkey) + seahorse_pgp_key_get_num_photoids(pkey)), GPG_E (GPG_ERR_INV_VALUE));
-
-    /* Make sure not revoked */
-    uid = seahorse_pgp_key_get_uid (pkey, index - 1);
-    g_return_val_if_fail (uid != NULL && !uid->userid->revoked && !uid->userid->invalid, 
-                          GPG_E (GPG_ERR_INV_VALUE));
-  
-    pri_parm = g_new0 (PrimaryParm, 1);
-    pri_parm->index = real_index;
+	PrimaryParm pri_parm;
+	SeahorseEditParm *parms;
+	gpgme_user_id_t userid;
+	gpgme_key_t key;
+
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+    
+	/* Make sure not revoked */
+	userid = seahorse_pgp_uid_get_userid (uid);
+	g_return_val_if_fail (userid != NULL && !userid->revoked && !userid->invalid, 
+	                      GPG_E (GPG_ERR_INV_VALUE));
+    
+	key = seahorse_pgp_uid_get_pubkey (uid);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
+    
+	pri_parm.index = seahorse_pgp_uid_get_actual_index (uid);
    
-    parms = seahorse_edit_parm_new (PRIMARY_START, primary_action,
-                primary_transit, pri_parm);
+	parms = seahorse_edit_parm_new (PRIMARY_START, primary_action,
+	                                primary_transit, &pri_parm);
  
-    return edit_key (pkey, parms);
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }
 
 
@@ -2104,31 +2084,23 @@
 }
                 
 gpgme_error_t   
-seahorse_pgp_key_op_del_uid (SeahorsePGPKey *pkey, const guint index)
+seahorse_pgp_key_op_del_uid (SeahorsePgpUid *uid)
 {
-    DelUidParm *del_uid_parm;
-    SeahorseEditParm *parms;
-    SeahorsePGPUid *uid;
-    guint real_index = seahorse_pgp_key_get_actual_uid(pkey, index);
- 
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	DelUidParm del_uid_parm;
+	SeahorseEditParm *parms;
+	gpgme_key_t key;
+	
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
     
-    /* Check index range */
-    DEBUG_OPERATION(("Del UID: uid %u\n", index));
-    g_return_val_if_fail (real_index >= 1 && real_index <= (seahorse_pgp_key_get_num_uids (pkey) + seahorse_pgp_key_get_num_photoids(pkey)), GPG_E (GPG_ERR_INV_VALUE));
-
-    /* Make sure not revoked */
-    uid = seahorse_pgp_key_get_uid (pkey, index - 1);
-    g_return_val_if_fail (uid != NULL && !uid->userid->revoked && !uid->userid->invalid, 
-                            GPG_E (GPG_ERR_INV_VALUE));
+	key = seahorse_pgp_uid_get_pubkey (uid);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
   
-    del_uid_parm = g_new0 (DelUidParm, 1);
-    del_uid_parm->index = real_index;
+	del_uid_parm.index = seahorse_pgp_uid_get_actual_index (uid);
    
-    parms = seahorse_edit_parm_new (DEL_UID_START, del_uid_action,
-                del_uid_transit, del_uid_parm);
+	parms = seahorse_edit_parm_new (DEL_UID_START, del_uid_action,
+	                                del_uid_transit, &del_uid_parm);
  
-    return edit_key (pkey, parms);
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }
 
 typedef struct {
@@ -2239,69 +2211,53 @@
     return next_state;
 }
 
-/**
- * seahorse_pgp_key_op_photoid_add:
- * @skey: #SeahorseKey to add photoid to
- * @uri: path to jpeg image to be added
- *
- * Tries to add @uri to @skey as a photoid.
- *
- * Returns: Error value
- **/
 gpgme_error_t 
-seahorse_pgp_key_op_photoid_add	(SeahorsePGPKey *pkey, const gchar *filename)
+seahorse_pgp_key_op_photo_add (SeahorsePgpKey *pkey, const gchar *filename)
 {
 	SeahorseEditParm *parms;
-	PhotoIdAddParm *photoid_add_parm;
-	gpgme_error_t err;
+	PhotoIdAddParm photoid_add_parm;
+	gpgme_key_t key;
 	
-	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (key), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (filename, GPG_E (GPG_ERR_INV_VALUE));
+      
+	key = seahorse_pgp_key_get_public (pkey);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
     
-	photoid_add_parm = g_new0 (PhotoIdAddParm, 1);
-	photoid_add_parm->filename = filename;
+	photoid_add_parm.filename = filename;
 	
 	parms = seahorse_edit_parm_new (PHOTO_ID_ADD_START, photoid_add_action,
-                                    photoid_add_transit, photoid_add_parm);
+	                                photoid_add_transit, &photoid_add_parm);
 	
-	/* add photoid */
-	err = edit_key (pkey, parms);
-	
-    return err;
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }
 
-/**
- * seahorse_pgp_key_op_photoid_delete:
- * @skey: #SeahorseKey whose photoid to delete
- * @uid: uid of photoid to delete
- *
- * Tries to delete photoid @uid from @skey. This uses the transit
- * and action functions from seahorse_key_op_del_uid.
- *
- * Returns: Error value
- **/
 gpgme_error_t 
-seahorse_pgp_key_op_photoid_delete	(SeahorsePGPKey *pkey, guint uid)
+seahorse_pgp_key_op_photo_delete (SeahorsePgpPhoto *photo)
 {
-    DelUidParm *del_uid_parm;
-    SeahorseEditParm *parms;
+	DelUidParm del_uid_parm;
+	SeahorseEditParm *parms;
+	gpgme_key_t key;
  
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	g_return_val_if_fail (SEAHORSE_IS_PGP_PHOTO (photo), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
       
-    del_uid_parm = g_new0 (DelUidParm, 1);
-    del_uid_parm->index = uid;
+	key = seahorse_pgp_photo_get_pubkey (photo);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
+    
+	del_uid_parm.index = seahorse_pgp_photo_get_index (photo);
    
-    parms = seahorse_edit_parm_new (DEL_UID_START, del_uid_action,
-                                    del_uid_transit, del_uid_parm);
+	parms = seahorse_edit_parm_new (DEL_UID_START, del_uid_action,
+	                                del_uid_transit, &del_uid_parm);
  
-    return edit_key (pkey, parms);
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }
 
 typedef struct {
-	gpgmex_photo_id_t list;
-    gpgmex_photo_id_t first;
+	GList *photos;
 	gint uid;
 	guint num_uids;
 	char *output_file;
+	gpgme_key_t key;
 } PhotoIdLoadParm;
 
 typedef enum {
@@ -2345,122 +2301,109 @@
 photoid_load_transit (guint current_state, gpgme_status_code_t status,
                       const gchar *args, gpointer data, gpgme_error_t *err)
 {
-    PhotoIdLoadParm *parm = (PhotoIdLoadParm*)data;
-    guint next_state = 0;
-    struct stat buf;
-    GError *error = NULL;
+	PhotoIdLoadParm *parm = (PhotoIdLoadParm*)data;
+	SeahorsePgpPhoto *photo;
+	GdkPixbuf *pixbuf;
+	guint next_state = 0;
+	struct stat st;
+	GError *error = NULL;
 	
-    switch (current_state) {
+	switch (current_state) {
     
-    /* start, get photoid list */
-    case PHOTO_ID_LOAD_START:
-        if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT))
-            next_state = PHOTO_ID_LOAD_SELECT;
-        else {
-            *err = GPG_E (GPG_ERR_GENERAL);
-            g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
-        }
-        break;
-    case PHOTO_ID_LOAD_SELECT:
+	/* start, get photoid list */
+	case PHOTO_ID_LOAD_START:
+		if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT))
+			next_state = PHOTO_ID_LOAD_SELECT;
+		else {
+			*err = GPG_E (GPG_ERR_GENERAL);
+			g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
+		}
+		break;
+		
+	case PHOTO_ID_LOAD_SELECT:
 		if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT)) {
 			next_state = PHOTO_ID_LOAD_OUTPUT_IMAGE;
 		} else {
-            *err = GPG_E (GPG_ERR_GENERAL);
-            g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
-        }
+			*err = GPG_E (GPG_ERR_GENERAL);
+			g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
+		}
 		break;
-    case PHOTO_ID_LOAD_OUTPUT_IMAGE:
-
-        if (g_file_test (parm->output_file, G_FILE_TEST_EXISTS)) {
-
-            DEBUG_OPERATION (("PhotoIDLoad uid %i/%i from file %s\n", parm->uid, 
-                             parm->num_uids, parm->output_file));
-            DEBUG_OPERATION(("PhotoIDLoad first %s\n", parm->first ? "NOT_NULL" : "NULL"));
-            DEBUG_OPERATION(("PhotoIDLoad list %s\n", parm->list ? "NOT_NULL" : "NULL"));
-            
-            if ((parm->first == NULL) && (parm->list == NULL)) {
-                parm->first = gpgmex_photo_id_alloc (parm->uid);
-                parm->list = parm->first;
-                parm->list->next = NULL;                     
-            } else {
-                parm->list->next = gpgmex_photo_id_alloc (parm->uid);
-                parm->list = parm->list->next;
-                parm->list->next = NULL;     
-            }
-            
-            DEBUG_OPERATION (("PhotoIDLoad After List Setup\n"));
-            
-            if (g_stat (parm->output_file, &buf) == -1) {
-                g_warning ("couldn't stat output image file '%s': %s", parm->output_file,
-                           g_strerror (errno));
-            
-            } else if (buf.st_size > 0) {
-                DEBUG_OPERATION (("PhotoIDLoad Loading %s\n", parm->output_file));
-                parm->list->photo = gdk_pixbuf_new_from_file (parm->output_file, &error);
-    
-                if ((parm->list->photo == NULL) || (error != NULL)) {
-                    g_warning ("Loading image %s failed: %s", parm->output_file,
-                               error ? error->message : "unknown");
-                    g_error_free (error);
-                }
-            }
-            
-            g_unlink (parm->output_file);
-        
-            if (parm->list->photo == NULL) {
-                /* Load a 'missing' icon */
-                parm->list->photo = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), 
-                                                              "gnome-unknown", 48, 0, NULL);
-                if (parm->list->photo  == NULL) {
-                    g_critical ("couldn't load 'gnome-unknown' icon");
-                    *err = GPG_E (GPG_ERR_GENERAL);
-                    break;
-                }
-            }
-        }
-    
-        if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT)) {
+		
+	case PHOTO_ID_LOAD_OUTPUT_IMAGE:
+		
+		if (g_file_test (parm->output_file, G_FILE_TEST_EXISTS)) {
+
+			photo = seahorse_pgp_photo_new (parm->key, NULL, parm->uid);
+			parm->photos = g_list_append (parm->photos, photo);
+			
+			if (g_stat (parm->output_file, &st) == -1) {
+				g_warning ("couldn't stat output image file '%s': %s", parm->output_file,
+				           g_strerror (errno));
+			    
+			} else if (st.st_size > 0) {
+				pixbuf = gdk_pixbuf_new_from_file (parm->output_file, &error);
+				if (pixbuf == NULL) {
+					g_warning ("Loading image %s failed: %s", parm->output_file,
+					           error && error->message ? error->message : "unknown");
+					g_error_free (error);
+				} 
+			}
+			
+			g_unlink (parm->output_file);
+			
+			/* Load a 'missing' icon */
+			if (!pixbuf) {
+				pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), 
+				                                   "gnome-unknown", 48, 0, NULL);
+			}
+			    
+			seahorse_pgp_photo_set_pixbuf (photo, pixbuf);
+			g_object_unref (pixbuf);
+		}
+	
+		if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT)) {
 			next_state = PHOTO_ID_LOAD_DESELECT;
 		} else {
-            *err = GPG_E (GPG_ERR_GENERAL);
-            g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
-        }
-        
-        break;
-    case PHOTO_ID_LOAD_DESELECT:
-    	if (parm->uid < parm->num_uids) {
-    		parm->uid = parm->uid + 1;
-    		DEBUG_OPERATION (("PhotoIDLoad Next UID %i\n", parm->uid));
-            
-    		if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT)) {
+			*err = GPG_E (GPG_ERR_GENERAL);
+			g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
+		}
+		break;
+		
+	case PHOTO_ID_LOAD_DESELECT:
+		if (parm->uid < parm->num_uids) {
+			parm->uid = parm->uid + 1;
+			DEBUG_OPERATION (("PhotoIDLoad Next UID %i\n", parm->uid));
+			if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT)) {
 				next_state = PHOTO_ID_LOAD_SELECT;
 			} else {
-	            *err = GPG_E (GPG_ERR_GENERAL);
-	            g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
-	        }
-        } else {
+				*err = GPG_E (GPG_ERR_GENERAL);
+				g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
+			}
+		} else {
 			if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT)) {
 				next_state = PHOTO_ID_LOAD_QUIT;
 				DEBUG_OPERATION (("PhotoIDLoad Quiting Load\n"));
 			} else {
-	            *err = GPG_E (GPG_ERR_GENERAL);
-	            g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
-	        }
-        }
-        break;
-    case PHOTO_ID_LOAD_QUIT:
-        /* Shouldn't be reached */
-        *err = GPG_E (GPG_ERR_GENERAL);
-        DEBUG_OPERATION (("PhotoIDLoad Reached Quit\n"));
-        g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
-        break;
-    default:
-        *err = GPG_E (GPG_ERR_GENERAL);
-        g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
-        break;
-    }
+				*err = GPG_E (GPG_ERR_GENERAL);
+				g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
+			}
+		}
+		break;
+		
+	case PHOTO_ID_LOAD_QUIT:
+		/* Shouldn't be reached */
+		*err = GPG_E (GPG_ERR_GENERAL);
+		DEBUG_OPERATION (("PhotoIDLoad Reached Quit\n"));
+		g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
+		break;
+		
+	default:
+		*err = GPG_E (GPG_ERR_GENERAL);
+		g_return_val_if_reached (PHOTO_ID_LOAD_ERROR);
+		break;
+	}
     
-    return next_state;
+	return next_state;
 }
 
 /**
@@ -2473,87 +2416,93 @@
  * Returns: Error value
  **/
 gpgme_error_t 
-seahorse_pgp_key_op_photoid_load (SeahorsePGPSource *psrc, gpgme_key_t key, 
-                                  gpgmex_photo_id_t *photoids)
+seahorse_pgp_key_op_photos_load (SeahorsePgpKey *pkey)
 {
-    /* Make sure there's enough room for the .jpg extension */
-    gchar image_path[]    = "/tmp/seahorse-photoid-XXXXXX\0\0\0\0";
+	/* Make sure there's enough room for the .jpg extension */
+	gchar image_path[]    = "/tmp/seahorse-photoid-XXXXXX\0\0\0\0";
     
-    SeahorseEditParm *parms;
-    PhotoIdLoadParm *photoid_load_parm;
-    gpgme_error_t err;
-    const gchar *oldpath;
-    gchar *path;
-    guint fd;
-
-    g_return_val_if_fail(*photoids == NULL, GPG_E (GPG_ERR_GENERAL));
-    g_return_val_if_fail (SEAHORSE_IS_PGP_SOURCE (psrc), 
-                          GPG_E (GPG_ERR_GENERAL));
-    g_return_val_if_fail (key && seahorse_pgp_key_get_id (key, 0), 
-                          GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-
-    DEBUG_OPERATION (("PhotoIDLoad Start\n"));
-    
-    fd = g_mkstemp (image_path);
-    if(fd == -1) 
-        err = GPG_E(GPG_ERR_GENERAL);
-    
-    else {
-
-        g_unlink(image_path);
-        close(fd);
-        strcat (image_path, ".jpg");
+	SeahorseEditParm *parms;
+	PhotoIdLoadParm photoid_load_parm;
+	gpgme_error_t gerr;
+	gpgme_key_t key;
+	const gchar *oldpath;
+	const gchar *keyid;
+	gchar *path;
+	guint fd;
+
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+	
+	key = seahorse_pgp_key_get_public (pkey);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
+	g_return_val_if_fail (key->subkeys && key->subkeys->keyid, GPG_E (GPG_ERR_INV_VALUE));
+	keyid = key->subkeys->keyid;
+	
+	DEBUG_OPERATION (("PhotoIDLoad Start\n"));
+    
+	fd = g_mkstemp (image_path);
+	if(fd == -1) { 
+		gerr = GPG_E(GPG_ERR_GENERAL);
+    
+	} else {
+
+		g_unlink(image_path);
+		close(fd);
+		strcat (image_path, ".jpg");
         
-        photoid_load_parm = g_new0 (PhotoIdLoadParm, 1);
-        photoid_load_parm->uid = 1;
-        photoid_load_parm->num_uids = 0;
-        photoid_load_parm->list = *photoids;
-        photoid_load_parm->first = NULL;
-        photoid_load_parm->output_file = image_path;
+		photoid_load_parm.uid = 1;
+		photoid_load_parm.num_uids = 0;
+		photoid_load_parm.photos = NULL;
+		photoid_load_parm.output_file = image_path;
+		photoid_load_parm.key = key;
         
-        DEBUG_OPERATION (("PhotoIdLoad KeyID %s\n", seahorse_pgp_key_get_id (key, 0)));
-        err = gpgmex_op_num_uids (NULL, seahorse_pgp_key_get_id (key, 0),
-                                  &(photoid_load_parm->num_uids));
-        DEBUG_OPERATION (("PhotoIDLoad Number of UIDs %i\n", photoid_load_parm->num_uids));
+		DEBUG_OPERATION (("PhotoIdLoad KeyID %s\n", keyid));
+		gerr = gpgmex_op_num_uids (NULL, keyid, &(photoid_load_parm.num_uids));
+		DEBUG_OPERATION (("PhotoIDLoad Number of UIDs %i\n", photoid_load_parm.num_uids));
         
-        if (GPG_IS_OK(err)) {
-            
-            setenv("SEAHORSE_IMAGE_FILE", image_path, 1);
-            oldpath = getenv("PATH");
+		if (GPG_IS_OK (gerr)) {
             
-            path = g_strdup_printf ("%s:%s", EXECDIR, getenv("PATH"));
-            setenv("PATH", path, 1);
-            g_free (path);
+			setenv ("SEAHORSE_IMAGE_FILE", image_path, 1);
+			oldpath = getenv("PATH");
             
-            parms = seahorse_edit_parm_new (PHOTO_ID_LOAD_START, photoid_load_action,
-                                            photoid_load_transit, photoid_load_parm);
+			path = g_strdup_printf ("%s:%s", EXECDIR, getenv ("PATH"));
+			setenv ("PATH", path, 1);
+			g_free (path);
             
-            /* generate list */
-            err = edit_gpgme_key (psrc, key, parms);
-            setenv("PATH", oldpath, 1);
+			parms = seahorse_edit_parm_new (PHOTO_ID_LOAD_START, photoid_load_action,
+			                                photoid_load_transit, &photoid_load_parm);
             
-            *photoids = photoid_load_parm->first;  
-        }
-    }
+			/* generate list */
+			gerr = edit_gpgme_key (NULL, key, parms);
+			setenv ("PATH", oldpath, 1);
+
+			if (GPG_IS_OK (gerr))
+				seahorse_pgp_key_set_photos (pkey, photoid_load_parm.photos);
+		}
+		
+		seahorse_object_list_free (photoid_load_parm.photos);
+	}
     
-    DEBUG_OPERATION (("PhotoIDLoad Done\n"));
+	DEBUG_OPERATION (("PhotoIDLoad Done\n"));
     
-    return err;
+	return gerr;
 }
 
 gpgme_error_t   
-seahorse_pgp_key_op_photoid_primary (SeahorsePGPKey *pkey, const guint index)
+seahorse_pgp_key_op_photo_primary (SeahorsePgpPhoto *photo)
 {
-    PrimaryParm *pri_parm;
-    SeahorseEditParm *parms;
- 
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-  
-    pri_parm = g_new0 (PrimaryParm, 1);
-    pri_parm->index = index;
+	PrimaryParm pri_parm;
+	SeahorseEditParm *parms;
+	gpgme_key_t key;
+    
+	g_return_val_if_fail (SEAHORSE_IS_PGP_PHOTO (photo), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
+      
+	key = seahorse_pgp_photo_get_pubkey (photo);
+	g_return_val_if_fail (key, GPG_E (GPG_ERR_INV_VALUE));
+    
+	pri_parm.index = seahorse_pgp_photo_get_index (photo);
    
-    parms = seahorse_edit_parm_new (PRIMARY_START, primary_action,
-                primary_transit, pri_parm);
- 
-    return edit_key (pkey, parms);
+	parms = seahorse_edit_parm_new (PRIMARY_START, primary_action,
+	                                primary_transit, &pri_parm);
+
+	return edit_refresh_gpgme_key (NULL, key, parms);
 }

Modified: trunk/pgp/seahorse-pgp-key-op.h
==============================================================================
--- trunk/pgp/seahorse-pgp-key-op.h	(original)
+++ trunk/pgp/seahorse-pgp-key-op.h	Fri Dec 12 23:54:26 2008
@@ -30,6 +30,9 @@
 
 #include "pgp/seahorse-gpgmex.h"
 #include "pgp/seahorse-pgp-key.h"
+#include "pgp/seahorse-pgp-subkey.h"
+#include "pgp/seahorse-pgp-uid.h"
+#include "pgp/seahorse-pgp-photo.h"
 #include "pgp/seahorse-pgp-source.h"
 
 /* Key type options. */
@@ -104,76 +107,71 @@
 	REVOKE_NOT_USED = 3
 } SeahorseRevokeReason;
 
-SeahorseOperation*  seahorse_pgp_key_op_generate (SeahorsePGPSource  *sksrc,
-                                                  const gchar *name,
-                                                  const gchar *email,
-                                                  const gchar *comment,
-                                                  const gchar *passphrase,
-                                                  SeahorseKeyEncType type,
-                                                  guint length,
-                                                  time_t expires,
-                                                  gpgme_error_t *err);
-
-gpgme_error_t  seahorse_pgp_key_op_delete           (SeahorsePGPKey *pkey);
-
-gpgme_error_t  seahorse_pgp_key_pair_op_delete      (SeahorsePGPKey *pkey);
-
-gpgme_error_t  seahorse_pgp_key_op_sign             (SeahorsePGPKey *pkey,
-                                                     SeahorsePGPKey *signer,
-                                                     guint index,
-                                                     SeahorseSignCheck check,
-                                                     SeahorseSignOptions options);
-
-gpgme_error_t  seahorse_pgp_key_pair_op_change_pass (SeahorsePGPKey *pkey);
-
-gpgme_error_t  seahorse_pgp_key_op_set_trust        (SeahorsePGPKey *pkey,
-                                                 SeahorseValidity validity);
-
-gpgme_error_t  seahorse_pgp_key_op_set_disabled     (SeahorsePGPKey *pkey,
-                                                 gboolean disabled);
-
-gpgme_error_t  seahorse_pgp_key_pair_op_set_expires (SeahorsePGPKey *pkey,
-                                                 guint index,
-                                                 time_t expires);
-
-gpgme_error_t  seahorse_pgp_key_pair_op_add_revoker (SeahorsePGPKey *pkey, 
-                                                 SeahorsePGPKey *revoker);
-
-gpgme_error_t  seahorse_pgp_key_pair_op_add_uid     (SeahorsePGPKey *pkey,
-                                                 const gchar *name,
-                                                 const gchar *email,
-                                                 const gchar *comment);
+SeahorseOperation*    seahorse_pgp_key_op_generate           (SeahorsePGPSource  *sksrc,
+                                                              const gchar *name,
+                                                              const gchar *email,
+                                                              const gchar *comment,
+                                                              const gchar *passphrase,
+                                                              SeahorseKeyEncType type,
+                                                              guint length,
+                                                              time_t expires,
+                                                              gpgme_error_t *err);
 
-gpgme_error_t  seahorse_pgp_key_op_primary_uid      (SeahorsePGPKey *pkey,
-                                                 guint index);
+gpgme_error_t         seahorse_pgp_key_op_delete             (SeahorsePgpKey *pkey);
 
-gpgme_error_t  seahorse_pgp_key_op_del_uid          (SeahorsePGPKey *pkey,
-                                                 guint index);
+gpgme_error_t         seahorse_pgp_key_op_delete_pair        (SeahorsePgpKey *pkey);
+
+gpgme_error_t         seahorse_pgp_key_op_sign               (SeahorsePgpKey *key,
+                                                              SeahorsePgpKey *signer,
+                                                              SeahorseSignCheck check,
+                                                              SeahorseSignOptions options);
+
+gpgme_error_t         seahorse_pgp_key_op_sign_uid           (SeahorsePgpUid *uid, 
+                                                              SeahorsePgpKey *signer, 
+                                                              SeahorseSignCheck check, 
+                                                              SeahorseSignOptions options);
+
+gpgme_error_t         seahorse_pgp_key_op_change_pass        (SeahorsePgpKey *pkey);
+
+gpgme_error_t         seahorse_pgp_key_op_set_trust          (SeahorsePgpKey *pkey,
+                                                              SeahorseValidity validity);
+
+gpgme_error_t         seahorse_pgp_key_op_set_disabled       (SeahorsePgpKey *pkey,
+                                                              gboolean disabled);
+
+gpgme_error_t         seahorse_pgp_key_op_set_expires        (SeahorsePgpSubkey *subkey,
+                                                              time_t expires);
+
+gpgme_error_t         seahorse_pgp_key_op_add_revoker        (SeahorsePgpKey *pkey, 
+                                                              SeahorsePgpKey *revoker);
+
+gpgme_error_t         seahorse_pgp_key_op_add_uid            (SeahorsePgpKey *pkey,
+                                                              const gchar *name,
+                                                              const gchar *email,
+                                                              const gchar *comment);
+
+gpgme_error_t         seahorse_pgp_key_op_primary_uid        (SeahorsePgpUid *uid);
+
+gpgme_error_t         seahorse_pgp_key_op_del_uid            (SeahorsePgpUid *uid);
                              
-gpgme_error_t  seahorse_pgp_key_pair_op_add_subkey  (SeahorsePGPKey *pkey,
-                                                 SeahorseKeyEncType type,
-                                                 guint length,
-                                                 time_t expires);
-
-gpgme_error_t  seahorse_pgp_key_op_del_subkey       (SeahorsePGPKey *pkey,
-                                                 guint index);
-
-gpgme_error_t  seahorse_pgp_key_op_revoke_subkey    (SeahorsePGPKey *pkey,
-                                                 guint index,
-                                                 SeahorseRevokeReason reason,
-                                                 const gchar *description);
+gpgme_error_t         seahorse_pgp_key_op_add_subkey         (SeahorsePgpKey *pkey,
+                                                              SeahorseKeyEncType type,
+                                                              guint length,
+                                                              time_t expires);
+
+gpgme_error_t         seahorse_pgp_key_op_del_subkey         (SeahorsePgpSubkey *subkey);
+
+gpgme_error_t         seahorse_pgp_key_op_revoke_subkey      (SeahorsePgpSubkey *subkey,
+                                                              SeahorseRevokeReason reason,
+                                                              const gchar *description);
 
-gpgme_error_t  seahorse_pgp_key_op_photoid_add      (SeahorsePGPKey *pkey,
-                                                     const gchar *filename);
+gpgme_error_t         seahorse_pgp_key_op_photo_add          (SeahorsePgpKey *pkey,
+                                                              const gchar *filename);
  
-gpgme_error_t  seahorse_pgp_key_op_photoid_delete   (SeahorsePGPKey *pkey,
-                                                     guint uid);
+gpgme_error_t         seahorse_pgp_key_op_photo_delete       (SeahorsePgpPhoto *photo);
                                                      
-gpgme_error_t  seahorse_pgp_key_op_photoid_load     (SeahorsePGPSource *psrc, 
-                                                     gpgme_key_t key, 
-                                                     gpgmex_photo_id_t *photoids);
+gpgme_error_t         seahorse_pgp_key_op_photos_load        (SeahorsePgpKey *key);
 
-gpgme_error_t  seahorse_pgp_key_op_photoid_primary (SeahorsePGPKey *pkey, 
-                                                    const guint index);
+gpgme_error_t         seahorse_pgp_key_op_photo_primary      (SeahorsePgpPhoto *photo);
 
 #endif /* __SEAHORSE_PGP_KEY_OP_H__ */

Modified: trunk/pgp/seahorse-pgp-key-properties.c
==============================================================================
--- trunk/pgp/seahorse-pgp-key-properties.c	(original)
+++ trunk/pgp/seahorse-pgp-key-properties.c	Fri Dec 12 23:54:26 2008
@@ -102,33 +102,35 @@
     g_free (text);
 }
 
-static gint
-get_selected_row (SeahorseWidget *swidget, const gchar *gladeid, guint column)
+static gpointer
+get_selected_object (SeahorseWidget *swidget, const gchar *gladeid, guint column)
 {
-    GtkTreeSelection *selection;
-    GtkWidget *widget;
-    GtkTreeIter iter;
-    GtkTreeModel *model;
-    GList *rows;
-    gint index = -1;
+	GtkTreeSelection *selection;
+	GtkWidget *widget;
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	GList *rows;
+	gpointer object = NULL;
 
-    widget = glade_xml_get_widget (swidget->xml, gladeid);
-    model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+	widget = glade_xml_get_widget (swidget->xml, gladeid);
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
 
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
-    g_assert (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE);
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+	g_assert (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE);
 
-    rows = gtk_tree_selection_get_selected_rows (selection, NULL);
-
-    if (g_list_length (rows) > 0) {
-        gtk_tree_model_get_iter (model, &iter, rows->data);
-        gtk_tree_model_get (model, &iter, column, &index, -1);
-    }
+	rows = gtk_tree_selection_get_selected_rows (selection, NULL);
+
+	if (g_list_length (rows) > 0) {
+		gtk_tree_model_get_iter (model, &iter, rows->data);
+		gtk_tree_model_get (model, &iter, column, &object, -1);
+		if (object)
+			g_object_unref (object);
+	}
 
-    g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
-    g_list_free (rows);
+	g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
+	g_list_free (rows);
 
-    return index;
+	return object;
 }
 
 static void
@@ -173,7 +175,7 @@
  */
 
 enum {
-    UIDSIG_INDEX,
+    UIDSIG_OBJECT,
     UIDSIG_ICON,
     UIDSIG_NAME,
     UIDSIG_KEYID,
@@ -181,16 +183,16 @@
 };
 
 const GType uidsig_columns[] = {
-    G_TYPE_INT,     /* index */
+    G_TYPE_OBJECT,  /* index */
     G_TYPE_STRING,  /* icon */
     G_TYPE_STRING,  /* name */
     G_TYPE_STRING   /* keyid */
 };
 
-static gint
+static SeahorsePgpUid*
 names_get_selected_uid (SeahorseWidget *swidget)
 {
-    return get_selected_row (swidget, "names-tree", UIDSIG_INDEX);
+	return get_selected_object (swidget, "names-tree", UIDSIG_OBJECT);
 }
 
 static void
@@ -203,38 +205,29 @@
 static void 
 names_primary_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    gpgme_error_t err;
-    gint index;
-    
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    index = names_get_selected_uid (swidget);
+	SeahorsePgpUid *uid;
+	gpgme_error_t err;
     
-    if (index > 0) {
-        err = seahorse_pgp_key_op_primary_uid (SEAHORSE_PGP_KEY (object), index);
-        if (!GPG_IS_OK (err)) 
-            seahorse_pgp_handle_gpgme_error (err, _("Couldn't change primary user ID"));
-    }
+	uid = names_get_selected_uid (swidget);
+	if (uid) {
+		err = seahorse_pgp_key_op_primary_uid (uid);
+		if (!GPG_IS_OK (err)) 
+			seahorse_pgp_handle_gpgme_error (err, _("Couldn't change primary user ID"));
+	}
 }
 
 static void 
 names_delete_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-	SeahorseObject *object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-	SeahorsePGPKey *pkey = SEAHORSE_PGP_KEY (object);
-	SeahorsePGPUid *uid;
-	gint index = names_get_selected_uid (swidget);
+	SeahorsePgpUid *uid;
 	gboolean ret;
 	gchar *message; 
 	gpgme_error_t gerr;
     
-	if (index < 1)
+	uid = names_get_selected_uid (swidget);
+	if (uid == NULL)
 		return;
 	
-	/* TODO: This whole index thing is messed up */
-	uid = SEAHORSE_PGP_UID (seahorse_object_get_nth_child (object, index));
-	g_return_if_fail (uid);
-	
 	message = g_strdup_printf (_("Are you sure you want to permanently delete the '%s' user ID?"), 
 	                           seahorse_object_get_label (SEAHORSE_OBJECT (uid)));
 	ret = seahorse_util_prompt_delete (message, seahorse_widget_get_toplevel (swidget));
@@ -243,7 +236,7 @@
 	if (ret == FALSE)
 		return;
 	
-	gerr = seahorse_pgp_key_op_del_uid (pkey, index);
+	gerr = seahorse_pgp_key_op_del_uid (uid);
 	if (!GPG_IS_OK (gerr))
 		seahorse_pgp_handle_gpgme_error (gerr, _("Couldn't delete user ID"));
 }
@@ -251,28 +244,11 @@
 static void 
 names_sign_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-	SeahorseObject *object;
-	gint index;
-	GList *keys = NULL;
-
-	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-	index = names_get_selected_uid (swidget);
-
-	if (index >= 1) {
-		seahorse_pgp_sign_prompt (SEAHORSE_PGP_KEY (object), 
-		                          index - 1,
-		                          GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
+	SeahorsePgpUid *uid;
 
-
-#ifdef WITH_KEYSERVER
-		if (seahorse_gconf_get_boolean(AUTOSYNC_KEY) == TRUE) {
-			keys = g_list_append (keys, object);
-			/* TODO: This cross module dependency needs to be fixed */
-			/* seahorse_keyserver_sync (keys); */
-			g_list_free(keys);
-		}
-#endif
-	}
+	uid = names_get_selected_uid (swidget);
+	if (uid != NULL)
+		seahorse_pgp_sign_prompt_uid (uid, GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
 }
 
 static void 
@@ -302,12 +278,13 @@
 static void
 update_names (GtkTreeSelection *selection, SeahorseWidget *swidget)
 {
-    gint index = names_get_selected_uid (swidget);
+	SeahorsePgpUid *uid = names_get_selected_uid (swidget);
+	gint index = uid ? seahorse_pgp_uid_get_gpgme_index (uid) : -1;
 
-    sensitive_glade_widget (swidget, "names-primary-button", index >= 1);
-    sensitive_glade_widget (swidget, "names-delete-button", index >= 1);
-    sensitive_glade_widget (swidget, "names-sign-button", index >= 1);
-    show_glade_widget (swidget, "names-revoke-button", FALSE);
+	sensitive_glade_widget (swidget, "names-primary-button", index > 0);
+	sensitive_glade_widget (swidget, "names-delete-button", index >= 0);
+	sensitive_glade_widget (swidget, "names-sign-button", index >= 0);
+	show_glade_widget (swidget, "names-revoke-button", FALSE);
 }
 
 /* Is called whenever a signature key changes, to update row */
@@ -335,48 +312,45 @@
 	id = seahorse_object_get_identifier (object);
 	
 	gtk_tree_store_set (GTK_TREE_STORE (skmodel), iter,
-	                    UIDSIG_INDEX, -1,
+	                    UIDSIG_OBJECT, NULL,
 	                    UIDSIG_ICON, icon,
 	                    UIDSIG_NAME, name ? name : _("[Unknown]"),
 	                    UIDSIG_KEYID, id, -1);
 }
 
 static void
-names_populate (SeahorseWidget *swidget, GtkTreeStore *store, SeahorsePGPKey *pkey)
+names_populate (SeahorseWidget *swidget, GtkTreeStore *store, SeahorsePgpKey *pkey)
 {
 	SeahorseObject *object;
 	gpgme_key_sig_t sig;
+	gpgme_user_id_t userid;
 	GtkTreeIter uiditer, sigiter;
-	const gchar *keyid;
 	GSList *rawids = NULL;
 	int j;
 	GList *keys, *l;
 	GList *uids, *u;
-	SeahorsePGPUid *uid;
+	SeahorsePgpUid *uid;
 
-	keyid = seahorse_pgp_key_get_id (pkey->pubkey, 0);
-    
 	/* Insert all the fun-ness */
-	uids = seahorse_object_get_children (SEAHORSE_OBJECT (pkey));
+	uids = seahorse_pgp_key_get_uids (pkey);
 	
 	for (u = uids; u; u = g_list_next (u)) {
 
-		g_return_if_fail (SEAHORSE_IS_PGP_UID (u->data));
 		uid = SEAHORSE_PGP_UID (u->data);
-		g_return_if_fail (uid->userid);
+		userid = seahorse_pgp_uid_get_userid (uid);
 
 		gtk_tree_store_append (store, &uiditer, NULL);
 		gtk_tree_store_set (store, &uiditer,  
-		                    UIDSIG_INDEX, seahorse_pgp_uid_get_index (uid),
+		                    UIDSIG_OBJECT, uid,
 		                    UIDSIG_ICON, SEAHORSE_STOCK_PERSON,
 		                    UIDSIG_NAME, seahorse_object_get_markup (SEAHORSE_OBJECT (uid)),
 		                    -1);
         
         
 		/* Build a list of all the keyids */
-		for (j = 1, sig = uid->userid->signatures; sig; sig = sig->next, j++) {
+		for (j = 1, sig = userid->signatures; sig; sig = sig->next, j++) {
 			/* Never show self signatures, they're implied */
-			if (strcmp (sig->keyid, keyid) == 0)
+			if (seahorse_pgp_key_has_keyid (pkey, sig->keyid))
 				continue;
 			rawids = g_slist_prepend (rawids, sig->keyid);
 		}
@@ -401,7 +375,7 @@
 do_names (SeahorseWidget *swidget)
 {
     SeahorseObject *object;
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
     GtkWidget *widget;
     GtkTreeStore *store;
     GtkCellRenderer *renderer;
@@ -503,7 +477,7 @@
                            SeahorseWidget *swidget)
 {       
     gboolean dnd_success = FALSE;
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
     gchar **uri_list;
     gint len = 0;
     gchar *uri;
@@ -545,7 +519,7 @@
 static void
 owner_photo_add_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
 
     pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
     g_assert (SEAHORSE_IS_PGP_KEY (pkey));
@@ -557,147 +531,145 @@
 static void
 owner_photo_delete_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-    SeahorsePGPKey *pkey;
-    gpgmex_photo_id_t photoid;
+	SeahorsePgpPhoto *photo;
 
-    photoid = (gpgmex_photo_id_t)g_object_get_data (G_OBJECT (swidget), 
-                                                    "current-photoid");
-    g_return_if_fail (photoid != NULL);
+	photo = g_object_get_data (G_OBJECT (swidget), "current-photoid");
+	g_return_if_fail (SEAHORSE_IS_PGP_PHOTO (photo));
 
-    pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
-    g_assert (SEAHORSE_IS_PGP_KEY (pkey));
-    
-    if (seahorse_pgp_photo_delete (pkey, GTK_WINDOW (seahorse_widget_get_toplevel (swidget)),
-                                   photoid))
-        g_object_set_data (G_OBJECT (swidget), "current-photoid", NULL);
+	if (seahorse_pgp_key_op_photo_delete (photo))
+		g_object_set_data (G_OBJECT (swidget), "current-photoid", NULL);
 }
 
 static void
 owner_photo_primary_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorsePGPKey *pkey;
-    gpgme_error_t gerr;
-    gint uid;
-    gpgmex_photo_id_t photoid;
-
-    photoid = (gpgmex_photo_id_t)g_object_get_data (G_OBJECT (swidget), 
-                                                    "current-photoid");
-    g_return_if_fail (photoid != NULL);
+	gpgme_error_t gerr;
+	SeahorsePgpPhoto *photo;
+
+	photo = g_object_get_data (G_OBJECT (swidget), "current-photoid");
+	g_return_if_fail (SEAHORSE_IS_PGP_PHOTO (photo));
         
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    pkey = SEAHORSE_PGP_KEY (object);
-    
-    uid = photoid->uid;
-    
-    gerr = seahorse_pgp_key_op_photoid_primary (pkey, uid);
-    if (!GPG_IS_OK (gerr))
-	    seahorse_pgp_handle_gpgme_error (gerr, _("Couldn't change primary photo"));
+	gerr = seahorse_pgp_key_op_photo_primary (photo);
+	if (!GPG_IS_OK (gerr))
+		seahorse_pgp_handle_gpgme_error (gerr, _("Couldn't change primary photo"));
 }
 
 static void
-set_photoid_state(SeahorseWidget *swidget, SeahorsePGPKey *pkey)
+set_photoid_state(SeahorseWidget *swidget, SeahorsePgpKey *pkey)
 {
-    SeahorseUsage etype; 
-    GtkWidget *photo_image;
-
-    gpgmex_photo_id_t photoid;
+	SeahorseUsage etype; 
+	GtkWidget *photo_image;
+	SeahorsePgpPhoto *photo;
+	GdkPixbuf *pixbuf;
+	GList *photos;
 
-    etype = seahorse_object_get_usage (SEAHORSE_OBJECT (pkey));
-    photoid = (gpgmex_photo_id_t)g_object_get_data (G_OBJECT (swidget), 
-                                                    "current-photoid");
-
-    /* Show when adding a photo is possible */
-    show_glade_widget (swidget, "owner-photo-add-button", 
-                       etype == SEAHORSE_USAGE_PRIVATE_KEY);
-
-    /* Show when we have a photo to set as primary */
-    show_glade_widget (swidget, "owner-photo-primary-button", 
-                       etype == SEAHORSE_USAGE_PRIVATE_KEY && photoid);
-
-    /* Display this when there are any photo ids */
-    show_glade_widget (swidget, "owner-photo-delete-button", 
-                       etype == SEAHORSE_USAGE_PRIVATE_KEY && photoid != NULL);
+	etype = seahorse_object_get_usage (SEAHORSE_OBJECT (pkey));
+	photos = seahorse_pgp_key_get_photos (pkey);
+	
+	photo = g_object_get_data (G_OBJECT (swidget), "current-photoid");
+	g_return_if_fail (!photo || SEAHORSE_IS_PGP_PHOTO (photo));
 
-    /* Sensitive when not the first photo id */
-    sensitive_glade_widget (swidget, "owner-photo-previous-button", 
-                            photoid && photoid != pkey->photoids);
-    
-    /* Sensitive when not the last photo id */
-    sensitive_glade_widget (swidget, "owner-photo-next-button", 
-                            photoid && photoid->next && photoid->next->photo);
-    
-    /* Display *both* of these when there are more than one photo id */
-    show_glade_widget (swidget, "owner-photo-previous-button", 
-                       pkey->photoids && pkey->photoids->next);
+	/* Show when adding a photo is possible */
+	show_glade_widget (swidget, "owner-photo-add-button", 
+	                   etype == SEAHORSE_USAGE_PRIVATE_KEY);
+
+	/* Show when we have a photo to set as primary */
+	show_glade_widget (swidget, "owner-photo-primary-button", 
+	                   etype == SEAHORSE_USAGE_PRIVATE_KEY && photo);
+
+	/* Display this when there are any photo ids */
+	show_glade_widget (swidget, "owner-photo-delete-button", 
+	                   etype == SEAHORSE_USAGE_PRIVATE_KEY && photo);
+
+	/* Sensitive when not the first photo id */
+	sensitive_glade_widget (swidget, "owner-photo-previous-button", 
+	                        photo && photos && photo != g_list_first (photos)->data);
+    
+	/* Sensitive when not the last photo id */
+	sensitive_glade_widget (swidget, "owner-photo-next-button", 
+	                        photo && photos && photo != g_list_last (photos)->data);
+    
+	/* Display *both* of these when there are more than one photo id */
+	show_glade_widget (swidget, "owner-photo-previous-button", 
+	                   photos && g_list_next (photos));
                        
-    show_glade_widget (swidget, "owner-photo-next-button", 
-                       pkey->photoids && pkey->photoids->next);
+	show_glade_widget (swidget, "owner-photo-next-button", 
+	                   photos && g_list_next (photos));
                        
-    photo_image = glade_xml_get_widget (swidget->xml, "photoid");
-    if (photo_image) {
-        if (!photoid || !photoid->photo)
-            gtk_image_set_from_stock (GTK_IMAGE (photo_image), 
-                etype == SEAHORSE_USAGE_PRIVATE_KEY ? SEAHORSE_STOCK_SECRET : SEAHORSE_STOCK_KEY, (GtkIconSize)-1);
-        else 
-            gtk_image_set_from_pixbuf (GTK_IMAGE (photo_image), photoid->photo);
-    }
+	photo_image = glade_xml_get_widget (swidget->xml, "photoid");
+	g_return_if_fail (photo_image);
+	
+	pixbuf = photo ? seahorse_pgp_photo_get_pixbuf (photo) : NULL;
+	if (pixbuf)
+		gtk_image_set_from_pixbuf (GTK_IMAGE (photo_image), pixbuf);
+	else if (etype == SEAHORSE_USAGE_PRIVATE_KEY)
+		gtk_image_set_from_stock (GTK_IMAGE (photo_image), SEAHORSE_STOCK_SECRET, (GtkIconSize)-1);
+	else 
+		gtk_image_set_from_stock (GTK_IMAGE (photo_image), SEAHORSE_STOCK_KEY, (GtkIconSize)-1);
 }
 
 static void
 do_photo_id (SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorsePGPKey *pkey;
+	SeahorsePgpKey *pkey;
+	GList *photos;
 
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    pkey = SEAHORSE_PGP_KEY (object);
+	pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+	photos = seahorse_pgp_key_get_photos (pkey);
 
-    g_object_set_data (G_OBJECT (swidget), "current-photoid", pkey->photoids);
-    
-    set_photoid_state (swidget, pkey);
+	if (!photos)
+		g_object_set_data (G_OBJECT (swidget), "current-photoid", NULL);
+	else
+		g_object_set_data_full (G_OBJECT (swidget), "current-photoid", 
+		                        g_object_ref (photos->data), g_object_unref);
+
+	set_photoid_state (swidget, pkey);
 }
 
 static void
 photoid_next_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorsePGPKey *pkey;
-    gpgmex_photo_id_t photoid;
-
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    pkey = SEAHORSE_PGP_KEY (object);
-
-    photoid = (gpgmex_photo_id_t)g_object_get_data (G_OBJECT (swidget), "current-photoid");
+	SeahorsePgpKey *pkey;
+	SeahorsePgpPhoto *photo;
+	GList *photos;
 
-    if (photoid && photoid->next)
-        g_object_set_data (G_OBJECT (swidget), "current-photoid", photoid->next);
+	pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+	photos = seahorse_pgp_key_get_photos (pkey);
+	
+	photo = g_object_get_data (G_OBJECT (swidget), "current-photoid");
+	if (photo) {
+		g_return_if_fail (SEAHORSE_IS_PGP_PHOTO (photo));
+		photos = g_list_find (photos, photo);
+		if(photos && photos->next)
+			g_object_set_data_full (G_OBJECT (swidget), "current-photoid", 
+			                        g_object_ref (photos->next->data), 
+			                        g_object_unref);
+	}
         
-    set_photoid_state (swidget, pkey);
+	set_photoid_state (swidget, pkey);
 }
 
 static void
 photoid_prev_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorsePGPKey *pkey;
-    gpgmex_photo_id_t itter, photoid;
-
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    pkey = SEAHORSE_PGP_KEY (object);
-
-    photoid = (gpgmex_photo_id_t)g_object_get_data (G_OBJECT (swidget), "current-photoid");
-
-    if (photoid != pkey->photoids) {
-        itter = pkey->photoids;
-    
-        while (itter->next != photoid && itter->next)
-           itter = itter->next;
-    
-        g_object_set_data (G_OBJECT (swidget), "current-photoid", itter);
-    }
-
-    set_photoid_state (swidget, pkey);
+	SeahorsePgpKey *pkey;
+	SeahorsePgpPhoto *photo;
+	GList *photos;
+
+	pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+	photos = seahorse_pgp_key_get_photos (pkey);
+
+	photo = g_object_get_data (G_OBJECT (swidget), "current-photoid");
+	if (photo) {
+		g_return_if_fail (SEAHORSE_IS_PGP_PHOTO (photo));
+		photos = g_list_find (photos, photo);
+		if(photos && photos->prev)
+			g_object_set_data_full (G_OBJECT (swidget), "current-photoid", 
+			                        g_object_ref (photos->prev->data), 
+			                        g_object_unref);
+	}
+	
+	set_photoid_state (swidget, pkey);
 }
 
 static void
@@ -721,49 +693,42 @@
 
 /* owner uid list */
 enum {
-    UID_INDEX,
+    UID_OBJECT,
     UID_ICON,
     UID_MARKUP,
     UID_N_COLUMNS
 };
 
 const GType uid_columns[] = {
-    G_TYPE_INT,     /* index */
+    G_TYPE_OBJECT,  /* object */
     G_TYPE_STRING,  /* icon */
     G_TYPE_STRING,  /* name */
     G_TYPE_STRING,  /* email */
     G_TYPE_STRING   /* comment */
 };
 
-static gint
+static SeahorsePgpUid*
 owner_get_selected_uid (SeahorseWidget *swidget)
 {
-    return get_selected_row (swidget, "owner-userid-tree", UID_INDEX);
+	return get_selected_object (swidget, "owner-userid-tree", UID_OBJECT);
 }
 
 static void 
 owner_sign_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-	SeahorseObject *object;
-	gint index;
-
-	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-	index = owner_get_selected_uid (swidget);
+	SeahorsePgpUid *uid;
 
-	if (index >= 1) 
-		seahorse_pgp_sign_prompt (SEAHORSE_PGP_KEY (object),
-		                          index - 1,
-		                          GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name))); 
+	uid = owner_get_selected_uid (swidget);
+	if (uid != NULL)
+		seahorse_pgp_sign_prompt_uid (uid, GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
 }
 
 static void
 owner_passphrase_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    
-    if (seahorse_object_get_usage (object) == SEAHORSE_USAGE_PRIVATE_KEY)
-        seahorse_pgp_key_pair_op_change_pass (SEAHORSE_PGP_KEY (object));
+	SeahorseObject *object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+	if (seahorse_object_get_usage (object) == SEAHORSE_USAGE_PRIVATE_KEY)
+		seahorse_pgp_key_op_change_pass (SEAHORSE_PGP_KEY (object));
 }
 
 static void
@@ -810,125 +775,122 @@
 static void
 do_owner (SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorsePGPKey *pkey;
-    SeahorsePGPUid *uid;
-    GtkWidget *widget;
-    GtkCellRenderer *renderer;
-    GtkListStore *store;
-    GtkTreeIter iter;
-    gchar *text, *t;
-    gulong expires_date;
-    guint flags;
-    const gchar *markup;
-    const gchar *label;
-    int i;
+	SeahorseObject *object;
+	SeahorsePgpKey *pkey;
+	SeahorsePgpUid *uid;
+	GtkWidget *widget;
+	GtkCellRenderer *renderer;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	gchar *text, *t;
+	gulong expires_date;
+	guint flags;
+	const gchar *markup;
+	const gchar *label;
+	GList *uids, *l;
 
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    pkey = SEAHORSE_PGP_KEY (object);
+	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+	pkey = SEAHORSE_PGP_KEY (object);
 
-    flags = seahorse_object_get_flags (object);
+	flags = seahorse_object_get_flags (object);
     
-    /* Display appropriate warnings */    
-    show_glade_widget (swidget, "expired-area", flags & SEAHORSE_FLAG_EXPIRED);
-    show_glade_widget (swidget, "revoked-area", flags & SEAHORSE_FLAG_REVOKED);
-    show_glade_widget (swidget, "disabled-area", flags & SEAHORSE_FLAG_DISABLED);
-    
-    /* Update the expired message */
-    if (flags & SEAHORSE_FLAG_EXPIRED) {
-        widget = glade_xml_get_widget (swidget->xml, "expired-message");
-        if (widget) {
+	/* Display appropriate warnings */    
+	show_glade_widget (swidget, "expired-area", flags & SEAHORSE_FLAG_EXPIRED);
+	show_glade_widget (swidget, "revoked-area", flags & SEAHORSE_FLAG_REVOKED);
+	show_glade_widget (swidget, "disabled-area", flags & SEAHORSE_FLAG_DISABLED);
+    
+	/* Update the expired message */
+	if (flags & SEAHORSE_FLAG_EXPIRED) {
+		widget = glade_xml_get_widget (swidget->xml, "expired-message");
+		if (widget) {
             
-            expires_date = seahorse_pgp_key_get_expires (pkey);
-            if (expires_date == 0) 
-                t = g_strdup (_("(unknown)"));
-            else
-                t = seahorse_util_get_display_date_string (expires_date);
-            text = g_strdup_printf (_("This key expired on: %s"), t);
-                
-            gtk_label_set_text (GTK_LABEL (widget), text);
+			expires_date = seahorse_pgp_key_get_expires (pkey);
+			if (expires_date == 0) 
+				t = g_strdup (_("(unknown)"));
+			else
+				t = seahorse_util_get_display_date_string (expires_date);
+			text = g_strdup_printf (_("This key expired on: %s"), t);
+			
+			gtk_label_set_text (GTK_LABEL (widget), text);
             
-            g_free (t);
-            g_free (text);
-        }
-    }
+			g_free (t);
+			g_free (text);
+		}
+	}
         
-    /* Hide trust page when above */
-    show_glade_widget (swidget, "trust-page", !((flags & SEAHORSE_FLAG_EXPIRED) ||
-                       (flags & SEAHORSE_FLAG_REVOKED) || (flags & SEAHORSE_FLAG_DISABLED)));
-
-    /* Hide or show the uids area */
-    show_glade_widget (swidget, "uids-area", seahorse_pgp_key_get_num_uids (pkey) > 1);
-    uid = seahorse_pgp_key_get_uid (pkey, 0);
-    
-    if ((text = seahorse_pgp_uid_get_name (uid)) != NULL) {
-        widget = glade_xml_get_widget (swidget->xml, "owner-name-label");
-        gtk_label_set_text (GTK_LABEL (widget), text);  
-
-        widget = glade_xml_get_widget (swidget->xml, swidget->name);
-        gtk_window_set_title (GTK_WINDOW (widget), text);
-        g_free (text);
-    }
-
-    if ((text = seahorse_pgp_uid_get_email (uid)) != NULL) {
-        widget = glade_xml_get_widget (swidget->xml, "owner-email-label");
-        gtk_label_set_text (GTK_LABEL (widget), text);  
-        g_free (text);
-    }
-
-    if ((text = seahorse_pgp_uid_get_comment (uid)) != NULL) {
-        widget = glade_xml_get_widget (swidget->xml, "owner-comment-label");
-        gtk_label_set_text (GTK_LABEL (widget), text);  
-        g_free (text);
-    }
-    
-	widget = glade_xml_get_widget (swidget->xml, "owner-keyid-label");
-	if (widget) {
-		label = seahorse_object_get_identifier (object); 
-		gtk_label_set_text (GTK_LABEL (widget), label);
+	/* Hide trust page when above */
+	show_glade_widget (swidget, "trust-page", !((flags & SEAHORSE_FLAG_EXPIRED) ||
+			   (flags & SEAHORSE_FLAG_REVOKED) || (flags & SEAHORSE_FLAG_DISABLED)));
+
+	/* Hide or show the uids area */
+	uids = seahorse_pgp_key_get_uids (pkey);
+	show_glade_widget (swidget, "uids-area", uids != NULL);
+	if (uids != NULL) {
+		uid = SEAHORSE_PGP_UID (uids->data);
+    
+		text = seahorse_pgp_uid_get_name (uid);
+		widget = glade_xml_get_widget (swidget->xml, "owner-name-label");
+		gtk_label_set_text (GTK_LABEL (widget), text ? text : NULL); 
+		widget = glade_xml_get_widget (swidget->xml, swidget->name);
+		gtk_window_set_title (GTK_WINDOW (widget), text);
+		g_free (text);
+
+		text = seahorse_pgp_uid_get_email (uid);
+		widget = glade_xml_get_widget (swidget->xml, "owner-email-label");
+		gtk_label_set_text (GTK_LABEL (widget), text ? text : NULL); 
+		g_free (text);	
+
+		text = seahorse_pgp_uid_get_comment (uid);
+		widget = glade_xml_get_widget (swidget->xml, "owner-comment-label");
+		gtk_label_set_text (GTK_LABEL (widget), text ? text : NULL); 
+		g_free (text);
+    
+		widget = glade_xml_get_widget (swidget->xml, "owner-keyid-label");
+		if (widget) {
+			label = seahorse_object_get_identifier (object); 
+			gtk_label_set_text (GTK_LABEL (widget), label);
+		}
 	}
     
-    /* Clear/create table store */
-    widget = glade_xml_get_widget (swidget->xml, "owner-userid-tree");
-    if (widget) {
-        store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
+	/* Clear/create table store */
+	widget = glade_xml_get_widget (swidget->xml, "owner-userid-tree");
+	if (widget) {
+		store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
     
-        if (store) {
-            gtk_list_store_clear (GTK_LIST_STORE (store));
+		if (store) {
+			gtk_list_store_clear (GTK_LIST_STORE (store));
             
-        } else {
+		} else {
     
-            /* This is our first time so create a store */
-            store = gtk_list_store_newv (UID_N_COLUMNS, (GType*)uid_columns);
+			/* This is our first time so create a store */
+			store = gtk_list_store_newv (UID_N_COLUMNS, (GType*)uid_columns);
     
-            /* Make the columns for the view */
-            renderer = gtk_cell_renderer_pixbuf_new ();
-            g_object_set (renderer, "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
-            gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
-                                                         -1, "", renderer,
-                                                         "stock-id", UID_ICON, NULL);
-
-            gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), 
-                                                         -1, _("Name"), gtk_cell_renderer_text_new (), 
-                                                         "markup", UID_MARKUP, NULL);
-        }
+			/* Make the columns for the view */
+			renderer = gtk_cell_renderer_pixbuf_new ();
+			g_object_set (renderer, "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
+			gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
+			                                             -1, "", renderer,
+			                                             "stock-id", UID_ICON, NULL);
+
+			gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), 
+			                                             -1, _("Name"), gtk_cell_renderer_text_new (), 
+			                                             "markup", UID_MARKUP, NULL);
+		}
     
-        for (i = 0; i < seahorse_pgp_key_get_num_uids (pkey); i++) {
+		for (l = uids; l; l = g_list_next (l)) {
     
-        	uid = seahorse_pgp_key_get_uid (pkey, i);
-        	markup = seahorse_object_get_markup (SEAHORSE_OBJECT (uid));
-        	
-        	gtk_list_store_append (store, &iter);
-        	gtk_list_store_set (store, &iter,  
-        	                    UID_INDEX, i + 1,
-        	                    UID_ICON, SEAHORSE_STOCK_PERSON,
-        	                    UID_MARKUP, markup, -1);
-        } 
+			markup = seahorse_object_get_markup (l->data);
+			gtk_list_store_append (store, &iter);
+			gtk_list_store_set (store, &iter,  
+			                    UID_OBJECT, l->data,
+			                    UID_ICON, SEAHORSE_STOCK_PERSON,
+			                    UID_MARKUP, markup, -1);
+		} 
         
-        gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL(store));
-    }
+		gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL(store));
+	}
     
-    do_photo_id (swidget);
+	do_photo_id (swidget);
 }
 
 /* -----------------------------------------------------------------------------
@@ -937,7 +899,7 @@
 
 /* details subkey list */
 enum {
-	SUBKEY_INDEX,
+	SUBKEY_OBJECT,
 	SUBKEY_ID,
 	SUBKEY_TYPE,
 	SUBKEY_CREATED,
@@ -948,7 +910,7 @@
 };
 
 const GType subkey_columns[] = {
-    G_TYPE_INT,     /* index */
+    G_TYPE_OBJECT,  /* index */
     G_TYPE_STRING,  /* id */
     G_TYPE_STRING,  /* created */
     G_TYPE_STRING,  /* expires */
@@ -969,47 +931,45 @@
     G_TYPE_INT      /* validity */
 };
 
-static gint 
+static SeahorsePgpSubkey* 
 get_selected_subkey (SeahorseWidget *swidget)
 {
-    return get_selected_row (swidget, "details-subkey-tree", SUBKEY_INDEX);
+	return get_selected_object (swidget, "details-subkey-tree", SUBKEY_OBJECT);
 }
 
 static void
 details_add_subkey_button_clicked (GtkButton *button, SeahorseWidget *swidget)
 {
-	SeahorseObject *object;
-	SeahorsePGPKey *pkey;
-	
-	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-	pkey = SEAHORSE_PGP_KEY (object);
-	
-	seahorse_pgp_add_subkey_new (pkey, 
-	                             GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
+	SeahorsePgpKey *pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+	seahorse_pgp_add_subkey_new (pkey, GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
 }
 
 static void
 details_del_subkey_button_clicked (GtkButton *button, SeahorseWidget *swidget)
 {
-	SeahorseObject *object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-	SeahorsePGPKey *pkey = SEAHORSE_PGP_KEY (object);
-	guint index = get_selected_subkey (swidget);
+	SeahorsePgpSubkey *subkey; 
+	SeahorsePgpKey *pkey; 
+	guint index;
 	gboolean ret;
-	const gchar *userid;
+	const gchar *label;
 	gchar *message; 
 	gpgme_error_t err;
 
-	userid = seahorse_object_get_label (object);
-	message = g_strdup_printf (_("Are you sure you want to permanently delete subkey %d of %s?"),
-	                           index, userid);
+	pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+	subkey = get_selected_subkey (swidget);
+	if (!subkey)
+		return;
 	
+	index = seahorse_pgp_subkey_get_index (subkey);
+	label = seahorse_object_get_label (SEAHORSE_OBJECT (pkey));
+	message = g_strdup_printf (_("Are you sure you want to permanently delete subkey %d of %s?"), index, label);
 	ret = seahorse_util_prompt_delete (message, seahorse_widget_get_toplevel (swidget));
 	g_free (message);
 	
 	if (ret == FALSE)
 		return;
 	
-	err = seahorse_pgp_key_op_del_subkey (pkey, index);
+	err = seahorse_pgp_key_op_del_subkey (subkey);
 	if (!GPG_IS_OK (err))
 		seahorse_pgp_handle_gpgme_error (err, _("Couldn't delete subkey"));
 }
@@ -1017,10 +977,9 @@
 static void
 details_revoke_subkey_button_clicked (GtkButton *button, SeahorseWidget *swidget)
 {
-	SeahorseObject *object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-	seahorse_pgp_revoke_new (SEAHORSE_PGP_KEY (object), 
-	                         GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)), 
-	                         get_selected_subkey (swidget));
+	SeahorsePgpSubkey *subkey = get_selected_subkey (swidget);
+	if (subkey != NULL)
+		seahorse_pgp_revoke_new (subkey, GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
 }
 
 static void
@@ -1070,7 +1029,7 @@
 details_export_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
 	SeahorseObject *object;
-	SeahorsePGPKey *pkey;
+	SeahorsePgpKey *pkey;
 	GtkDialog *dialog;
 	gchar* uri = NULL;
 	GError *err = NULL;
@@ -1080,10 +1039,14 @@
 	gpgme_data_t data;
 	gchar *results;
 	gsize n_results;
+	gpgme_key_t seckey;
     
 	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
 	pkey = SEAHORSE_PGP_KEY (object);
-	
+
+	seckey = seahorse_pgp_key_get_private (pkey);
+	g_return_if_fail (seckey && seckey->subkeys && seckey->subkeys->keyid);
+
 	dialog = seahorse_util_chooser_save_new (_("Export Complete Key"), 
 	                                         GTK_WINDOW (seahorse_widget_get_toplevel (swidget)));
 	seahorse_util_chooser_show_key_files (dialog);
@@ -1098,7 +1061,7 @@
 	g_return_if_fail (GPG_IS_OK (gerr));
 	ctx = seahorse_pgp_source_new_context ();
 	g_return_if_fail (ctx);
-	gerr = gpgmex_op_export_secret (ctx, seahorse_pgp_key_get_id (pkey->seckey, 0), data);
+	gerr = gpgmex_op_export_secret (ctx, seckey->subkeys->keyid, data);
 	gpgme_release (ctx);
 	results = gpgme_data_release_and_get_mem (data, &n_results);
 
@@ -1116,28 +1079,24 @@
 	g_free (uri);
 }
 
-/*
- * This function is called by 2 different buttons. There may not
- * be a selected subkey which will cause an index of -1
- */
-
 static void
 details_calendar_button_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-	SeahorseObject *object;
-	gint index;
+	SeahorsePgpSubkey *subkey;
+	SeahorsePgpKey *pkey;
+	GList *subkeys;
 	
-	g_return_if_fail (SEAHORSE_IS_OBJECT_WIDGET (swidget));
-	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+	subkey = get_selected_subkey (swidget);
+	if (subkey == NULL) {
+		pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+		subkeys = seahorse_pgp_key_get_subkeys (pkey);
+		if (subkeys)
+			subkey = subkeys->data;
+	}
 
-	index = get_selected_subkey (swidget);
+	if (subkey != NULL)
+		seahorse_pgp_expires_new (subkey, GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
 	
-	if (-1 == index) {
-		index = 0;
-	}
-	seahorse_pgp_expires_new (SEAHORSE_PGP_KEY (object), 
-	                          GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)), 
-	                          index);	
 }
 
 static void
@@ -1249,24 +1208,31 @@
 do_details (SeahorseWidget *swidget)
 {
     SeahorseObject *object;
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
     gpgme_subkey_t subkey;
+    gpgme_key_t pubkey;
     GtkWidget *widget;
     GtkListStore *store;
     GtkTreeModel *model;
     GtkTreeIter iter;
-    GtkTreeIter default_key;
-    GtkTreeSelection *selection;
     gchar dbuffer[G_ASCII_DTOSTR_BUF_SIZE];
     gchar *fp_label, *expiration_date, *created_date;
     const gchar *label, *status, *length;
-    gint subkey_number, key, trust;
+    gint trust;
+    GList *subkeys, *l;
     guint keyloc;
     gboolean valid;
 
     object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
     pkey = SEAHORSE_PGP_KEY (object);
-    subkey = pkey->pubkey->subkeys;
+    
+    pubkey = seahorse_pgp_key_get_public (pkey);
+    g_return_if_fail (pubkey);
+    
+    subkeys = seahorse_pgp_key_get_subkeys (pkey);
+    g_return_if_fail (subkeys);
+    subkey = seahorse_pgp_subkey_get_subkey (subkeys->data);
+    
     keyloc = seahorse_object_get_location (object);
 
     widget = glade_xml_get_widget (swidget->xml, "details-id-label");
@@ -1286,7 +1252,7 @@
 
     widget = glade_xml_get_widget (swidget->xml, "details-algo-label");
     if (widget) {
-        label = seahorse_pgp_key_get_algo (pkey, 0);
+        label = seahorse_pgp_key_get_algo (pkey);
         gtk_label_set_text (GTK_LABEL (widget), label);
     }
 
@@ -1319,7 +1285,7 @@
     widget = glade_xml_get_widget (swidget->xml, "details-trust-combobox");
     
     if (widget) {
-        gtk_widget_set_sensitive (widget, !(pkey->pubkey->disabled));
+        gtk_widget_set_sensitive (widget, !pubkey->disabled);
         model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
         
         valid = gtk_tree_model_get_iter_first (model, &iter);
@@ -1371,10 +1337,9 @@
                                                      "text", SUBKEY_LENGTH, NULL);
     }
 
-    subkey_number = seahorse_pgp_key_get_num_subkeys (pkey);
-    for (key = 0; key < subkey_number; key++) {
+    for (l = subkeys; l; l = g_list_next (l)) {
 
-        subkey = seahorse_pgp_key_get_nth_subkey (pkey, key);
+        subkey = seahorse_pgp_subkey_get_subkey (l->data);
 
         if (subkey->revoked)
         	status = _("Revoked");
@@ -1394,9 +1359,9 @@
 
         gtk_list_store_append (store, &iter);
         gtk_list_store_set (store, &iter,  
-                            SUBKEY_INDEX, key,
-                            SUBKEY_ID, seahorse_pgp_key_get_id (pkey->pubkey, key),
-                            SUBKEY_TYPE, seahorse_pgp_key_get_algo (pkey, key),
+                            SUBKEY_OBJECT, l->data,
+                            SUBKEY_ID, seahorse_pgp_subkey_get_keyid (l->data),
+                            SUBKEY_TYPE, seahorse_pgp_subkey_get_algorithm (l->data),
                             SUBKEY_CREATED, created_date,
                             SUBKEY_EXPIRES, expiration_date,
                             SUBKEY_STATUS,  status, 
@@ -1405,14 +1370,7 @@
         
         g_free (expiration_date);
         g_free (created_date);
-
-        if (!key) 
-            default_key = iter;
     } 
-    
-    gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL(store));
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
-    gtk_tree_selection_select_iter (selection, &default_key);
 }
 
 /* -----------------------------------------------------------------------------
@@ -1507,55 +1465,57 @@
 static void
 signatures_populate_model (SeahorseWidget *swidget, SeahorseObjectModel *skmodel)
 {
-    SeahorseObject *object;
-    SeahorsePGPKey *pkey;
-    GtkTreeIter iter;
-    GtkWidget *widget;
-    const gchar *keyid;
-    gpgme_user_id_t uid;
-    gpgme_key_sig_t sig;
-    gboolean have_sigs = FALSE;
-    GSList *rawids = NULL;
-    GList *keys, *l;
+	SeahorseObject *object;
+	SeahorsePgpKey *pkey;
+	GtkTreeIter iter;
+	GtkWidget *widget;
+	gpgme_user_id_t userid;
+	gpgme_key_sig_t sig;
+	gboolean have_sigs = FALSE;
+	GSList *rawids = NULL;
+	GList *keys, *l, *uids;
 
-    pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
-    widget = glade_xml_get_widget (swidget->xml, "signatures-tree");
+	pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+	widget = glade_xml_get_widget (swidget->xml, "signatures-tree");
+	if (!widget)
+		return;
     
-    keyid = seahorse_pgp_key_get_id (pkey->pubkey, 0);
+	uids = seahorse_pgp_key_get_uids (pkey);
 
-    /* Build a list of all the keyids */        
-    for (uid = pkey->pubkey->uids; uid; uid = uid->next) {
-        for (sig = uid->signatures; sig; sig = sig->next) {
-            /* Never show self signatures, they're implied */
-            if (strcmp (sig->keyid, keyid) == 0)
-                continue;
-            have_sigs = TRUE;
-            rawids = g_slist_prepend (rawids, sig->keyid);
-        }
-    }
+	/* Build a list of all the keyids */        
+	for (l = uids; l; l = g_list_next (l)) {
+		userid = seahorse_pgp_uid_get_userid (l->data);
+		for (sig = userid->signatures; sig; sig = sig->next) {
+			/* Never show self signatures, they're implied */
+			if (seahorse_pgp_key_has_keyid (pkey, sig->keyid))
+				continue;
+			have_sigs = TRUE;
+			rawids = g_slist_prepend (rawids, sig->keyid);
+		}
+	}
     
-    /* Only show signatures area when there are signatures */
-    seahorse_widget_set_visible (swidget, "signatures-area", have_sigs);
+	/* Only show signatures area when there are signatures */
+	seahorse_widget_set_visible (swidget, "signatures-area", have_sigs);
 
-    if (skmodel) {
+	if (skmodel) {
     
-        /* String out duplicates */
-        rawids = unique_slist_strings (rawids);
+		/* String out duplicates */
+		rawids = unique_slist_strings (rawids);
         
-        /* Pass it to 'DiscoverKeys' for resolution/download */
-        keys = seahorse_context_discover_objects (SCTX_APP (), SEAHORSE_PGP, rawids);
-        g_slist_free (rawids);
-        rawids = NULL;
-        
-        /* Add the keys to the store */
-        for (l = keys; l; l = g_list_next (l)) {
-            object = SEAHORSE_OBJECT (l->data);
-            gtk_tree_store_append (GTK_TREE_STORE (skmodel), &iter, NULL);
+		/* Pass it to 'DiscoverKeys' for resolution/download */
+		keys = seahorse_context_discover_objects (SCTX_APP (), SEAHORSE_PGP, rawids);
+		g_slist_free (rawids);
+		rawids = NULL;
+        
+		/* Add the keys to the store */
+		for (l = keys; l; l = g_list_next (l)) {
+			object = SEAHORSE_OBJECT (l->data);
+			gtk_tree_store_append (GTK_TREE_STORE (skmodel), &iter, NULL);
             
-            /* This calls the 'update-row' callback, to set the values for the key */
-            seahorse_object_model_set_row_object (SEAHORSE_OBJECT_MODEL (skmodel), &iter, object);
-        }
-    }
+			/* This calls the 'update-row' callback, to set the values for the key */
+			seahorse_object_model_set_row_object (SEAHORSE_OBJECT_MODEL (skmodel), &iter, object);
+		}
+	}
 }
 
 /* Refilter when the user toggles the 'only show trusted' checkbox */
@@ -1573,9 +1533,14 @@
 static void 
 trust_sign_clicked (GtkWidget *widget, SeahorseWidget *swidget)
 {
-	g_return_if_fail (SEAHORSE_IS_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object));
-	seahorse_pgp_sign_prompt (SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object), 
-	                          0, GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
+	SeahorsePgpKey *pkey;
+	GList *uids;
+	
+	pkey = SEAHORSE_PGP_KEY (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+	uids = seahorse_pgp_key_get_uids (pkey);
+	g_return_if_fail (uids);
+	
+	seahorse_pgp_sign_prompt (uids->data, GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)));
 }
 
 static void
@@ -1636,11 +1601,29 @@
     return !g_object_get_data (G_OBJECT (model), "only-trusted") || trusted;
 }
 
+gboolean        
+key_have_signatures (SeahorsePgpKey *pkey, guint types)
+{
+	gpgme_key_t key;
+	gpgme_user_id_t uid;
+	gpgme_key_sig_t sig;
+	
+	key = seahorse_pgp_key_get_public (pkey);
+	for (uid = key->uids; uid; uid = uid->next) {
+		for (sig = uid->signatures; sig; sig = sig->next) {
+			if (seahorse_pgp_uid_signature_get_type (sig) & types)
+				return TRUE;
+		}
+	}
+    
+	return FALSE;
+}
+
 static void 
 do_trust (SeahorseWidget *swidget)
 {
     SeahorseObject *object;
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
     GtkWidget *widget;
     GtkTreeStore *store;
     GtkTreeModelFilter *filter;
@@ -1725,18 +1708,18 @@
     
         /* Managed check boxes */
         if (managed) {
-            widget = seahorse_widget_get_widget (swidget, "trust-marginal-check");
-            g_return_if_fail (widget != NULL);
-            gtk_widget_set_sensitive (widget, TRUE);
+            widget = glade_xml_get_widget (swidget->xml, "trust-marginal-check");
+            if (widget != NULL) {
+                gtk_widget_set_sensitive (widget, TRUE);
             
-            g_signal_handlers_block_by_func (widget, trust_marginal_toggled, swidget);
-            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), trust != SEAHORSE_VALIDITY_UNKNOWN);
-            g_signal_handlers_unblock_by_func (widget, trust_marginal_toggled, swidget);
-        
+                g_signal_handlers_block_by_func (widget, trust_marginal_toggled, swidget);
+                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), trust != SEAHORSE_VALIDITY_UNKNOWN);
+                g_signal_handlers_unblock_by_func (widget, trust_marginal_toggled, swidget);
+            }
         }
     
         /* Signing and revoking */
-        sigpersonal = seahorse_pgp_key_have_signatures (pkey, SKEY_PGPSIG_PERSONAL);
+        sigpersonal = key_have_signatures (pkey, SKEY_PGPSIG_PERSONAL);
         show_glade_widget (swidget, "sign-area", !sigpersonal);
         show_glade_widget (swidget, "revoke-area", sigpersonal);
         
@@ -1744,49 +1727,51 @@
         set_glade_image (swidget, "sign-image", icon);
     }
     
-    /* The actual signatures listing */
-    widget = glade_xml_get_widget (swidget->xml, "signatures-tree");
-    filter = GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
-    
-    if (filter) {
-        store = GTK_TREE_STORE (gtk_tree_model_filter_get_model (filter));
-        gtk_tree_store_clear (store);
-    
-    /* First time create the store */
-    } else {
-        
-        /* Create a new SeahorseObjectModel store.... */
-        store = GTK_TREE_STORE (seahorse_object_model_new (SIGN_N_COLUMNS, (GType*)sign_columns));
-        g_signal_connect (store, "update-row", G_CALLBACK (trust_update_row), swidget);
-        
-        /* .... and a filter to go ontop of it */
-        filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL));
-        gtk_tree_model_filter_set_visible_func (filter, 
-                                (GtkTreeModelFilterVisibleFunc)trust_filter, NULL, NULL);
-        
-        /* Make the colunms for the view */
-        renderer = gtk_cell_renderer_pixbuf_new ();
-        g_object_set (renderer, "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
-        gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
-                                                     -1, "", renderer,
-                                                     "stock-id", SIGN_ICON, NULL);
-        gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), 
-                                                     -1, _("Name/Email"), gtk_cell_renderer_text_new (), 
-                                                     "text", SIGN_NAME, NULL);
-        gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), 
-                                                     -1, _("Key ID"), gtk_cell_renderer_text_new (), 
-                                                     "text", SIGN_KEYID, NULL);
-        
-        gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL(filter));
-        
-        glade_xml_signal_connect_data (swidget->xml, "on_signatures_toggle_toggled",
-                                       G_CALLBACK (trusted_toggled), filter);
-        widget = glade_xml_get_widget (swidget->xml, "signatures-toggle");
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
-        trusted_toggled (GTK_TOGGLE_BUTTON (widget), filter);
-    } 
+	/* The actual signatures listing */
+	widget = glade_xml_get_widget (swidget->xml, "signatures-tree");
+	if(widget) {
+		filter = GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (GTK_TREE_VIEW (widget)));
+    
+		if (filter) {
+			store = GTK_TREE_STORE (gtk_tree_model_filter_get_model (filter));
+			gtk_tree_store_clear (store);
+    
+			/* First time create the store */
+		} else {
+        
+			/* Create a new SeahorseObjectModel store.... */
+			store = GTK_TREE_STORE (seahorse_object_model_new (SIGN_N_COLUMNS, (GType*)sign_columns));
+			g_signal_connect (store, "update-row", G_CALLBACK (trust_update_row), swidget);
+        
+			/* .... and a filter to go ontop of it */
+			filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL));
+			gtk_tree_model_filter_set_visible_func (filter, 
+			                                        (GtkTreeModelFilterVisibleFunc)trust_filter, NULL, NULL);
+        
+			/* Make the colunms for the view */
+			renderer = gtk_cell_renderer_pixbuf_new ();
+			g_object_set (renderer, "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
+			gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget),
+			                                             -1, "", renderer,
+			                                             "stock-id", SIGN_ICON, NULL);
+			gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), 
+			                                             -1, _("Name/Email"), gtk_cell_renderer_text_new (), 
+			                                             "text", SIGN_NAME, NULL);
+			gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), 
+			                                             -1, _("Key ID"), gtk_cell_renderer_text_new (), 
+			                                             "text", SIGN_KEYID, NULL);
+			
+			gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL(filter));
+        
+			glade_xml_signal_connect_data (swidget->xml, "on_signatures_toggle_toggled",
+			                               G_CALLBACK (trusted_toggled), filter);
+			widget = glade_xml_get_widget (swidget->xml, "signatures-toggle");
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+			trusted_toggled (GTK_TOGGLE_BUTTON (widget), filter);
+		}
+	}
 
-    signatures_populate_model (swidget, SEAHORSE_OBJECT_MODEL (store));
+	signatures_populate_model (swidget, SEAHORSE_OBJECT_MODEL (store));
 }
 
 /* -----------------------------------------------------------------------------
@@ -1814,7 +1799,7 @@
 }
 
 static SeahorseWidget*
-setup_public_properties (SeahorsePGPKey *pkey, GtkWindow *parent)
+setup_public_properties (SeahorsePgpKey *pkey, GtkWindow *parent)
 {
     SeahorseWidget *swidget;
     GtkWidget *widget;
@@ -1849,7 +1834,7 @@
 }
 
 static SeahorseWidget*
-setup_private_properties (SeahorsePGPKey *pkey, GtkWindow *parent)
+setup_private_properties (SeahorsePgpKey *pkey, GtkWindow *parent)
 {
     SeahorseWidget *swidget;
     GtkWidget *widget;
@@ -1884,7 +1869,7 @@
 }
 
 void
-seahorse_pgp_key_properties_show (SeahorsePGPKey *pkey, GtkWindow *parent)
+seahorse_pgp_key_properties_show (SeahorsePgpKey *pkey, GtkWindow *parent)
 {
     SeahorseObject *sobj = SEAHORSE_OBJECT (pkey);
     SeahorseSource *sksrc;

Modified: trunk/pgp/seahorse-pgp-key.c
==============================================================================
--- trunk/pgp/seahorse-pgp-key.c	(original)
+++ trunk/pgp/seahorse-pgp-key.c	Fri Dec 12 23:54:26 2008
@@ -18,7 +18,7 @@
  * 59 Temple Place, Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#include <config.h>
+#include "config.h"
 
 #include <string.h>
 
@@ -29,188 +29,290 @@
 #include "seahorse-gtkstock.h"
 #include "seahorse-util.h"
 
+#include "common/seahorse-object-list.h"
+
+#include "pgp/seahorse-pgp.h"
 #include "pgp/seahorse-gpgmex.h"
 #include "pgp/seahorse-pgp-key.h"
+#include "pgp/seahorse-pgp-key-op.h"
 
 enum {
-    PROP_0,
-    PROP_PUBKEY,
-    PROP_SECKEY,
-    PROP_SIMPLE_NAME,
-    PROP_FINGERPRINT,
-    PROP_VALIDITY,
-    PROP_VALIDITY_STR,
-    PROP_TRUST,
-    PROP_TRUST_STR,
-    PROP_EXPIRES,
-    PROP_EXPIRES_STR,
-    PROP_LENGTH
+	PROP_0,
+	PROP_PUBKEY,
+	PROP_SECKEY,
+	PROP_PHOTOS,
+	PROP_SUBKEYS,
+	PROP_UIDS,
+	PROP_FINGERPRINT,
+	PROP_VALIDITY,
+	PROP_VALIDITY_STR,
+	PROP_TRUST,
+	PROP_TRUST_STR,
+	PROP_EXPIRES,
+	PROP_EXPIRES_STR,
+	PROP_LENGTH,
+	PROP_ALGO
 };
 
-G_DEFINE_TYPE (SeahorsePGPKey, seahorse_pgp_key, SEAHORSE_TYPE_OBJECT);
+G_DEFINE_TYPE (SeahorsePgpKey, seahorse_pgp_key, SEAHORSE_TYPE_OBJECT);
+
+struct _SeahorsePgpKeyPrivate {
+	gpgme_key_t pubkey;   		/* The public key */
+	gpgme_key_t seckey;      	/* The secret key */
+	gboolean has_secret;		/* Whether we have a secret key or not */
+
+	int list_mode;                  /* What to load our public key as */
+	
+	GList *uids;			/* All the UID objects */
+	GList *subkeys;                 /* All the Subkey objects */
+	
+	GList *photos;                  /* List of photos */
+	gboolean photos_loaded;		/* Photos were loaded */
+};
 
 /* -----------------------------------------------------------------------------
  * INTERNAL HELPERS
  */
 
-static gchar*
-convert_string (const gchar *str, gboolean escape)
+static gboolean 
+load_gpgme_key (GQuark id, int mode, int secret, gpgme_key_t *key)
 {
-    gchar *t, *ret;
-    
-    if (!str)
-        return NULL;
-    
-    /* If not utf8 valid, assume latin 1 */
-    if (!g_utf8_validate (str, -1, NULL))
-    {
-        ret = g_convert (str, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
-        if (escape) {
-            t = ret;
-            ret = g_markup_escape_text (t, -1);
-            g_free (t);
-        }
-        
-        return ret;
-    }
+	GError *err = NULL;
+	gpgme_ctx_t ctx;
+	gpgme_error_t gerr;
+	
+	ctx = seahorse_pgp_source_new_context ();
+	gpgme_set_keylist_mode (ctx, mode);
+	gerr = gpgme_op_keylist_start (ctx, seahorse_pgp_key_get_rawid (id), secret);
+	if (GPG_IS_OK (gerr)) {
+		gerr = gpgme_op_keylist_next (ctx, key);
+		gpgme_op_keylist_end (ctx);
+	}
 
-    if (escape)
-        return g_markup_escape_text (str, -1);
-    else
-        return g_strdup (str);
+	gpgme_release (ctx);
+	
+	if (!GPG_IS_OK (gerr)) {
+		seahorse_gpgme_to_error (gerr, &err);
+		g_message ("couldn't load PGP key: %s", err->message);
+		return FALSE;
+	}
+	
+	return TRUE;
 }
 
-static gchar* 
-calc_fingerprint (SeahorsePGPKey *pkey)
+static gboolean
+require_key_public (SeahorsePgpKey *self, int list_mode)
 {
-    const gchar *raw;
-    GString *string;
-    guint index, len;
-    gchar *fpr;
-    
-    g_assert (pkey->pubkey && pkey->pubkey->subkeys);
-
-    raw = pkey->pubkey->subkeys->fpr;
-    g_return_val_if_fail (raw != NULL, NULL);
+	gpgme_key_t key = NULL;
+	gboolean ret;
+	GQuark id;
+	
+	if (self->pv->pubkey && (self->pv->list_mode & list_mode) == list_mode)
+		return TRUE;
+	
+	list_mode |= self->pv->list_mode;
+	
+	id = seahorse_object_get_id (SEAHORSE_OBJECT (self));
+	g_return_val_if_fail (id, FALSE);
+	
+	ret = load_gpgme_key (id, list_mode, FALSE, &key);
+	if (!ret)
+		return FALSE;
+	
+	self->pv->list_mode = list_mode;
+	seahorse_pgp_key_set_public (self, key);
+	gpgmex_key_unref (key);
+	
+	return TRUE;
+}
 
-    string = g_string_new ("");
-    len = strlen (raw);
-    
-    for (index = 0; index < len; index++) {
-        if (index > 0 && index % 4 == 0)
-            g_string_append (string, " ");
-        g_string_append_c (string, raw[index]);
-    }
-    
-    fpr = string->str;
-    g_string_free (string, FALSE);
-    
-    return fpr;
+static gboolean
+require_key_private (SeahorsePgpKey *self)
+{
+	gpgme_key_t key = NULL;
+	gboolean ret;
+	GQuark id;
+	
+	if (self->pv->seckey)
+		return TRUE;
+	if (!self->pv->has_secret)
+		return FALSE;
+	
+	id = seahorse_object_get_id (SEAHORSE_OBJECT (self));
+	g_return_val_if_fail (id, FALSE);
+	
+	ret = load_gpgme_key (id, GPGME_KEYLIST_MODE_LOCAL, TRUE, &key);
+	if (!ret)
+		return FALSE;
+	
+	seahorse_pgp_key_set_private (self, key);
+	gpgmex_key_unref (key);
+	
+	return TRUE;
 }
 
-static SeahorseValidity 
-calc_validity (SeahorsePGPKey *pkey)
+static gboolean
+require_key_uids (SeahorsePgpKey *self)
 {
-	g_return_val_if_fail (pkey->pubkey, SEAHORSE_VALIDITY_UNKNOWN);
-	g_return_val_if_fail (pkey->uids, SEAHORSE_VALIDITY_UNKNOWN);
+	return require_key_public (self, GPGME_KEYLIST_MODE_LOCAL);
+}
 
-	if (pkey->pubkey->revoked)
-		return SEAHORSE_VALIDITY_REVOKED;
-	if (pkey->pubkey->disabled)
-		return SEAHORSE_VALIDITY_DISABLED;
-	return seahorse_pgp_uid_get_validity (pkey->uids->data);
+static gboolean
+require_key_subkeys (SeahorsePgpKey *self)
+{
+	return require_key_public (self, GPGME_KEYLIST_MODE_LOCAL);
 }
 
-static SeahorseValidity 
-calc_trust (SeahorsePGPKey *pkey)
+static gboolean
+require_key_photos (SeahorsePgpKey *self)
 {
-    g_return_val_if_fail (pkey->pubkey, SEAHORSE_VALIDITY_UNKNOWN);
-    return gpgmex_validity_to_seahorse (pkey->pubkey->owner_trust);
+	gpgme_error_t gerr;
+	
+	if (self->pv->photos_loaded)
+		return TRUE;
+	
+	gerr = seahorse_pgp_key_op_photos_load (self);
+	if (!GPG_IS_OK (gerr)) {
+		g_warning ("couldn't load key photos: %s", gpgme_strerror (gerr));
+		return FALSE;
+	}
+	
+	self->pv->photos_loaded = TRUE;
+	return TRUE;
 }
 
 static gchar* 
-calc_short_name (SeahorsePGPKey *pkey)
+calc_short_name (SeahorsePgpKey *self)
 {
-	SeahorsePGPUid *uid = pkey->uids->data;
+	SeahorsePgpUid *uid;
+	
+	if (!require_key_uids (self))
+		return NULL;
+
+	uid = self->pv->uids->data;
 	return uid ? seahorse_pgp_uid_get_name (uid) : NULL;
 }
 
 static gchar* 
-calc_name (SeahorsePGPKey *self)
+calc_name (SeahorsePgpKey *self)
 {
-	SeahorsePGPUid *uid;
-	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
-	uid = g_list_nth_data (self->uids, 0);
-	return uid ? seahorse_pgp_uid_get_display_name (uid) : NULL;
+	SeahorsePgpUid *uid;
+
+	if (!require_key_uids (self))
+		return NULL;
+
+	uid = self->pv->uids->data;
+	return uid ? seahorse_pgp_uid_calc_label (seahorse_pgp_uid_get_userid (uid)) : "";
 }
 
 static gchar* 
-calc_markup (SeahorsePGPKey *self)
+calc_markup (SeahorsePgpKey *self, guint flags)
 {
-	SeahorsePGPUid *uid;
-	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
-	uid = g_list_nth_data (self->uids, 0);
-	return uid ? seahorse_pgp_uid_get_markup (uid, seahorse_object_get_flags (SEAHORSE_OBJECT (self))) : NULL;
-}
+	SeahorsePgpUid *uid;
 
+	if (!require_key_uids (self))
+		return NULL;
 
-static void 
-update_uids (SeahorsePGPKey *pkey)
+	uid = self->pv->uids->data;
+	return uid ? seahorse_pgp_uid_calc_markup (seahorse_pgp_uid_get_userid (uid), flags) : "";
+}
+
+static void
+renumber_actual_uids (SeahorsePgpKey *self)
 {
-	gpgme_user_id_t guid;
-	SeahorsePGPUid *uid;
-	SeahorseSource *source;
+	GArray *index_map;
 	GList *l;
-	guint index = 1;
+	guint index, i;
 	
-	source = seahorse_object_get_source (SEAHORSE_OBJECT (pkey));
-	g_return_if_fail (SEAHORSE_IS_SOURCE (source));
+	g_assert (SEAHORSE_IS_PGP_KEY (self));
 	
-	l = pkey->uids;
-	guid = pkey->pubkey ? pkey->pubkey->uids : NULL;
+	/* 
+	 * This function is necessary because the uid stored in a gpgme_user_id_t
+	 * struct is only usable with gpgme functions.  Problems will be caused if 
+	 * that uid is used with functions found in seahorse-pgp-key-op.h.  This 
+	 * function is only to be called with uids from gpgme_user_id_t structs.
+	 */
+	
+	/* First we build a bitmap of where all the photo uid indexes are */
+	index_map = g_array_new (FALSE, TRUE, sizeof (gboolean));
+	for (l = self->pv->photos; l; l = g_list_next (l)) {
+		index = seahorse_pgp_photo_get_index (l->data);
+		if (index >= index_map->len)
+			g_array_set_size (index_map, index + 1);
+		g_array_index (index_map, gboolean, index) = TRUE;
+	}
 	
-	/* Look for out of sync or missing UIDs */
-	while (l != NULL) {
-		g_return_if_fail (SEAHORSE_IS_PGP_UID (l->data));
-		uid = SEAHORSE_PGP_UID (l->data);
-		l = g_list_next (l);
-		
-		/* Remove if no uid */
-		if (!guid) {
-			seahorse_object_set_parent (SEAHORSE_OBJECT (uid), NULL);			
-			pkey->uids = g_list_remove (pkey->uids, uid);
+	/* Now for each UID we add however many photo indexes are below the gpgme index */
+	for (l = self->pv->uids; l; l = g_list_next (l)) {
+		index = seahorse_pgp_uid_get_gpgme_index (l->data);
+		for (i = 0; i < index_map->len && i < index; ++i) {
+			if(g_array_index (index_map, gboolean, index))
+				++index;
+		}
+		seahorse_pgp_uid_set_actual_index (l->data, index);
+	}
+	
+	g_array_free (index_map, TRUE);
+}
+
+static void 
+realize_uids (SeahorsePgpKey *self)
+{
+	gpgme_user_id_t guid;
+	SeahorsePgpUid *uid;
+	GList *list = NULL;
+	
+	if (self->pv->pubkey) {
+
+		for (guid = self->pv->pubkey->uids; guid; guid = guid->next) {
+			uid = seahorse_pgp_uid_new (self->pv->pubkey, guid);
+			list = seahorse_object_list_prepend (list, uid);
 			g_object_unref (uid);
-		} else {
-			/* Bring this UID up to date */
-			g_object_set (uid, "userid", guid, "index", index, "source", source, NULL);
-			++index;
 		}
+		
+		list = g_list_reverse (list);
+	}
 
-		if (guid)
-			guid = guid->next; 
+	seahorse_pgp_key_set_uids (self, list);
+	seahorse_object_list_free (list);
+}
+
+static void 
+realize_subkeys (SeahorsePgpKey *self)
+{
+	gpgme_subkey_t gsubkey;
+	SeahorsePgpSubkey *subkey;
+	GList *list = NULL;
+	
+	if (self->pv->pubkey) {
+
+		for (gsubkey = self->pv->pubkey->subkeys; gsubkey; gsubkey = gsubkey->next) {
+			subkey = seahorse_pgp_subkey_new (self->pv->pubkey, gsubkey);
+			list = seahorse_object_list_prepend (list, subkey);
+			g_object_unref (subkey);
+		}
+		
+		list = g_list_reverse (list);
 	}
-	
-	/* Add new UIDs */
-	while (guid != NULL) {
-		uid = seahorse_pgp_uid_new (pkey->pubkey, guid);
-		g_object_set (uid, "index", index, "source", source, NULL);
-		++index;
-		pkey->uids = g_list_append (pkey->uids, uid);
-		guid = guid->next;
-	}
-	
-	/* Set 'parent' on all UIDs but the first one */
-	l = pkey->uids;
-	if (l != NULL)
-		seahorse_object_set_parent (SEAHORSE_OBJECT (l->data), NULL);
-	for (l = g_list_next (l); l; l = g_list_next (l))
-		seahorse_object_set_parent (SEAHORSE_OBJECT (l->data), SEAHORSE_OBJECT (pkey));
+
+	seahorse_pgp_key_set_subkeys (self, list);
+	seahorse_object_list_free (list);
+}
+
+static void
+refresh_each_object (SeahorseObject *object, gpointer data)
+{
+	seahorse_object_refresh (object);
 }
 
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
 static void
-changed_key (SeahorsePGPKey *self)
+seahorse_pgp_key_realize (SeahorseObject *obj)
 {
-	SeahorseObject *obj = SEAHORSE_OBJECT (self);
+	SeahorsePgpKey *self = SEAHORSE_PGP_KEY (obj);
 	SeahorseLocation loc;
 	SeahorseUsage usage;
 	const gchar *description, *icon, *identifier;
@@ -218,45 +320,36 @@
 	GQuark id;
 	guint flags;
 	
-	if (!self->pubkey) {
-		
-		self->loaded = SKEY_INFO_NONE;
-		g_object_set (obj,
-		              "id", 0,
-		              "label", "",
-		              "icon", NULL,
-		              "usage", SEAHORSE_USAGE_NONE,
-		              "markup", "",
-		              "idenitfier", "",
-		              "nickname", "",
-		              "description", _("Invalid"),
-		              "location", SEAHORSE_LOCATION_INVALID,
-		              "flags", SEAHORSE_FLAG_DISABLED,
-		              NULL);
-		return;
-	}
-
+	if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		g_return_if_reached ();
+	
+	g_return_if_fail (self->pv->pubkey);
+	g_return_if_fail (self->pv->pubkey->subkeys);
+	id = seahorse_pgp_key_get_cannonical_id (self->pv->pubkey->subkeys->keyid);
+	g_object_set (self, "id", id, NULL); 
+	
+	SEAHORSE_OBJECT_CLASS (seahorse_pgp_key_parent_class)->realize (obj);
+	
 	/* Update the sub UIDs */
-	update_uids (self);
-
+	realize_uids (self);
+	realize_subkeys (self);
+	
 	/* The key id */
-	id = 0;
-	identifier = NULL;
-	if (self->pubkey->subkeys) {
-		id = seahorse_pgp_key_get_cannonical_id (self->pubkey->subkeys->keyid);
-		identifier = self->pubkey->subkeys->keyid;
-	}
+	g_return_if_fail (self->pv->pubkey->subkeys);
+	identifier = self->pv->pubkey->subkeys->keyid;
 
 	/* The location */
 	loc = seahorse_object_get_location (obj);
-	if (self->pubkey->keylist_mode & GPGME_KEYLIST_MODE_EXTERN && 
+	
+	if (self->pv->pubkey->keylist_mode & GPGME_KEYLIST_MODE_EXTERN && 
 	    loc <= SEAHORSE_LOCATION_REMOTE)
 		loc = SEAHORSE_LOCATION_REMOTE;
+	
 	else if (loc <= SEAHORSE_LOCATION_LOCAL)
 		loc = SEAHORSE_LOCATION_LOCAL;
 
 	/* The type */
-	if (self->seckey) {
+	if (self->pv->seckey) {
 		usage = SEAHORSE_USAGE_PRIVATE_KEY;
 		description = _("Private PGP Key");
 		icon = SEAHORSE_STOCK_SECRET;
@@ -269,36 +362,35 @@
 	/* The flags */
 	flags = SEAHORSE_FLAG_EXPORTABLE;
 
-	if (!self->pubkey->disabled && !self->pubkey->expired && 
-	    !self->pubkey->revoked && !self->pubkey->invalid) {
-		if (calc_validity (self) >= SEAHORSE_VALIDITY_MARGINAL)
+	if (!self->pv->pubkey->disabled && !self->pv->pubkey->expired && 
+	    !self->pv->pubkey->revoked && !self->pv->pubkey->invalid) {
+		if (seahorse_pgp_key_get_validity (self) >= SEAHORSE_VALIDITY_MARGINAL)
 			flags |= SEAHORSE_FLAG_IS_VALID;
-		if (self->pubkey->can_encrypt)
+		if (self->pv->pubkey->can_encrypt)
 			flags |= SEAHORSE_FLAG_CAN_ENCRYPT;
-		if (self->seckey && self->pubkey->can_sign)
+		if (self->pv->seckey && self->pv->pubkey->can_sign)
 			flags |= SEAHORSE_FLAG_CAN_SIGN;
 	}
 
-	if (self->pubkey->expired)
+	if (self->pv->pubkey->expired)
 		flags |= SEAHORSE_FLAG_EXPIRED;
 
-	if (self->pubkey->revoked)
+	if (self->pv->pubkey->revoked)
 		flags |= SEAHORSE_FLAG_REVOKED;
 
-	if (self->pubkey->disabled)
+	if (self->pv->pubkey->disabled)
 		flags |= SEAHORSE_FLAG_DISABLED;
 
-	if (calc_trust (self) >= SEAHORSE_VALIDITY_MARGINAL && 
-	    !self->pubkey->revoked && !self->pubkey->disabled && 
-	    !self->pubkey->expired)
+	if (seahorse_pgp_key_get_trust (self) >= SEAHORSE_VALIDITY_MARGINAL && 
+	    !self->pv->pubkey->revoked && !self->pv->pubkey->disabled && 
+	    !self->pv->pubkey->expired)
 		flags |= SEAHORSE_FLAG_TRUSTED;
-	
+		
 	name = calc_name (self);
-	markup = calc_markup (self);
+	markup = calc_markup (self, flags);
 	nickname = calc_short_name (self);
-	
+		
 	g_object_set (obj,
-		      "id", id,
 		      "label", name,
 		      "icon", icon,
 		      "usage", usage,
@@ -309,71 +401,96 @@
 		      "location", loc,
 		      "flags", flags,
 		      NULL);
-	
+		
 	g_free (name);
 	g_free (markup);
 	g_free (nickname);
 }
 
-
-/* -----------------------------------------------------------------------------
- * OBJECT 
- */
-
 static void
-seahorse_pgp_key_init (SeahorsePGPKey *pkey)
+seahorse_pgp_key_flush (SeahorseObject *obj)
 {
+	SeahorsePgpKey *self = SEAHORSE_PGP_KEY (obj);
+	GList *l;
+	
+	/* Free all the attached UIDs */
+	for (l = self->pv->uids; l; l = g_list_next (l))
+		seahorse_object_set_parent (l->data, NULL);
+	seahorse_object_list_free (self->pv->uids);
+	self->pv->uids = NULL;
+
+	/* Free all the attached Photos */
+	seahorse_object_list_free (self->pv->photos);
+	self->pv->photos = NULL;
+	self->pv->photos_loaded = FALSE;
+	
+	/* Free all the attached Subkeys */
+	seahorse_object_list_free (self->pv->subkeys);
+	self->pv->subkeys = NULL;
+
+	if (self->pv->pubkey)
+		gpgmex_key_unref (self->pv->pubkey);
+	if (self->pv->seckey)
+		gpgmex_key_unref (self->pv->seckey);
+	self->pv->pubkey = self->pv->seckey = NULL;
 
+	SEAHORSE_OBJECT_CLASS (seahorse_pgp_key_parent_class)->flush (obj);
 }
 
+static void
+seahorse_pgp_key_init (SeahorsePgpKey *self)
+{
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_PGP_KEY, SeahorsePgpKeyPrivate);
+}
 
 static void
 seahorse_pgp_key_get_property (GObject *object, guint prop_id,
                                GValue *value, GParamSpec *pspec)
 {
-	SeahorsePGPKey *self = SEAHORSE_PGP_KEY (object);
-	gchar *expires;
+	SeahorsePgpKey *self = SEAHORSE_PGP_KEY (object);
     
 	switch (prop_id) {
 	case PROP_PUBKEY:
-		g_value_set_pointer (value, self->pubkey);
+		g_value_set_boxed (value, seahorse_pgp_key_get_public (self));
 		break;
 	case PROP_SECKEY:
-		g_value_set_pointer (value, self->seckey);
+		g_value_set_boxed (value, seahorse_pgp_key_get_private (self));
+		break;
+	case PROP_PHOTOS:
+		g_value_set_boxed (value, seahorse_pgp_key_get_photos (self));
+		break;
+	case PROP_SUBKEYS:
+		g_value_set_pointer (value, seahorse_pgp_key_get_subkeys (self));
+		break;
+	case PROP_UIDS:
+		g_value_set_boxed (value, seahorse_pgp_key_get_uids (self));
 		break;
 	case PROP_FINGERPRINT:
-		g_value_take_string (value, calc_fingerprint (self));
+		g_value_take_string (value, seahorse_pgp_key_get_fingerprint (self));
 		break;
 	case PROP_VALIDITY:
-		g_value_set_uint (value, calc_validity (self));
+		g_value_set_uint (value, seahorse_pgp_key_get_validity (self));
 		break;
 	case PROP_VALIDITY_STR:
-		g_value_set_string (value, seahorse_validity_get_string (calc_validity (self)));
+		g_value_set_string (value, seahorse_pgp_key_get_validity_str (self));
 		break;
 	case PROP_TRUST:
-		g_value_set_uint (value, calc_trust (self));
+		g_value_set_uint (value, seahorse_pgp_key_get_trust (self));
 		break;
 	case PROP_TRUST_STR:
-		g_value_set_string (value, seahorse_validity_get_string (calc_trust (self)));
+		g_value_set_string (value, seahorse_pgp_key_get_trust_str (self));
 		break;
 	case PROP_EXPIRES:
-		if (self->pubkey)
-			g_value_set_ulong (value, self->pubkey->subkeys->expires);
+		g_value_set_ulong (value, seahorse_pgp_key_get_expires (self));
 		break;
 	case PROP_EXPIRES_STR:
-		if (seahorse_object_get_flags (SEAHORSE_OBJECT (self)) & SEAHORSE_FLAG_EXPIRED) {
-			expires = g_strdup (_("Expired"));
-		} else {
-			if (self->pubkey->subkeys->expires == 0)
-				expires = g_strdup ("");
-			else 
-				expires = seahorse_util_get_date_string (self->pubkey->subkeys->expires);
-		}
-		g_value_take_string (value, expires);
+		g_value_take_string (value, seahorse_pgp_key_get_expires_str (self));
 		break;
 	case PROP_LENGTH:
-		if (self->pubkey)
-			g_value_set_uint (value, self->pubkey->subkeys->length);
+		g_value_set_uint (value, seahorse_pgp_key_get_length (self));
+		break;
+	case PROP_ALGO:
+		g_value_set_string (value, seahorse_pgp_key_get_algo (self));
 		break;
 	}
 }
@@ -382,118 +499,111 @@
 seahorse_pgp_key_set_property (GObject *object, guint prop_id, const GValue *value, 
                                GParamSpec *pspec)
 {
-    SeahorsePGPKey *skey = SEAHORSE_PGP_KEY (object);
+	SeahorsePgpKey *self = SEAHORSE_PGP_KEY (object);
 
-    switch (prop_id) {
-    case PROP_PUBKEY:
-        if (skey->pubkey)
-            gpgmex_key_unref (skey->pubkey);
-        skey->pubkey = g_value_get_pointer (value);
-        if (skey->pubkey)
-            gpgmex_key_ref (skey->pubkey);
-        changed_key (skey);
-        break;
-    case PROP_SECKEY:
-        if (skey->seckey)
-            gpgmex_key_unref (skey->seckey);
-        skey->seckey = g_value_get_pointer (value);
-        if (skey->seckey)
-            gpgmex_key_ref (skey->seckey);
-        changed_key (skey);
-        break;
-    }
+	switch (prop_id) {
+	case PROP_PUBKEY:
+		seahorse_pgp_key_set_public (self, g_value_get_boxed (value));
+		break;
+	case PROP_SECKEY:
+		seahorse_pgp_key_set_private (self, g_value_get_boxed (value));
+		break;
+	}
 }
 
 static void
-seahorse_pgp_key_object_dispose (GObject *gobject)
+seahorse_pgp_key_object_dispose (GObject *obj)
 {
-	SeahorsePGPKey *pkey = SEAHORSE_PGP_KEY (gobject);
-	GList *l;
-	
-	/* Free all the attached UIDs */
-	for (l = pkey->uids; l; l = g_list_next (l)) {
-		seahorse_object_set_parent (l->data, NULL);
-		g_object_unref (l->data);
-	}
-	
-	g_list_free (pkey->uids);
-	pkey->uids = NULL;
-
-	G_OBJECT_CLASS (seahorse_pgp_key_parent_class)->dispose (gobject);
+	seahorse_pgp_key_flush (SEAHORSE_OBJECT (obj));
+	G_OBJECT_CLASS (seahorse_pgp_key_parent_class)->dispose (obj);
 }
 
 static void
-seahorse_pgp_key_object_finalize (GObject *gobject)
+seahorse_pgp_key_object_finalize (GObject *obj)
 {
-    SeahorsePGPKey *skey = SEAHORSE_PGP_KEY (gobject);
+	SeahorsePgpKey *self = SEAHORSE_PGP_KEY (obj);
 
-    g_assert (skey->uids == NULL);
-    
-    if (skey->pubkey)
-        gpgmex_key_unref (skey->pubkey);
-    if (skey->seckey)
-        gpgmex_key_unref (skey->seckey);
-    skey->pubkey = skey->seckey = NULL;
+	g_assert (self->pv->uids == NULL);
+	g_assert (self->pv->pubkey == NULL);
+	g_assert (self->pv->seckey == NULL);
+	g_assert (self->pv->photos == NULL);
+	g_assert (self->pv->subkeys == NULL);
     
-    if (skey->photoids)
-            gpgmex_photo_id_free_all (skey->photoids);
-    skey->photoids = NULL;
-    
-    G_OBJECT_CLASS (seahorse_pgp_key_parent_class)->finalize (gobject);
+	G_OBJECT_CLASS (seahorse_pgp_key_parent_class)->finalize (obj);
 }
 
 static void
-seahorse_pgp_key_class_init (SeahorsePGPKeyClass *klass)
+seahorse_pgp_key_class_init (SeahorsePgpKeyClass *klass)
 {
-    GObjectClass *gobject_class;
-    
-    seahorse_pgp_key_parent_class = g_type_class_peek_parent (klass);
-    gobject_class = G_OBJECT_CLASS (klass);
-    
-    gobject_class->dispose = seahorse_pgp_key_object_dispose;
-    gobject_class->finalize = seahorse_pgp_key_object_finalize;
-    gobject_class->set_property = seahorse_pgp_key_set_property;
-    gobject_class->get_property = seahorse_pgp_key_get_property;
-    
-    g_object_class_install_property (gobject_class, PROP_PUBKEY,
-        g_param_spec_pointer ("pubkey", "Gpgme Public Key", "Gpgme Public Key that this object represents",
-                              G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class, PROP_SECKEY,
-        g_param_spec_pointer ("seckey", "Gpgme Secret Key", "Gpgme Secret Key that this object represents",
-                              G_PARAM_READWRITE));
-                      
-    g_object_class_install_property (gobject_class, PROP_FINGERPRINT,
-        g_param_spec_string ("fingerprint", "Fingerprint", "Unique fingerprint for this key",
-                             "", G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class, PROP_VALIDITY,
-        g_param_spec_uint ("validity", "Validity", "Validity of this key",
-                           0, G_MAXUINT, 0, G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class, PROP_VALIDITY_STR,
-        g_param_spec_string ("validity-str", "Validity String", "Validity of this key as a string",
-                             "", G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class, PROP_TRUST,
-        g_param_spec_uint ("trust", "Trust", "Trust in this key",
-                           0, G_MAXUINT, 0, G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class, PROP_TRUST_STR,
-        g_param_spec_string ("trust-str", "Trust String", "Trust in this key as a string",
-                             "", G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class, PROP_EXPIRES,
-        g_param_spec_ulong ("expires", "Expires On", "Date this key expires on",
-                           0, G_MAXULONG, 0, G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class, PROP_EXPIRES_STR,
-        g_param_spec_string ("expires-str", "Expires String", "Readable expiry date",
-                             "", G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class, PROP_LENGTH,
-        g_param_spec_uint ("length", "Length", "The length of this key.",
-                           0, G_MAXUINT, 0, G_PARAM_READABLE));
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	SeahorseObjectClass *seahorse_class = SEAHORSE_OBJECT_CLASS (klass);
+	
+	seahorse_pgp_key_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePgpKeyPrivate));
+
+	gobject_class->dispose = seahorse_pgp_key_object_dispose;
+	gobject_class->finalize = seahorse_pgp_key_object_finalize;
+	gobject_class->set_property = seahorse_pgp_key_set_property;
+	gobject_class->get_property = seahorse_pgp_key_get_property;
+	
+	seahorse_class->flush = seahorse_pgp_key_flush;
+	seahorse_class->realize = seahorse_pgp_key_realize;
+    
+	g_object_class_install_property (gobject_class, PROP_PUBKEY,
+	        g_param_spec_boxed ("pubkey", "GPGME Public Key", "GPGME Public Key that this object represents",
+	                            SEAHORSE_PGP_BOXED_KEY, G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_SECKEY,
+                g_param_spec_boxed ("seckey", "GPGME Secret Key", "GPGME Secret Key that this object represents",
+                                    SEAHORSE_PGP_BOXED_KEY, G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_PHOTOS,
+                g_param_spec_boxed ("photos", "Key Photos", "Photos for the key",
+                                    SEAHORSE_BOXED_OBJECT_LIST, G_PARAM_READWRITE));
+	
+	g_object_class_install_property (gobject_class, PROP_SUBKEYS,
+                g_param_spec_boxed ("subkeys", "PGP subkeys", "PGP subkeys",
+                                    SEAHORSE_BOXED_OBJECT_LIST, G_PARAM_READABLE));
+	
+	g_object_class_install_property (gobject_class, PROP_UIDS,
+                g_param_spec_boxed ("uids", "PGP User Ids", "PGP User Ids",
+                                    SEAHORSE_BOXED_OBJECT_LIST, G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_FINGERPRINT,
+                g_param_spec_string ("fingerprint", "Fingerprint", "Unique fingerprint for this key",
+                                     "", G_PARAM_READABLE));
+
+	g_object_class_install_property (gobject_class, PROP_VALIDITY,
+	        g_param_spec_uint ("validity", "Validity", "Validity of this key",
+                                   0, G_MAXUINT, 0, G_PARAM_READABLE));
+
+        g_object_class_install_property (gobject_class, PROP_VALIDITY_STR,
+                g_param_spec_string ("validity-str", "Validity String", "Validity of this key as a string",
+                                     "", G_PARAM_READABLE));
+
+        g_object_class_install_property (gobject_class, PROP_TRUST,
+                g_param_spec_uint ("trust", "Trust", "Trust in this key",
+                                   0, G_MAXUINT, 0, G_PARAM_READABLE));
+
+        g_object_class_install_property (gobject_class, PROP_TRUST_STR,
+                g_param_spec_string ("trust-str", "Trust String", "Trust in this key as a string",
+                                     "", G_PARAM_READABLE));
+
+        g_object_class_install_property (gobject_class, PROP_EXPIRES,
+                g_param_spec_ulong ("expires", "Expires On", "Date this key expires on",
+                                    0, G_MAXULONG, 0, G_PARAM_READABLE));
+
+ 	g_object_class_install_property (gobject_class, PROP_EXPIRES_STR,
+ 	        g_param_spec_string ("expires-str", "Expires String", "Readable expiry date",
+ 	                             "", G_PARAM_READABLE));
+
+ 	g_object_class_install_property (gobject_class, PROP_LENGTH,
+ 	        g_param_spec_uint ("length", "Length", "The length of this key.",
+ 	                           0, G_MAXUINT, 0, G_PARAM_READABLE));
+ 	
+ 	g_object_class_install_property (gobject_class, PROP_ALGO,
+ 	        g_param_spec_string ("algo", "Algorithm", "The algorithm of this key.",
+ 	                             "", G_PARAM_READABLE));
 }
 
 
@@ -501,350 +611,376 @@
  * PUBLIC 
  */
 
-/**
- * seahorse_pgp_key_new:
- * @pubkey: Public PGP key
- * @pubkey: Optional Private PGP key
- *
- * Creates a new #SeahorsePGPKey 
- *
- * Returns: A new #SeahorsePGPKey
- **/
-SeahorsePGPKey* 
+SeahorsePgpKey* 
 seahorse_pgp_key_new (SeahorseSource *sksrc, gpgme_key_t pubkey, 
                       gpgme_key_t seckey)
 {
-    SeahorsePGPKey *pkey;
-    pkey = g_object_new (SEAHORSE_TYPE_PGP_KEY, "source", sksrc,
-                         "pubkey", pubkey, "seckey", seckey, NULL);
-    return pkey;
+	return g_object_new (SEAHORSE_TYPE_PGP_KEY, "source", sksrc,
+	                     "pubkey", pubkey, "seckey", seckey, NULL);
 }
 
-/**
- * seahorse_key_get_num_subkeys:
- * @skey: #SeahorseKey
- *
- * Counts the number of subkeys for @skey.
- *
- * Returns: The number of subkeys for @skey, or -1 if error.
- **/
-guint
-seahorse_pgp_key_get_num_subkeys (SeahorsePGPKey *pkey)
+GQuark
+seahorse_pgp_key_get_cannonical_id (const gchar *id)
 {
-    gint index = 0;
-    gpgme_subkey_t subkey;
-
-    g_return_val_if_fail (pkey != NULL && SEAHORSE_IS_PGP_KEY (pkey), -1);
-    g_return_val_if_fail (pkey->pubkey != NULL, -1);
-
-    subkey = pkey->pubkey->subkeys;
-    while (subkey) {
-        subkey = subkey->next;
-        index++;
+    guint len = strlen (id);
+    GQuark keyid;
+    gchar *t;
+    
+    if (len < 16) {
+        g_warning ("invalid keyid (less than 16 chars): %s", id);
+        return 0;
     }
     
-    return index;
+    if (len > 16)
+        id += len - 16;
+    
+    t = g_strdup_printf ("%s:%s", SEAHORSE_PGP_STR, id);
+    keyid = g_quark_from_string (t);
+    g_free (t);
+    
+    return keyid;
 }
 
-/**
- * seahorse_key_get_nth_subkey:
- * @skey: #SeahorseKey
- * @index: Which subkey
- *
- * Gets the the subkey at @index of @skey.
- *
- * Returns: subkey of @skey at @index, or NULL if @index is out of bounds
- */
-gpgme_subkey_t
-seahorse_pgp_key_get_nth_subkey (SeahorsePGPKey *pkey, guint index)
+const gchar* 
+seahorse_pgp_key_get_rawid (GQuark keyid)
 {
-    gpgme_subkey_t subkey;
-    guint n;
-
-    g_return_val_if_fail (pkey != NULL && SEAHORSE_IS_PGP_KEY (pkey), NULL);
-    g_return_val_if_fail (pkey->pubkey != NULL, NULL);
-
-    subkey = pkey->pubkey->subkeys;
-    for (n = index; subkey && n; n--)
-        subkey = subkey->next;
+	const gchar* id, *rawid;
+	
+	id = g_quark_to_string (keyid);
+	g_return_val_if_fail (id != NULL, NULL);
+	
+	rawid = strchr (id, ':');
+	return rawid ? rawid + 1 : id;
+}
 
-    return subkey;
+void
+seahorse_pgp_key_reload (SeahorsePgpKey *pkey)
+{
+	SeahorseSource *src;
+	
+	g_return_if_fail (SEAHORSE_IS_PGP_KEY (pkey));
+	src = seahorse_object_get_source (SEAHORSE_OBJECT (pkey));
+	g_return_if_fail (SEAHORSE_IS_PGP_SOURCE (src));
+	seahorse_source_load_async (src, seahorse_object_get_id (SEAHORSE_OBJECT (pkey)));
 }
 
-SeahorsePGPUid*
-seahorse_pgp_key_get_uid (SeahorsePGPKey *pkey, guint index)
+gpgme_key_t
+seahorse_pgp_key_get_public (SeahorsePgpKey *self)
 {
-	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), NULL);
-	return g_list_nth_data (pkey->uids, index);
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	if (require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		return self->pv->pubkey;
+	return NULL;
 }
 
-guint           
-seahorse_pgp_key_get_num_uids (SeahorsePGPKey *pkey)
+void
+seahorse_pgp_key_set_public (SeahorsePgpKey *self, gpgme_key_t key)
 {
-	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), 0);
-	return g_list_length (pkey->uids);
+	GObject *obj;
+	
+	g_return_if_fail (SEAHORSE_IS_PGP_KEY (self));
+	
+	if (self->pv->pubkey)
+		gpgmex_key_unref (self->pv->pubkey);
+	self->pv->pubkey = key;
+	if (self->pv->pubkey) {
+		gpgmex_key_ref (self->pv->pubkey);
+		self->pv->list_mode |= self->pv->pubkey->keylist_mode;
+	}
+	
+	obj = G_OBJECT (self);
+	g_object_freeze_notify (obj);
+	seahorse_pgp_key_realize (SEAHORSE_OBJECT (self));
+	g_object_notify (obj, "fingerprint");
+	g_object_notify (obj, "validity");
+	g_object_notify (obj, "validity-str");
+	g_object_notify (obj, "trust");
+	g_object_notify (obj, "trust-str");
+	g_object_notify (obj, "expires");
+	g_object_notify (obj, "expires-str");
+	g_object_notify (obj, "length");
+	g_object_notify (obj, "algo");
+	g_object_thaw_notify (obj);
 }
 
-const gchar*
-seahorse_pgp_key_get_algo (SeahorsePGPKey *pkey, guint index)
+gpgme_key_t
+seahorse_pgp_key_get_private (SeahorsePgpKey *self)
 {
-    const gchar* algo_type;
-    gpgme_subkey_t subkey;
-    
-    subkey = pkey->pubkey->subkeys;
-    while (0 < index) {
-        subkey = subkey->next;
-        index--;
-    }
-    
-    algo_type = gpgme_pubkey_algo_name (subkey->pubkey_algo);
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	if (require_key_private (self))
+		return self->pv->seckey;
+	return NULL;	
+}
 
-    if (algo_type == NULL)
-        algo_type = _("Unknown");
-    else if (g_str_equal ("Elg", algo_type) || g_str_equal("ELG-E", algo_type))
-        algo_type = _("ElGamal");
+void
+seahorse_pgp_key_set_private (SeahorsePgpKey *self, gpgme_key_t key)
+{
+	GObject *obj;
+	
+	g_return_if_fail (SEAHORSE_IS_PGP_KEY (self));
+	
+	if (self->pv->seckey)
+		gpgmex_key_unref (self->pv->seckey);
+	self->pv->seckey = key;
+	if (self->pv->seckey)
+		gpgmex_key_ref (self->pv->seckey);
+	
+	obj = G_OBJECT (self);
+	g_object_freeze_notify (obj);
+	seahorse_pgp_key_realize (SEAHORSE_OBJECT (self));
+	g_object_thaw_notify (obj);
+}
 
-    return algo_type;
+GList*
+seahorse_pgp_key_get_uids (SeahorsePgpKey *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	if (!require_key_uids (self))
+		return NULL;
+	return self->pv->uids;
 }
 
-const gchar*
-seahorse_pgp_key_get_id (gpgme_key_t key, guint index)
+void
+seahorse_pgp_key_set_uids (SeahorsePgpKey *self, GList *uids)
 {
-    gpgme_subkey_t subkey = subkey = key->subkeys;
-    guint n;
+	SeahorseSource *source;
+	GList *l;
+	
+	g_return_if_fail (SEAHORSE_IS_PGP_KEY (self));
 
-    for (n = index; subkey && n; n--)
-        subkey = subkey->next;
-    
-    g_return_val_if_fail (subkey, "");
-    return subkey->keyid;
+	/* Remove the parent on each old one */
+	for (l = self->pv->uids; l; l = g_list_next (l)) 
+		seahorse_object_set_parent (l->data, NULL);
+
+	seahorse_object_list_free (self->pv->uids);
+	self->pv->uids = seahorse_object_list_copy (uids);
+
+	source = seahorse_object_get_source (SEAHORSE_OBJECT (self));
+	g_return_if_fail (SEAHORSE_IS_SOURCE (source));
+
+	/* Set parent and source on each new one, except the first */
+	for (l = self->pv->uids ? g_list_next (self->pv->uids) : NULL;
+	     l; l = g_list_next (l)) {
+		g_object_set (l->data, "source", source, NULL);
+		seahorse_object_set_parent (l->data, SEAHORSE_OBJECT (self));
+	}
+	
+	renumber_actual_uids (self);
+	g_object_notify (G_OBJECT (self), "uids");
 }
 
-guint           
-seahorse_pgp_key_get_num_photoids (SeahorsePGPKey *pkey)
+GList*
+seahorse_pgp_key_get_subkeys (SeahorsePgpKey *self)
 {
-    gint index = 0;
-    gpgmex_photo_id_t photoid;
-
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), 0);    
-    
-    if (pkey->photoids != NULL) {
-        photoid = pkey->photoids;
-        while (photoid) {
-            photoid = photoid->next;
-            index++;
-        }
-    }
-    
-    return index;
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	if (!require_key_subkeys (self))
+		return NULL;
+	return self->pv->subkeys;
 }
 
-/**
- * seahorse_pgp_key_get_nth_photoid:
- * @skey: #SeahorseKey
- * @index: Which photo id
- *
- * Gets the the photo id at @index of @skey.
- *
- * Returns: subkey of @skey at @index, or NULL if @index is out of bounds
- */
-gpgmex_photo_id_t  
-seahorse_pgp_key_get_nth_photoid (SeahorsePGPKey *pkey, guint index)
+void
+seahorse_pgp_key_set_subkeys (SeahorsePgpKey *self, GList *subkeys)
 {
-    gpgmex_photo_id_t photoid;
-    guint n;
+	g_return_if_fail (SEAHORSE_IS_PGP_KEY (self));
+	
+	seahorse_object_list_free (self->pv->subkeys);
+	self->pv->subkeys = seahorse_object_list_copy (subkeys);
+	
+	g_object_notify (G_OBJECT (self), "subkeys");
+}
 
-    g_return_val_if_fail (pkey != NULL && SEAHORSE_IS_PGP_KEY (pkey), NULL);
-    g_return_val_if_fail (pkey->photoids != NULL, NULL);
-    
-    photoid = pkey->photoids;
-    for (n = index; photoid && n; n--)
-        photoid = photoid->next;
-
-    return photoid;
-}    
-
-gpgmex_photo_id_t 
-seahorse_pgp_key_get_photoid_n      (SeahorsePGPKey   *pkey,
-                                     guint            uid)
+GList*
+seahorse_pgp_key_get_photos (SeahorsePgpKey *self)
 {
-    gpgmex_photo_id_t photoid;
-    
-    g_return_val_if_fail (pkey != NULL && SEAHORSE_IS_PGP_KEY (pkey), NULL);
-    g_return_val_if_fail (pkey->photoids != NULL, NULL);
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	if (!require_key_photos (self))
+		return NULL;
+	return self->pv->photos;
+}
 
-    photoid = pkey->photoids;
-    while((photoid->uid != uid) && (photoid != NULL))
-        photoid = photoid->next;
-        
-    return photoid;
+void
+seahorse_pgp_key_set_photos (SeahorsePgpKey *self, GList *photos)
+{
+	g_return_if_fail (SEAHORSE_IS_PGP_KEY (self));
+	
+	seahorse_object_list_free (self->pv->photos);
+	self->pv->photos = seahorse_object_list_copy (photos);
+	self->pv->photos_loaded = TRUE;
+	
+	renumber_actual_uids (self);
+	g_object_notify (G_OBJECT (self), "photos");
 }
 
-/* 
- * This function is necessary because the uid stored in a gpgme_user_id_t
- * struct is only usable with gpgme functions.  Problems will be caused if 
- * that uid is used with functions found in seahorse-pgp-key-op.h.  This 
- * function is only to be called with uids from gpgme_user_id_t structs.
- */
-guint 
-seahorse_pgp_key_get_actual_uid       (SeahorsePGPKey   *pkey,
-                                       guint            uid)
-{
-    guint num_uids, num_photoids, uids, uid_count, i;
-    gpgmex_photo_id_t photoid;
-    gchar *ids;
-    
-    g_return_val_if_fail (pkey != NULL && SEAHORSE_IS_PGP_KEY (pkey), 0);
+gchar*
+seahorse_pgp_key_get_fingerprint (SeahorsePgpKey *self)
+{
+	const gchar *raw;
+	GString *string;
+	guint index, len;
+	gchar *fpr;
+	    
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		return NULL;
+	
+	g_return_val_if_fail (self->pv->pubkey && self->pv->pubkey->subkeys, NULL);
 
-    num_uids = seahorse_pgp_key_get_num_uids (pkey);
-    num_photoids = seahorse_pgp_key_get_num_photoids(pkey);
-    uids = num_uids + num_photoids;
+	raw = self->pv->pubkey->subkeys->fpr;
+	g_return_val_if_fail (raw != NULL, NULL);
 
-    ids = g_malloc0(uids + 1);
-    
-    photoid = pkey->photoids;
-    while (photoid != NULL){
-        ids[photoid->uid - 1] = 'x';
-        photoid = photoid->next;
-    }
-    
-    uid_count = 0;
-    
-    for(i = 0; i < uids; i++){
-        if (ids[i] == '\0'){
-            uid_count++;
-           
-            if (uid == uid_count)
-                break;
-        }
-    }
-    
-    g_free(ids);
-    return i + 1;
+	string = g_string_new ("");
+	len = strlen (raw);
+	    
+	for (index = 0; index < len; index++) {
+		if (index > 0 && index % 4 == 0)
+			g_string_append (string, " ");
+		g_string_append_c (string, raw[index]);
+	}
+	    
+	fpr = string->str;
+	g_string_free (string, FALSE);
+	    
+	return fpr;
 }
 
-void
-seahorse_pgp_key_get_signature_text (SeahorsePGPKey *pkey, gpgme_key_sig_t signature,
-                                     gchar **name, gchar **email, gchar **comment)
+SeahorseValidity
+seahorse_pgp_key_get_validity (SeahorsePgpKey *self)
 {
-    g_return_if_fail (signature != NULL);
-    
-    if (name)
-        *name = signature->name ? convert_string (signature->name, FALSE) : NULL;
-    if (email)
-        *email = signature->email ? convert_string (signature->email, FALSE) : NULL;
-    if (comment)
-        *comment = signature->comment ? convert_string (signature->comment, FALSE) : NULL;
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), SEAHORSE_VALIDITY_UNKNOWN);
+	if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		return SEAHORSE_VALIDITY_UNKNOWN;
+	
+	g_return_val_if_fail (self->pv->pubkey, SEAHORSE_VALIDITY_UNKNOWN);
+	g_return_val_if_fail (self->pv->uids, SEAHORSE_VALIDITY_UNKNOWN);
+
+	if (self->pv->pubkey->revoked)
+		return SEAHORSE_VALIDITY_REVOKED;
+	if (self->pv->pubkey->disabled)
+		return SEAHORSE_VALIDITY_DISABLED;
+	return seahorse_pgp_uid_get_validity (self->pv->uids->data);
 }
 
-guint         
-seahorse_pgp_key_get_sigtype (SeahorsePGPKey *pkey, gpgme_key_sig_t signature)
+const gchar*
+seahorse_pgp_key_get_validity_str (SeahorsePgpKey *self)
 {
-    SeahorseObject *sobj;
-    GQuark id;
-    
-    id = seahorse_pgp_key_get_cannonical_id (signature->keyid);
-    sobj = seahorse_context_find_object (SCTX_APP (), id, SEAHORSE_LOCATION_LOCAL);
-    
-    if (sobj) {
-        if (seahorse_object_get_usage (sobj) == SEAHORSE_USAGE_PRIVATE_KEY) 
-            return SKEY_PGPSIG_TRUSTED | SKEY_PGPSIG_PERSONAL;
-        if (seahorse_object_get_flags (sobj) & SEAHORSE_FLAG_TRUSTED)
-            return SKEY_PGPSIG_TRUSTED;
-    }
-
-    return 0;
+	SeahorseValidity validity = seahorse_pgp_key_get_validity (self);
+	return seahorse_validity_get_string (validity);
 }
 
-gboolean        
-seahorse_pgp_key_have_signatures (SeahorsePGPKey *pkey, guint types)
+gulong
+seahorse_pgp_key_get_expires (SeahorsePgpKey *self)
 {
-    gpgme_user_id_t uid;
-    gpgme_key_sig_t sig;
-    
-    for (uid = pkey->pubkey->uids; uid; uid = uid->next) {
-        for (sig = uid->signatures; sig; sig = sig->next) {
-            if (seahorse_pgp_key_get_sigtype (pkey, sig) & types)
-                return TRUE;
-        }
-    }
-    
-    return FALSE;
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), 0);
+	if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		return 0;
+	g_return_val_if_fail (self->pv->pubkey->subkeys, 0);
+	return self->pv->pubkey->subkeys->expires;
 }
 
-GQuark
-seahorse_pgp_key_get_cannonical_id (const gchar *id)
+gchar*
+seahorse_pgp_key_get_expires_str (SeahorsePgpKey *self)
 {
-    guint len = strlen (id);
-    GQuark keyid;
-    gchar *t;
-    
-    if (len < 16) {
-        g_warning ("invalid keyid (less than 16 chars): %s", id);
-        return 0;
-    }
-    
-    if (len > 16)
-        id += len - 16;
-    
-    t = g_strdup_printf ("%s:%s", SEAHORSE_PGP_STR, id);
-    keyid = g_quark_from_string (t);
-    g_free (t);
-    
-    return keyid;
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), SEAHORSE_VALIDITY_UNKNOWN);
+	if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		return g_strdup ("");
+	
+	if (self->pv->pubkey->expired) {
+		return g_strdup (_("Expired"));
+	} else {
+		g_return_val_if_fail (self->pv->pubkey->subkeys, NULL);
+		if (self->pv->pubkey->subkeys->expires == 0)
+			return g_strdup ("");
+		else 
+			return seahorse_util_get_date_string (self->pv->pubkey->subkeys->expires);
+	}
 }
 
-const gchar* 
-seahorse_pgp_key_get_rawid (GQuark keyid)
+SeahorseValidity
+seahorse_pgp_key_get_trust (SeahorsePgpKey *self)
 {
-	const gchar* id, *rawid;
-	
-	id = g_quark_to_string (keyid);
-	g_return_val_if_fail (id != NULL, NULL);
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), SEAHORSE_VALIDITY_UNKNOWN);
+	if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		return SEAHORSE_VALIDITY_UNKNOWN;
 	
-	rawid = strchr (id, ':');
-	return rawid ? rawid + 1 : id;
+	return gpgmex_validity_to_seahorse (self->pv->pubkey->owner_trust);
 }
 
-void
-seahorse_pgp_key_reload (SeahorsePGPKey *pkey)
+const gchar*
+seahorse_pgp_key_get_trust_str (SeahorsePgpKey *self)
 {
-	SeahorseSource *src;
-	
-	g_return_if_fail (SEAHORSE_IS_PGP_KEY (pkey));
-	src = seahorse_object_get_source (SEAHORSE_OBJECT (pkey));
-	g_return_if_fail (SEAHORSE_IS_PGP_SOURCE (src));
-	seahorse_source_load_async (src, seahorse_object_get_id (SEAHORSE_OBJECT (pkey)));
+	SeahorseValidity trust = seahorse_pgp_key_get_trust (self);
+	return seahorse_validity_get_string (trust);
 }
 
-gulong
-seahorse_pgp_key_get_expires (SeahorsePGPKey *self)
+guint
+seahorse_pgp_key_get_length (SeahorsePgpKey *self)
 {
-	gulong expires;
-	g_object_get (self, "expires", &expires, NULL);
-	return expires;
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), 0);
+	if (!require_key_public (self, GPGME_KEYLIST_MODE_LOCAL))
+		return 0;
+	
+	g_return_val_if_fail (self->pv->pubkey->subkeys, 0);
+	return self->pv->pubkey->subkeys->length;
 }
 
-gchar*
-seahorse_pgp_key_get_expires_str (SeahorsePGPKey *self)
+const gchar*
+seahorse_pgp_key_get_algo (SeahorsePgpKey *self)
 {
-	gchar *expires;
-	g_object_get (self, "expires-str", &expires, NULL);
-	return expires;
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	if (!require_key_subkeys (self))
+		return "";
+	g_return_val_if_fail (self->pv->subkeys, NULL);
+	return seahorse_pgp_subkey_get_algorithm (self->pv->subkeys->data);
 }
 
-gchar*
-seahorse_pgp_key_get_fingerprint (SeahorsePGPKey *self)
+const gchar*
+seahorse_pgp_key_get_keyid (SeahorsePgpKey *self)
 {
-	gchar *fpr;
-	g_object_get (self, "fingerprint", &fpr, NULL);
-	return fpr;	
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), NULL);
+	g_return_val_if_fail (self->pv->pubkey, NULL);
+	g_return_val_if_fail (self->pv->pubkey->subkeys, NULL);
+	g_return_val_if_fail (self->pv->pubkey->subkeys->keyid, NULL);
+	return self->pv->pubkey->subkeys->keyid;
+}
+
+gboolean
+seahorse_pgp_key_has_keyid (SeahorsePgpKey *self, const gchar *match)
+{
+	gpgme_subkey_t subkey;
+	const gchar *keyid;
+	guint n_match, n_keyid;
+	
+	g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (self), FALSE);
+	g_return_val_if_fail (match, FALSE);
+	g_return_val_if_fail (self->pv->pubkey, FALSE);
+	g_return_val_if_fail (self->pv->pubkey->subkeys, FALSE);
+	
+	n_match = strlen (match);
+	
+	for (subkey = self->pv->pubkey->subkeys; subkey; subkey = subkey->next) {
+		g_return_val_if_fail (subkey->keyid, FALSE);
+		keyid = subkey->keyid;
+		n_keyid = strlen (keyid);
+		if (n_match <= n_keyid) {
+			keyid += (n_keyid - n_match);
+			if (strncmp (keyid, match, n_match) == 0)
+				return TRUE;
+		}
+	}
+	
+	return FALSE;
 }
 
-SeahorseValidity
-seahorse_pgp_key_get_trust (SeahorsePGPKey *self)
+void
+seahorse_pgp_key_refresh_matching (gpgme_key_t key)
 {
-    guint validity;
-    g_object_get (self, "trust", &validity, NULL);
-    return validity;
+	SeahorseObjectPredicate pred;
+	
+	g_return_if_fail (key->subkeys->keyid);
+	
+	memset (&pred, 0, sizeof (pred));
+	pred.type = SEAHORSE_TYPE_PGP_KEY;
+	pred.id = seahorse_pgp_key_get_cannonical_id (key->subkeys->keyid);
+	
+	seahorse_context_for_objects_full (NULL, &pred, refresh_each_object, NULL);
 }

Modified: trunk/pgp/seahorse-pgp-key.h
==============================================================================
--- trunk/pgp/seahorse-pgp-key.h	(original)
+++ trunk/pgp/seahorse-pgp-key.h	Fri Dec 12 23:54:26 2008
@@ -22,7 +22,8 @@
 #ifndef __SEAHORSE_PGP_KEY_H__
 #define __SEAHORSE_PGP_KEY_H__
 
-#include <gtk/gtk.h>
+#include <glib-object.h>
+
 #include <gpgme.h>
 
 #include "seahorse-object.h"
@@ -37,106 +38,89 @@
     SKEY_PGPSIG_PERSONAL = 0x0002
 };
 
-typedef enum {
-    SKEY_INFO_NONE,     /* We have no information on this key */
-    SKEY_INFO_BASIC,    /* We have the usual basic quick info loaded */
-    SKEY_INFO_COMPLETE  /* All info */
-} SeahorseKeyInfo;
-
 #define SEAHORSE_TYPE_PGP_KEY            (seahorse_pgp_key_get_type ())
 
 /* For vala's sake */
-#define SEAHORSE_PGP_TYPE_KEY 		SEAHORSE_TYPE_PGP_KEY
+#define SEAHORSE_PGP_TYPE_KEY            SEAHORSE_TYPE_PGP_KEY
 
-#define SEAHORSE_PGP_KEY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_KEY, SeahorsePGPKey))
-#define SEAHORSE_PGP_KEY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PGP_KEY, SeahorsePGPKeyClass))
+#define SEAHORSE_PGP_KEY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_KEY, SeahorsePgpKey))
+#define SEAHORSE_PGP_KEY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PGP_KEY, SeahorsePgpKeyClass))
 #define SEAHORSE_IS_PGP_KEY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_PGP_KEY))
 #define SEAHORSE_IS_PGP_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PGP_KEY))
-#define SEAHORSE_PGP_KEY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PGP_KEY, SeahorsePGPKeyClass))
-
+#define SEAHORSE_PGP_KEY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PGP_KEY, SeahorsePgpKeyClass))
 
-typedef struct _SeahorsePGPKey SeahorsePGPKey;
-typedef struct _SeahorsePGPKeyClass SeahorsePGPKeyClass;
 
-struct _SeahorsePGPKey {
-    SeahorseObject              parent;
+typedef struct _SeahorsePgpKey SeahorsePgpKey;
+typedef struct _SeahorsePgpKeyClass SeahorsePgpKeyClass;
+typedef struct _SeahorsePgpKeyPrivate SeahorsePgpKeyPrivate;
 
-    /*< public >*/
-    gpgme_key_t                 pubkey;         /* The public key */
-    gpgme_key_t                 seckey;         /* The secret key */
-    gpgmex_photo_id_t           photoids;       /* List of photos */
-    GList                       *uids;		/* All the UID objects */
-    SeahorseKeyInfo		loaded;		/* What's loaded */
-    
+struct _SeahorsePgpKey {
+	SeahorseObject parent;
+	SeahorsePgpKeyPrivate *pv;
 };
 
-struct _SeahorsePGPKeyClass {
-    SeahorseObjectClass         parent_class;
+struct _SeahorsePgpKeyClass {
+	SeahorseObjectClass         parent_class;
 };
 
-SeahorsePGPKey* seahorse_pgp_key_new                  (SeahorseSource *sksrc,
-                                                       gpgme_key_t        pubkey,
-                                                       gpgme_key_t        seckey);
+SeahorsePgpKey*   seahorse_pgp_key_new                  (SeahorseSource *sksrc,
+                                                         gpgme_key_t pubkey,
+                                                         gpgme_key_t seckey);
+
+GType             seahorse_pgp_key_get_type             (void);
+
+gpgme_key_t       seahorse_pgp_key_get_public           (SeahorsePgpKey *self);
+
+void              seahorse_pgp_key_set_public           (SeahorsePgpKey *self,
+                                                         gpgme_key_t key);
+
+gpgme_key_t       seahorse_pgp_key_get_private          (SeahorsePgpKey *self);
+
+void              seahorse_pgp_key_set_private          (SeahorsePgpKey *self,
+                                                         gpgme_key_t key);
+
+GList*            seahorse_pgp_key_get_subkeys          (SeahorsePgpKey *self);
 
-void            seahorse_pgp_key_reload               (SeahorsePGPKey *pkey);
+void              seahorse_pgp_key_set_subkeys          (SeahorsePgpKey *self,
+                                                         GList *subkeys);
 
-GType           seahorse_pgp_key_get_type             (void);
+GList*            seahorse_pgp_key_get_uids             (SeahorsePgpKey *self);
 
-guint           seahorse_pgp_key_get_num_subkeys      (SeahorsePGPKey   *pkey);
+void              seahorse_pgp_key_set_uids             (SeahorsePgpKey *self,
+                                                         GList *subkeys);
 
-gpgme_subkey_t  seahorse_pgp_key_get_nth_subkey       (SeahorsePGPKey   *pkey,
-                                                       guint            index);
+GList*            seahorse_pgp_key_get_photos           (SeahorsePgpKey *self);
 
-guint           seahorse_pgp_key_get_num_uids         (SeahorsePGPKey *pkey);
+void              seahorse_pgp_key_set_photos           (SeahorsePgpKey *self,
+                                                         GList *subkeys);
 
-SeahorsePGPUid* seahorse_pgp_key_get_uid              (SeahorsePGPKey *pkey, 
-                                                       guint index);
+gchar*            seahorse_pgp_key_get_fingerprint      (SeahorsePgpKey *self);
 
-gulong          seahorse_pgp_key_get_expires          (SeahorsePGPKey *self);
+SeahorseValidity  seahorse_pgp_key_get_validity         (SeahorsePgpKey *self);
 
-gchar*          seahorse_pgp_key_get_expires_str      (SeahorsePGPKey *self);
+const gchar*      seahorse_pgp_key_get_validity_str     (SeahorsePgpKey *self);
 
-gchar*          seahorse_pgp_key_get_fingerprint      (SeahorsePGPKey *self);
+gulong            seahorse_pgp_key_get_expires          (SeahorsePgpKey *self);
 
-SeahorseValidity seahorse_pgp_key_get_trust           (SeahorsePGPKey *self);
+gchar*            seahorse_pgp_key_get_expires_str      (SeahorsePgpKey *self);
 
-const gchar*    seahorse_pgp_key_get_algo             (SeahorsePGPKey   *pkey,
-                                                       guint            index);
+SeahorseValidity  seahorse_pgp_key_get_trust            (SeahorsePgpKey *self);
 
-const gchar*    seahorse_pgp_key_get_id               (gpgme_key_t      key,
-                                                       guint            index);
+const gchar*      seahorse_pgp_key_get_trust_str        (SeahorsePgpKey *self);
 
-const gchar*    seahorse_pgp_key_get_rawid            (GQuark keyid);
+guint             seahorse_pgp_key_get_length           (SeahorsePgpKey *self);
 
-guint           seahorse_pgp_key_get_num_photoids     (SeahorsePGPKey   *pkey);
- 
-gpgmex_photo_id_t seahorse_pgp_key_get_nth_photoid    (SeahorsePGPKey   *pkey,
-                                                       guint            index);                                                    
+const gchar*      seahorse_pgp_key_get_algo             (SeahorsePgpKey *self);
 
-gpgmex_photo_id_t seahorse_pgp_key_get_photoid_n      (SeahorsePGPKey   *pkey,
-                                                       guint            uid);
+GQuark            seahorse_pgp_key_get_cannonical_id    (const gchar *id);
 
-void            seahorse_pgp_key_get_signature_text   (SeahorsePGPKey   *pkey,
-                                                       gpgme_key_sig_t  signature,
-                                                       gchar            **name,
-                                                       gchar            **email,
-                                                       gchar            **comment);
+const gchar*      seahorse_pgp_key_get_rawid            (GQuark keyid);
 
-guint           seahorse_pgp_key_get_sigtype          (SeahorsePGPKey   *pkey, 
-                                                       gpgme_key_sig_t  signature);
+const gchar*      seahorse_pgp_key_get_keyid            (SeahorsePgpKey *self);
 
-gboolean        seahorse_pgp_key_have_signatures      (SeahorsePGPKey   *pkey,
-                                                       guint            types);
+gboolean          seahorse_pgp_key_has_keyid            (SeahorsePgpKey *self, 
+                                                         const gchar *keyid);
 
-/* 
- * This function is necessary because the uid stored in a gpgme_user_id_t
- * struct is only usable with gpgme functions.  Problems will be caused if 
- * that uid is used with functions found in seahorse-pgp-key-op.h.  This 
- * function is only to be called with uids from gpgme_user_id_t structs.
- */
-guint           seahorse_pgp_key_get_actual_uid       (SeahorsePGPKey   *pkey,
-                                                       guint            uid);
-                                                       
-GQuark          seahorse_pgp_key_get_cannonical_id     (const gchar *id);
+void              seahorse_pgp_key_refresh_matching     (gpgme_key_t key);
 
 #endif /* __SEAHORSE_KEY_H__ */

Added: trunk/pgp/seahorse-pgp-photo.c
==============================================================================
--- (empty file)
+++ trunk/pgp/seahorse-pgp-photo.c	Fri Dec 12 23:54:26 2008
@@ -0,0 +1,206 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * 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-pgp.h"
+#include "seahorse-pgp-photo.h"
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+enum {
+	PROP_0,
+	PROP_PUBKEY,
+	PROP_PIXBUF,
+	PROP_INDEX
+};
+
+G_DEFINE_TYPE (SeahorsePgpPhoto, seahorse_pgp_photo, G_TYPE_OBJECT);
+
+struct _SeahorsePgpPhotoPrivate {
+	gpgme_key_t pubkey;        /* Key that this photo is on */
+	GdkPixbuf *pixbuf;         /* The public key that this photo is part of */
+	guint index;               /* The GPGME index of the photo */
+};
+
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
+static void
+seahorse_pgp_photo_init (SeahorsePgpPhoto *self)
+{
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_PGP_PHOTO, SeahorsePgpPhotoPrivate);
+	self->pv->index = 0;
+}
+
+static GObject*
+seahorse_pgp_photo_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+	GObject *obj = G_OBJECT_CLASS (seahorse_pgp_photo_parent_class)->constructor (type, n_props, props);
+	SeahorsePgpPhoto *self = NULL;
+	
+	if (obj) {
+		self = SEAHORSE_PGP_PHOTO (obj);
+		g_return_val_if_fail (self->pv->pubkey, NULL);
+	}
+	
+	return obj;
+}
+
+static void
+seahorse_pgp_photo_get_property (GObject *object, guint prop_id,
+                                  GValue *value, GParamSpec *pspec)
+{
+	SeahorsePgpPhoto *self = SEAHORSE_PGP_PHOTO (object);
+	
+	switch (prop_id) {
+	case PROP_PUBKEY:
+		g_value_set_boxed (value, seahorse_pgp_photo_get_pubkey (self));
+		break;
+	case PROP_PIXBUF:
+		g_value_set_object (value, seahorse_pgp_photo_get_pixbuf (self));
+		break;
+	case PROP_INDEX:
+		g_value_set_uint (value, seahorse_pgp_photo_get_index (self));
+		break;
+	}
+}
+
+static void
+seahorse_pgp_photo_set_property (GObject *object, guint prop_id, const GValue *value, 
+                                  GParamSpec *pspec)
+{
+	SeahorsePgpPhoto *self = SEAHORSE_PGP_PHOTO (object);
+
+	switch (prop_id) {
+	case PROP_PUBKEY:
+		g_return_if_fail (!self->pv->pubkey);
+		self->pv->pubkey = g_value_get_boxed (value);
+		if (self->pv->pubkey)
+			gpgmex_key_ref (self->pv->pubkey);
+		break;		
+	case PROP_PIXBUF:
+		seahorse_pgp_photo_set_pixbuf (self, g_value_get_object (value));
+		break;
+	case PROP_INDEX:
+		seahorse_pgp_photo_set_index (self, g_value_get_uint (value));
+		break;
+	}
+}
+
+static void
+seahorse_pgp_photo_finalize (GObject *gobject)
+{
+	SeahorsePgpPhoto *self = SEAHORSE_PGP_PHOTO (gobject);
+
+	if (self->pv->pixbuf)
+		g_object_unref (self->pv->pixbuf);
+	self->pv->pixbuf = NULL;
+    
+	G_OBJECT_CLASS (seahorse_pgp_photo_parent_class)->finalize (gobject);
+}
+
+static void
+seahorse_pgp_photo_class_init (SeahorsePgpPhotoClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);    
+
+	seahorse_pgp_photo_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePgpPhotoPrivate));
+    
+	gobject_class->constructor = seahorse_pgp_photo_constructor;
+	gobject_class->finalize = seahorse_pgp_photo_finalize;
+	gobject_class->set_property = seahorse_pgp_photo_set_property;
+	gobject_class->get_property = seahorse_pgp_photo_get_property;
+    
+	g_object_class_install_property (gobject_class, PROP_PUBKEY,
+	        g_param_spec_boxed ("pubkey", "Public Key", "GPGME Public Key that this subkey is on",
+	                            SEAHORSE_PGP_BOXED_KEY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (gobject_class, PROP_PIXBUF,
+	        g_param_spec_object ("pixbuf", "Pixbuf", "Photo Pixbuf",
+	                             GDK_TYPE_PIXBUF, G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_INDEX,
+	        g_param_spec_uint ("index", "Index", "Index of photo UID",
+	                           0, G_MAXUINT, 0, G_PARAM_READWRITE));
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC 
+ */
+
+SeahorsePgpPhoto* 
+seahorse_pgp_photo_new (gpgme_key_t pubkey, GdkPixbuf *pixbuf, guint index) 
+{
+	return g_object_new (SEAHORSE_TYPE_PGP_PHOTO,
+	                     "pubkey", pubkey,
+	                     "pixbuf", pixbuf, 
+	                     "index", index, NULL);
+}
+
+gpgme_key_t
+seahorse_pgp_photo_get_pubkey (SeahorsePgpPhoto *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_PHOTO (self), NULL);
+	g_return_val_if_fail (self->pv->pubkey, NULL);
+	return self->pv->pubkey;
+}
+
+GdkPixbuf*
+seahorse_pgp_photo_get_pixbuf (SeahorsePgpPhoto *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_PHOTO (self), NULL);
+	return self->pv->pixbuf;
+}
+
+void
+seahorse_pgp_photo_set_pixbuf (SeahorsePgpPhoto *self, GdkPixbuf* pixbuf)
+{
+	g_return_if_fail (SEAHORSE_IS_PGP_PHOTO (self));
+
+	if (self->pv->pixbuf)
+		g_object_unref (self->pv->pixbuf);
+	self->pv->pixbuf = pixbuf;
+	if (self->pv->pixbuf)
+		g_object_ref (self->pv->pixbuf);
+	
+	g_object_notify (G_OBJECT (self), "pixbuf");
+}
+
+guint
+seahorse_pgp_photo_get_index (SeahorsePgpPhoto *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_PHOTO (self), 0);
+	return self->pv->index;
+}
+
+void
+seahorse_pgp_photo_set_index (SeahorsePgpPhoto *self, guint index)
+{
+	g_return_if_fail (SEAHORSE_IS_PGP_PHOTO (self));
+
+	self->pv->index = index;
+	g_object_notify (G_OBJECT (self), "index");
+}

Added: trunk/pgp/seahorse-pgp-photo.h
==============================================================================
--- (empty file)
+++ trunk/pgp/seahorse-pgp-photo.h	Fri Dec 12 23:54:26 2008
@@ -0,0 +1,71 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * 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.
+ */
+
+#ifndef __SEAHORSE_PGP_PHOTO_H__
+#define __SEAHORSE_PGP_PHOTO_H__
+
+#include <glib-object.h>
+
+#include <gpgme.h>
+
+#include "pgp/seahorse-pgp-module.h"
+#include "pgp/seahorse-gpgmex.h"
+
+#define SEAHORSE_TYPE_PGP_PHOTO            (seahorse_pgp_photo_get_type ())
+
+#define SEAHORSE_PGP_PHOTO(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_PHOTO, SeahorsePgpPhoto))
+#define SEAHORSE_PGP_PHOTO_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PGP_PHOTO, SeahorsePgpPhotoClass))
+#define SEAHORSE_IS_PGP_PHOTO(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_PGP_PHOTO))
+#define SEAHORSE_IS_PGP_PHOTO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PGP_PHOTO))
+#define SEAHORSE_PGP_PHOTO_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PGP_PHOTO, SeahorsePgpPhotoClass))
+
+typedef struct _SeahorsePgpPhoto SeahorsePgpPhoto;
+typedef struct _SeahorsePgpPhotoClass SeahorsePgpPhotoClass;
+typedef struct _SeahorsePgpPhotoPrivate SeahorsePgpPhotoPrivate;
+
+struct _SeahorsePgpPhoto {
+	GObject parent;
+	SeahorsePgpPhotoPrivate *pv;
+};
+
+struct _SeahorsePgpPhotoClass {
+	GObjectClass parent_class;
+};
+
+GType               seahorse_pgp_photo_get_type          (void);
+
+SeahorsePgpPhoto*   seahorse_pgp_photo_new               (gpgme_key_t key,
+                                                          GdkPixbuf *pixbuf,
+                                                          guint index);
+
+gpgme_key_t         seahorse_pgp_photo_get_pubkey        (SeahorsePgpPhoto *self);
+
+GdkPixbuf*          seahorse_pgp_photo_get_pixbuf        (SeahorsePgpPhoto *self);
+
+void                seahorse_pgp_photo_set_pixbuf        (SeahorsePgpPhoto *self,
+                                                          GdkPixbuf *pixbuf);
+
+guint               seahorse_pgp_photo_get_index         (SeahorsePgpPhoto *self);
+
+void                seahorse_pgp_photo_set_index         (SeahorsePgpPhoto *self,
+                                                          guint index);
+
+#endif /* __SEAHORSE_PGP_PHOTO_H__ */

Modified: trunk/pgp/seahorse-pgp-photos.c
==============================================================================
--- trunk/pgp/seahorse-pgp-photos.c	(original)
+++ trunk/pgp/seahorse-pgp-photos.c	Fri Dec 12 23:54:26 2008
@@ -246,7 +246,7 @@
 
 
 gboolean
-seahorse_pgp_photo_add (SeahorsePGPKey *pkey, GtkWindow *parent, const gchar *path)
+seahorse_pgp_photo_add (SeahorsePgpKey *pkey, GtkWindow *parent, const gchar *path)
 {
     gchar *filename = NULL;
     gchar *tempfile = NULL;
@@ -281,7 +281,7 @@
         return FALSE;
     }
     
-    gerr = seahorse_pgp_key_op_photoid_add (pkey, tempfile ? tempfile : filename);
+    gerr = seahorse_pgp_key_op_photo_add (pkey, tempfile ? tempfile : filename);
     if (!GPG_IS_OK (gerr)) {
         
         /* A special error value set by seahorse_key_op_photoid_add to 
@@ -307,14 +307,13 @@
 }
 
 gboolean
-seahorse_pgp_photo_delete (SeahorsePGPKey *pkey, GtkWindow *parent, gpgmex_photo_id_t photo)
+seahorse_pgp_photo_delete (SeahorsePgpPhoto *photo, GtkWindow *parent)
 {
     gpgme_error_t gerr;
     GtkWidget *dlg;
     gint response; 
 
-    g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (pkey), FALSE);
-    g_return_val_if_fail (photo != NULL, FALSE);
+    g_return_val_if_fail (SEAHORSE_IS_PGP_PHOTO (photo), FALSE);
     
     dlg = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL,
                                   GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
@@ -329,7 +328,7 @@
     if (response != GTK_RESPONSE_ACCEPT)
         return FALSE;
     
-    gerr = seahorse_pgp_key_op_photoid_delete (pkey, photo->uid);
+    gerr = seahorse_pgp_key_op_photo_delete (photo);
     if (!GPG_IS_OK (gerr)) {
 	    seahorse_pgp_handle_gpgme_error (gerr, _("Couldn't delete photo"));
         return FALSE;

Modified: trunk/pgp/seahorse-pgp-revoke.c
==============================================================================
--- trunk/pgp/seahorse-pgp-revoke.c	(original)
+++ trunk/pgp/seahorse-pgp-revoke.c	Fri Dec 12 23:54:26 2008
@@ -42,9 +42,8 @@
 static void
 ok_clicked (GtkButton *button, SeahorseWidget *swidget)
 {
-	SeahorseObjectWidget *skwidget;
-	guint index;
 	SeahorseRevokeReason reason;
+	SeahorsePgpSubkey *subkey;
 	const gchar *description;
 	gpgme_error_t err;
 	GtkWidget *widget;
@@ -52,9 +51,6 @@
 	GtkTreeIter iter;
 	GValue value;
 	
-	skwidget = SEAHORSE_OBJECT_WIDGET (swidget);
-	index = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (skwidget), "index"));
-	
 	widget = glade_xml_get_widget (swidget->xml, "reason");
 	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
 	gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
@@ -65,95 +61,90 @@
 	g_value_unset (&value);
 	
 	description = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (swidget->xml, "description")));
+	subkey = g_object_get_data (G_OBJECT (swidget), "subkey");
+	g_return_if_fail (SEAHORSE_IS_PGP_SUBKEY (subkey));
 	
-	if (index != 0) {
-		err = seahorse_pgp_key_op_revoke_subkey (SEAHORSE_PGP_KEY (skwidget->object), 
-		                                         index, reason, description);
-		if (!GPG_IS_OK (err))
-			seahorse_pgp_handle_gpgme_error (err, _("Couldn't revoke subkey"));
-	}
+	err = seahorse_pgp_key_op_revoke_subkey (subkey, reason, description);
+	if (!GPG_IS_OK (err))
+		seahorse_pgp_handle_gpgme_error (err, _("Couldn't revoke subkey"));
 	seahorse_widget_destroy (swidget);
 }
 
 void
-seahorse_pgp_revoke_new (SeahorsePGPKey *pkey, GtkWindow *parent, guint index)
+seahorse_pgp_revoke_new (SeahorsePgpSubkey *subkey, GtkWindow *parent)
 {
 	SeahorseWidget *swidget;
 	gchar *title;
-	const gchar *userid;
+	gchar *label;
 	GtkWidget *widget;
 	GtkListStore *store;
 	GtkTreeIter iter;
 	GtkCellRenderer *renderer;
 	
-	g_return_if_fail (pkey != NULL && SEAHORSE_IS_PGP_KEY (pkey));
-	g_return_if_fail (index <= seahorse_pgp_key_get_num_subkeys (pkey));
+	g_return_if_fail (SEAHORSE_IS_PGP_SUBKEY (subkey));
 	
-	swidget = seahorse_object_widget_new ("revoke", parent, SEAHORSE_OBJECT (pkey));
+	swidget = seahorse_widget_new ("revoke", parent);
 	g_return_if_fail (swidget != NULL);
 	
 	glade_xml_signal_connect_data (swidget->xml, "ok_clicked",
 		G_CALLBACK (ok_clicked), swidget);
 	
-	userid = seahorse_object_get_label (SEAHORSE_OBJECT (pkey));
-	if (index)
-		title = g_strdup_printf (_("Revoke Subkey %d of %s"), index, userid);
-	else
-		title = g_strdup_printf (_("Revoke %s"), userid);
-   
-	g_object_set_data (G_OBJECT (swidget), "index", GUINT_TO_POINTER (index));
-	gtk_window_set_title (GTK_WINDOW (glade_xml_get_widget (swidget->xml,
-		              swidget->name)), title);
+	label = seahorse_pgp_subkey_get_description (subkey);
+	title = g_strdup_printf (_("Revoke: %s"), label);
+	gtk_window_set_title (GTK_WINDOW (glade_xml_get_widget (swidget->xml, swidget->name)), title);
+	g_free (title);
+	g_free (label);
+	
+	g_object_set_data (G_OBJECT (swidget), "subkey", subkey);
 
-    /* Initialize List Store for the Combo Box */
-    store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
+	/* Initialize List Store for the Combo Box */
+	store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
     
-    gtk_list_store_append (store, &iter);
-    gtk_list_store_set (store, &iter,
-                        COLUMN_TEXT, _("No reason"),
-                        COLUMN_TOOLTIP, _("No reason for revoking key"),
-                        COLUMN_INT, REVOKE_NO_REASON,
-                        -1);
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter,
+	                    COLUMN_TEXT, _("No reason"),
+	                    COLUMN_TOOLTIP, _("No reason for revoking key"),
+	                    COLUMN_INT, REVOKE_NO_REASON,
+	                    -1);
                         
-    gtk_list_store_append (store, &iter);
-    gtk_list_store_set (store, &iter,
-                        COLUMN_TEXT, _("Compromised"),
-                        COLUMN_TOOLTIP, _("Key has been compromised"),
-                        COLUMN_INT, REVOKE_COMPROMISED,
-                        -1);     
-                        gtk_list_store_append (store, &iter);
-
-    gtk_list_store_set (store, &iter,
-                        COLUMN_TEXT, _("Superseded"),
-                        COLUMN_TOOLTIP, _("Key has been superseded"),
-                        COLUMN_INT, REVOKE_SUPERSEDED,
-                        -1);
-
-    gtk_list_store_append (store, &iter);
-    gtk_list_store_set (store, &iter,
-                        COLUMN_TEXT, _("Not Used"),
-                        COLUMN_TOOLTIP, _("Key is no longer used"),
-                        COLUMN_INT, REVOKE_NOT_USED,
-                        -1);
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter,
+	                    COLUMN_TEXT, _("Compromised"),
+	                    COLUMN_TOOLTIP, _("Key has been compromised"),
+	                    COLUMN_INT, REVOKE_COMPROMISED,
+	                    -1);     
+	
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter,
+	                    COLUMN_TEXT, _("Superseded"),
+	                    COLUMN_TOOLTIP, _("Key has been superseded"),
+	                    COLUMN_INT, REVOKE_SUPERSEDED,
+	                    -1);
+
+	gtk_list_store_append (store, &iter);
+	gtk_list_store_set (store, &iter,
+	                    COLUMN_TEXT, _("Not Used"),
+	                    COLUMN_TOOLTIP, _("Key is no longer used"),
+	                    COLUMN_INT, REVOKE_NOT_USED,
+	                    -1);
                         
-    /* Finish Setting Up Combo Box */
-    
-    widget = glade_xml_get_widget (swidget->xml, "reason");
+	/* Finish Setting Up Combo Box */
+	widget = glade_xml_get_widget (swidget->xml, "reason");
     
-    gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
-    gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
+	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
     
-    renderer = gtk_cell_renderer_text_new ();
-    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE);
-    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer,
-                                    "text", COLUMN_TEXT,
-                                    NULL);
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE);
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer,
+	                                "text", COLUMN_TEXT,
+	                                NULL);
 }
 
 void
-seahorse_pgp_add_revoker_new (SeahorsePGPKey *pkey, GtkWindow *parent)
+seahorse_pgp_add_revoker_new (SeahorsePgpKey *pkey, GtkWindow *parent)
 {
-	SeahorsePGPKey *revoker;
+	SeahorsePgpKey *revoker;
 	GtkWidget *dialog;
 	gint response;
 	gpgme_error_t err;
@@ -169,10 +160,10 @@
 	userid2 = seahorse_object_get_label (SEAHORSE_OBJECT (pkey));
 
 	dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL,
-		GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
-		_("You are about to add %s as a revoker for %s."
-		" This operation cannot be undone! Are you sure you want to continue?"),
-		userid1, userid2);
+	                                 GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
+	                                 _("You are about to add %s as a revoker for %s."
+	                                   " This operation cannot be undone! Are you sure you want to continue?"),
+	                                   userid1, userid2);
     
 	response = gtk_dialog_run (GTK_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
@@ -180,7 +171,7 @@
 	if (response != GTK_RESPONSE_YES)
 		return;
 	
-	err = seahorse_pgp_key_pair_op_add_revoker (pkey, revoker);
+	err = seahorse_pgp_key_op_add_revoker (pkey, revoker);
 	if (!GPG_IS_OK (err))
 		seahorse_pgp_handle_gpgme_error (err, _("Couldn't add revoker"));
 }

Modified: trunk/pgp/seahorse-pgp-sign.c
==============================================================================
--- trunk/pgp/seahorse-pgp-sign.c	(original)
+++ trunk/pgp/seahorse-pgp-sign.c	Fri Dec 12 23:54:26 2008
@@ -38,18 +38,12 @@
 static gboolean
 ok_clicked (SeahorseWidget *swidget)
 {
-    SeahorseObjectWidget *skwidget;
     SeahorseSignCheck check;
     SeahorseSignOptions options = 0;
     SeahorseObject *signer;
     GtkWidget *w;
     gpgme_error_t err;
-    SeahorseObject *object;
-    GList *keys;
-    guint index;
-    
-    skwidget = SEAHORSE_OBJECT_WIDGET (swidget);
-    object = skwidget->object;
+    SeahorseObject *to_sign;
     
     /* Figure out choice */
     check = SIGN_CHECK_NO_ANSWER;
@@ -90,24 +84,19 @@
     g_assert (!signer || (SEAHORSE_IS_PGP_KEY (signer) && 
                           seahorse_object_get_usage (SEAHORSE_OBJECT (signer)) == SEAHORSE_USAGE_PRIVATE_KEY));
     
-    index = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (swidget), "index"));
-    err = seahorse_pgp_key_op_sign (SEAHORSE_PGP_KEY (object), 
-                                    SEAHORSE_PGP_KEY (signer), 
-                                    index + 1, check, options);
+    to_sign = g_object_get_data (G_OBJECT (swidget), "to-sign");
+    if (SEAHORSE_IS_PGP_UID (to_sign))
+	    err = seahorse_pgp_key_op_sign_uid (SEAHORSE_PGP_UID (to_sign), SEAHORSE_PGP_KEY (signer), check, options);
+    else if (SEAHORSE_IS_PGP_KEY (to_sign))
+	    err = seahorse_pgp_key_op_sign (SEAHORSE_PGP_KEY (to_sign), SEAHORSE_PGP_KEY (signer), check, options);
+    else
+	    g_assert (FALSE);
+    
     if (!GPG_IS_OK (err))
         seahorse_pgp_handle_gpgme_error (err, _("Couldn't sign key"));
     
     seahorse_widget_destroy (swidget);
     
-#ifdef WITH_KEYSERVER
-    if (GPG_IS_OK (err) && seahorse_gconf_get_boolean (AUTOSYNC_KEY)) {
-        keys = g_list_append (NULL, object);
-        /* TODO: This cross module dependency needs to be fixed */
-        /* seahorse_keyserver_sync (keys); */
-        g_list_free (keys);
-    }
-#endif
-    
     return TRUE;
 }
 
@@ -140,15 +129,14 @@
                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)));
 }
 
-void
-seahorse_pgp_sign_prompt (SeahorsePGPKey *pkey, guint index, GtkWindow *parent)
+static void
+sign_internal (SeahorseObject *to_sign, GtkWindow *parent)
 {
     SeahorseSet *skset;
     GtkWidget *w;
     gint response;
     SeahorseWidget *swidget;
     gboolean do_sign = TRUE;
-    SeahorsePGPUid *uid;
     gchar *userid;
 
     /* Some initial checks */
@@ -163,17 +151,16 @@
         return;
     }
 
-    swidget = seahorse_object_widget_new ("sign", parent, SEAHORSE_OBJECT (pkey));
+    swidget = seahorse_widget_new ("sign", parent);
     g_return_if_fail (swidget != NULL);
     
-    g_object_set_data (G_OBJECT (swidget), "index", GUINT_TO_POINTER (index));
+    g_object_set_data_full (G_OBJECT (swidget), "to-sign", g_object_ref (to_sign), g_object_unref);
 
     /* ... Except for when calling this, which is messed up */
     w = glade_xml_get_widget (swidget->xml, "sign-uid-text");
     g_return_if_fail (w != NULL);
-    uid = seahorse_pgp_key_get_uid (pkey, index);
-    g_return_if_fail (uid);
-    userid = g_markup_printf_escaped("<i>%s</i>", seahorse_object_get_label (SEAHORSE_OBJECT (uid)));
+
+    userid = g_markup_printf_escaped("<i>%s</i>", seahorse_object_get_label (to_sign));
     gtk_label_set_markup (GTK_LABEL (w), userid);
     g_free (userid);
     
@@ -236,3 +223,15 @@
         }
     }
 }
+
+void
+seahorse_pgp_sign_prompt (SeahorsePgpKey *to_sign, GtkWindow *parent)
+{
+	sign_internal (SEAHORSE_OBJECT (to_sign), parent);
+}
+
+void
+seahorse_pgp_sign_prompt_uid (SeahorsePgpUid *to_sign, GtkWindow *parent)
+{
+	sign_internal (SEAHORSE_OBJECT (to_sign), parent);
+}

Modified: trunk/pgp/seahorse-pgp-source.c
==============================================================================
--- trunk/pgp/seahorse-pgp-source.c	(original)
+++ trunk/pgp/seahorse-pgp-source.c	Fri Dec 12 23:54:26 2008
@@ -466,80 +466,75 @@
 }
 
 /* Add a key to the context  */
-static SeahorsePGPKey*
-add_key_to_context (SeahorsePGPSource *psrc, gpgme_key_t key, gpgmex_photo_id_t photos)
+static SeahorsePgpKey*
+add_key_to_context (SeahorsePGPSource *psrc, gpgme_key_t key)
 {
-    SeahorsePGPKey *pkey = NULL;
-    SeahorsePGPKey *prev;
-    const gchar *id;
-    GQuark keyid;
-    GList *l;
+	SeahorsePgpKey *pkey = NULL;
+	SeahorsePgpKey *prev;
+	const gchar *id;
+	gpgme_key_t seckey;
+	GQuark keyid;
+	GList *l;
     
-    id = seahorse_pgp_key_get_id (key, 0);
-    keyid = seahorse_pgp_key_get_cannonical_id (id);
-    g_return_val_if_fail (keyid, NULL);
+	g_return_val_if_fail (key->subkeys && key->subkeys->keyid, NULL);
     
-    g_assert (SEAHORSE_IS_PGP_SOURCE (psrc));
-    prev = SEAHORSE_PGP_KEY (seahorse_context_get_object (SCTX_APP (), SEAHORSE_SOURCE (psrc), keyid));
-    
-    /* Check if we can just replace the key on the object */
-    if (prev != NULL) {
-        if (key->secret) 
-            g_object_set (prev, "seckey", key, NULL);
-        else
-            g_object_set (prev, "pubkey", key, NULL);
-        
-        if (prev->photoids)
-            gpgmex_photo_id_free_all (prev->photoids);
-        prev->photoids = photos;
-        
-        return prev;
-    }
+	id = key->subkeys->keyid;
+	keyid = seahorse_pgp_key_get_cannonical_id (id);
+	g_return_val_if_fail (keyid, NULL);
+    
+	g_assert (SEAHORSE_IS_PGP_SOURCE (psrc));
+	prev = SEAHORSE_PGP_KEY (seahorse_context_get_object (SCTX_APP (), SEAHORSE_SOURCE (psrc), keyid));
+    
+	/* Check if we can just replace the key on the object */
+	if (prev != NULL) {
+		if (key->secret) 
+			g_object_set (prev, "seckey", key, NULL);
+		else
+			g_object_set (prev, "pubkey", key, NULL);
+		return prev;
+	}
     
-    /* Create a new key with secret */    
-    if (key->secret) {
-        pkey = seahorse_pgp_key_new (SEAHORSE_SOURCE (psrc), NULL, key);
+	/* Create a new key with secret */    
+	if (key->secret) {
+		pkey = seahorse_pgp_key_new (SEAHORSE_SOURCE (psrc), NULL, key);
         
-        /* Since we don't have a public key yet, save this away */
-        psrc->pv->orphan_secret = g_list_append (psrc->pv->orphan_secret, pkey);
+		/* Since we don't have a public key yet, save this away */
+		psrc->pv->orphan_secret = g_list_append (psrc->pv->orphan_secret, pkey);
         
-        if (photos)
-            gpgmex_photo_id_free_all (photos);
-        
-        /* No key was loaded as far as everyone is concerned */
-        return NULL;
-    }
+		/* No key was loaded as far as everyone is concerned */
+		return NULL;
+	}
  
-    /* Just a new public key */
+	/* Just a new public key */
 
-    /* Check for orphans */
-    for (l = psrc->pv->orphan_secret; l; l = g_list_next (l)) {
+	/* Check for orphans */
+	for (l = psrc->pv->orphan_secret; l; l = g_list_next (l)) {
         
-        /* Look for a matching key */
-        if (g_str_equal (id, seahorse_pgp_key_get_id (SEAHORSE_PGP_KEY(l->data)->seckey, 0))) {
+		seckey = seahorse_pgp_key_get_private (l->data);
+		g_return_val_if_fail (seckey && seckey->subkeys && seckey->subkeys->keyid, NULL);
+		g_assert (seckey);
+		
+		/* Look for a matching key */
+		if (g_str_equal (id, seckey->subkeys->keyid)) {
             
-            /* Set it up properly */
-            pkey = SEAHORSE_PGP_KEY (l->data);
-            g_object_set (pkey, "pubkey", key, NULL);
+			/* Set it up properly */
+			pkey = SEAHORSE_PGP_KEY (l->data);
+			g_object_set (pkey, "pubkey", key, NULL);
             
-            /* Remove item from orphan list cleanly */
-            psrc->pv->orphan_secret = g_list_remove_link (psrc->pv->orphan_secret, l);
-            g_list_free (l);
-            break;
-        }
-    }
+			/* Remove item from orphan list cleanly */
+			psrc->pv->orphan_secret = g_list_remove_link (psrc->pv->orphan_secret, l);
+			g_list_free (l);
+			break;
+		}
+	}
 
-    if (pkey == NULL)
-        pkey = seahorse_pgp_key_new (SEAHORSE_SOURCE (psrc), key, NULL);
+	if (pkey == NULL)
+		pkey = seahorse_pgp_key_new (SEAHORSE_SOURCE (psrc), key, NULL);
     
-    /* Add to context */ 
-    seahorse_context_take_object (SCTX_APP (), SEAHORSE_OBJECT (pkey));
+	/* Add to context */ 
+	seahorse_context_take_object (SCTX_APP (), SEAHORSE_OBJECT (pkey));
 
-    if (pkey->photoids)
-        gpgmex_photo_id_free_all (pkey->photoids);
-    pkey->photoids = photos;
-    
-    return pkey; 
+	return pkey; 
 }
 
 /* -----------------------------------------------------------------------------
@@ -672,11 +667,9 @@
 static gboolean
 keyload_handler (SeahorseLoadOperation *lop)
 {
-    SeahorsePGPKey *pkey;
-    gpgmex_photo_id_t photos;
+    SeahorsePgpKey *pkey;
     gpgme_key_t key;
     guint batch;
-    const gchar *id;
     GQuark keyid;
     gchar *t;
     
@@ -699,8 +692,8 @@
             return FALSE; /* Remove event handler */
         }
         
-        id = seahorse_pgp_key_get_id (key, 0);
-        keyid = seahorse_pgp_key_get_cannonical_id (id);
+        g_return_val_if_fail (key->subkeys && key->subkeys->keyid, FALSE);
+        keyid = seahorse_pgp_key_get_cannonical_id (key->subkeys->keyid);
         
         /* Invalid id from GPG ? */
         if (!keyid) {
@@ -716,13 +709,12 @@
 
         }
         
+        pkey = add_key_to_context (lop->psrc, key);
+
         /* Load additional info */
-        photos = NULL;
-        if (lop->parts & LOAD_PHOTOS)
-            seahorse_pgp_key_op_photoid_load (lop->psrc, key, &photos);
+        if (pkey && lop->parts & LOAD_PHOTOS)
+        	seahorse_pgp_key_op_photos_load (pkey);
 
-        pkey = add_key_to_context (lop->psrc, key, photos);
-        
         gpgmex_key_unref (key);
         lop->loaded++;
     }
@@ -959,7 +951,7 @@
 {
 	SeahorsePGPOperation *pop;
 	SeahorsePGPSource *psrc;
-	SeahorsePGPKey *pkey;
+	SeahorsePgpKey *pkey;
 	SeahorseObject *object;
 	ExportContext *ctx;
 	gpgme_data_t data;
@@ -1004,7 +996,7 @@
         	g_return_val_if_fail (seahorse_object_get_source (object) == sksrc, NULL);
         
         	/* Building list */
-        	keyid = seahorse_pgp_key_get_id (pkey->pubkey, 0);
+        	keyid = seahorse_pgp_key_get_keyid (pkey);
         	g_array_append_val (ctx->keyids, keyid);
         }
 
@@ -1017,7 +1009,6 @@
 static SeahorseOperation*          
 seahorse_pgp_source_remove (SeahorseSource *sksrc, SeahorseObject *sobj)
 {
-	SeahorseObject *parent;
 	GError *error = NULL;
 	gpgme_error_t gerr;
     
@@ -1026,13 +1017,10 @@
 	g_return_val_if_fail (seahorse_object_get_source (sobj) == sksrc, NULL);
 
 	if (SEAHORSE_IS_PGP_UID (sobj)) {
-		parent = seahorse_object_get_parent (sobj);
-		g_return_val_if_fail (SEAHORSE_IS_PGP_KEY (parent), NULL);
-		gerr = seahorse_pgp_key_op_del_uid (SEAHORSE_PGP_KEY (parent), 
-		                                    SEAHORSE_PGP_UID (sobj)->index + 1);
+		gerr = seahorse_pgp_key_op_del_uid (SEAHORSE_PGP_UID (sobj));
 	} else if (SEAHORSE_IS_PGP_KEY (sobj)) {
 		if (seahorse_object_get_usage (sobj) == SEAHORSE_USAGE_PRIVATE_KEY) 
-			gerr = seahorse_pgp_key_pair_op_delete (SEAHORSE_PGP_KEY (sobj));
+			gerr = seahorse_pgp_key_op_delete_pair (SEAHORSE_PGP_KEY (sobj));
 		else 
 			gerr = seahorse_pgp_key_op_delete (SEAHORSE_PGP_KEY (sobj));
 	} else {

Added: trunk/pgp/seahorse-pgp-subkey.c
==============================================================================
--- (empty file)
+++ trunk/pgp/seahorse-pgp-subkey.c	Fri Dec 12 23:54:26 2008
@@ -0,0 +1,300 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * 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-pgp.h"
+#include "seahorse-gpgmex.h"
+#include "seahorse-pgp-subkey.h"
+#include "seahorse-pgp-uid.h"
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+enum {
+	PROP_0,
+	PROP_PUBKEY,
+	PROP_SUBKEY,
+	PROP_INDEX,
+	PROP_KEYID,
+	PROP_ALGORITHM,
+	PROP_EXPIRES
+};
+
+G_DEFINE_TYPE (SeahorsePgpSubkey, seahorse_pgp_subkey, G_TYPE_OBJECT);
+
+struct _SeahorsePgpSubkeyPrivate {
+	gpgme_key_t pubkey;         /* The public key that this subkey is part of */
+	gpgme_subkey_t subkey;      /* The subkey referred to */
+	guint index;                /* The GPGME index of the subkey */
+};
+
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
+static void
+seahorse_pgp_subkey_init (SeahorsePgpSubkey *self)
+{
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_PGP_SUBKEY, SeahorsePgpSubkeyPrivate);
+	self->pv->index = 0;
+}
+
+static GObject*
+seahorse_pgp_subkey_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+	GObject *obj = G_OBJECT_CLASS (seahorse_pgp_subkey_parent_class)->constructor (type, n_props, props);
+	SeahorsePgpSubkey *self = NULL;
+	
+	if (obj) {
+		self = SEAHORSE_PGP_SUBKEY (obj);
+		g_return_val_if_fail (self->pv->pubkey, NULL);
+	}
+	
+	return obj;
+}
+
+static void
+seahorse_pgp_subkey_get_property (GObject *object, guint prop_id,
+                                  GValue *value, GParamSpec *pspec)
+{
+	SeahorsePgpSubkey *self = SEAHORSE_PGP_SUBKEY (object);
+	
+	switch (prop_id) {
+	case PROP_PUBKEY:
+		g_value_set_boxed (value, seahorse_pgp_subkey_get_pubkey (self));
+		break;
+	case PROP_SUBKEY:
+		g_value_set_pointer (value, seahorse_pgp_subkey_get_subkey (self));
+		break;
+	case PROP_INDEX:
+		g_value_set_uint (value, seahorse_pgp_subkey_get_index (self));
+		break;
+	case PROP_KEYID:
+		g_value_set_string (value, seahorse_pgp_subkey_get_keyid (self));
+		break;
+	case PROP_ALGORITHM:
+		g_value_set_string (value, seahorse_pgp_subkey_get_algorithm (self));
+		break;
+	case PROP_EXPIRES:
+		g_value_set_ulong (value, seahorse_pgp_subkey_get_expires (self));
+		break;
+	}
+}
+
+static void
+seahorse_pgp_subkey_set_property (GObject *object, guint prop_id, const GValue *value, 
+                                  GParamSpec *pspec)
+{
+	SeahorsePgpSubkey *self = SEAHORSE_PGP_SUBKEY (object);
+
+	switch (prop_id) {
+	case PROP_PUBKEY:
+		g_return_if_fail (!self->pv->pubkey);
+		self->pv->pubkey = g_value_get_boxed (value);
+		if (self->pv->pubkey)
+			gpgmex_key_ref (self->pv->pubkey);
+		break;
+	case PROP_SUBKEY:
+		seahorse_pgp_subkey_set_subkey (self, g_value_get_pointer (value));
+		break;
+	}
+}
+
+static void
+seahorse_pgp_subkey_finalize (GObject *gobject)
+{
+	SeahorsePgpSubkey *self = SEAHORSE_PGP_SUBKEY (gobject);
+
+	/* Unref the key */
+	if (self->pv->pubkey)
+		gpgmex_key_unref (self->pv->pubkey);
+	self->pv->pubkey = NULL;
+	self->pv->subkey = NULL;
+    
+	G_OBJECT_CLASS (seahorse_pgp_subkey_parent_class)->finalize (gobject);
+}
+
+static void
+seahorse_pgp_subkey_class_init (SeahorsePgpSubkeyClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);    
+
+	seahorse_pgp_subkey_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePgpSubkeyPrivate));
+
+	gobject_class->constructor = seahorse_pgp_subkey_constructor;
+	gobject_class->finalize = seahorse_pgp_subkey_finalize;
+	gobject_class->set_property = seahorse_pgp_subkey_set_property;
+	gobject_class->get_property = seahorse_pgp_subkey_get_property;
+    
+	g_object_class_install_property (gobject_class, PROP_PUBKEY,
+	        g_param_spec_boxed ("pubkey", "Public Key", "GPGME Public Key that this subkey is on",
+	                            SEAHORSE_PGP_BOXED_KEY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (gobject_class, PROP_SUBKEY,
+	        g_param_spec_pointer ("subkey", "Subkey", "GPGME Subkey",
+	                              G_PARAM_READWRITE));
+                      
+	g_object_class_install_property (gobject_class, PROP_INDEX,
+	        g_param_spec_uint ("index", "GPGME Index", "GPGME Subkey Index",
+	                           0, G_MAXUINT, 0, G_PARAM_READWRITE));
+	
+        g_object_class_install_property (gobject_class, PROP_KEYID,
+                g_param_spec_string ("keyid", "Key ID", "GPG Key ID",
+                                     "", G_PARAM_READABLE));
+        
+        g_object_class_install_property (gobject_class, PROP_ALGORITHM,
+                g_param_spec_string ("algorithm", "Algorithm", "GPG Algorithm",
+                                     "", G_PARAM_READABLE));
+        
+        g_object_class_install_property (gobject_class, PROP_EXPIRES,
+                g_param_spec_ulong ("expires", "Expires On", "Date this key expires on",
+                                    0, G_MAXULONG, 0, G_PARAM_READABLE));
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC 
+ */
+
+SeahorsePgpSubkey* 
+seahorse_pgp_subkey_new (gpgme_key_t pubkey, gpgme_subkey_t subkey) 
+{
+	return g_object_new (SEAHORSE_TYPE_PGP_SUBKEY, 
+	                     "pubkey", pubkey, 
+	                     "subkey", subkey, NULL);
+}
+
+
+gpgme_key_t
+seahorse_pgp_subkey_get_pubkey (SeahorsePgpSubkey *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), NULL);
+	g_return_val_if_fail (self->pv->pubkey, NULL);
+	return self->pv->pubkey;
+}
+
+gpgme_subkey_t
+seahorse_pgp_subkey_get_subkey (SeahorsePgpSubkey *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), NULL);
+	g_return_val_if_fail (self->pv->subkey, NULL);
+	return self->pv->subkey;
+}
+
+void
+seahorse_pgp_subkey_set_subkey (SeahorsePgpSubkey *self, gpgme_subkey_t subkey)
+{
+	GObject *obj;
+	gpgme_subkey_t sub;
+	gint i, index;
+	
+	g_return_if_fail (SEAHORSE_IS_PGP_SUBKEY (self));
+	g_return_if_fail (subkey);
+	
+	/* Make sure that this userid is in the pubkey */
+	index = -1;
+	for (i = 0, sub = self->pv->pubkey->subkeys; sub; ++i, sub = sub->next) {
+		if(sub == subkey) {
+			index = i;
+			break;
+		}
+	}
+	
+	g_return_if_fail (index >= 0);
+	
+	self->pv->subkey = subkey;
+	self->pv->index = index;
+	
+	obj = G_OBJECT (self);
+	g_object_freeze_notify (obj);
+	g_object_notify (obj, "subkey");
+	g_object_notify (obj, "index");
+	g_object_notify (obj, "keyid");
+	g_object_notify (obj, "algorithm");
+	g_object_notify (obj, "expires");
+	g_object_thaw_notify (obj);
+}
+
+guint
+seahorse_pgp_subkey_get_index (SeahorsePgpSubkey *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), 0);
+	return self->pv->index;
+}
+
+const gchar*
+seahorse_pgp_subkey_get_keyid (SeahorsePgpSubkey *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), NULL);
+	g_return_val_if_fail (self->pv->subkey, NULL);
+	return self->pv->subkey->keyid;
+}
+
+const gchar*
+seahorse_pgp_subkey_get_algorithm (SeahorsePgpSubkey *self)
+{
+	const gchar* algo_type;
+
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), NULL);
+	g_return_val_if_fail (self->pv->subkey, NULL);
+	
+	algo_type = gpgme_pubkey_algo_name (self->pv->subkey->pubkey_algo);
+
+	if (algo_type == NULL)
+		algo_type = _("Unknown");
+	else if (g_str_equal ("Elg", algo_type) || g_str_equal("ELG-E", algo_type))
+		algo_type = _("ElGamal");
+	
+	return algo_type;
+}
+
+gulong
+seahorse_pgp_subkey_get_expires (SeahorsePgpSubkey *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), 0);
+	g_return_val_if_fail (self->pv->subkey, 0);
+	return self->pv->subkey->expires;
+}
+
+gchar*
+seahorse_pgp_subkey_get_description (SeahorsePgpSubkey *self)
+{
+	gchar *label;
+	gchar *description;
+	
+	g_return_val_if_fail (SEAHORSE_IS_PGP_SUBKEY (self), NULL);
+	g_return_val_if_fail (self->pv->pubkey, NULL);
+	
+	if (self->pv->pubkey->uids)
+		label = seahorse_pgp_uid_calc_name (self->pv->pubkey->uids);
+	else
+		label = g_strdup (_("Key"));
+	
+	if (self->pv->index == 0)
+		return label;
+	
+	description = g_strdup_printf (_("Subkey %d of %s"), self->pv->index, label);
+	g_free (label);
+	
+	return description;
+}

Added: trunk/pgp/seahorse-pgp-subkey.h
==============================================================================
--- (empty file)
+++ trunk/pgp/seahorse-pgp-subkey.h	Fri Dec 12 23:54:26 2008
@@ -0,0 +1,75 @@
+/*
+ * Seahorse
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * 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.
+ */
+
+#ifndef __SEAHORSE_PGP_SUBKEY_H__
+#define __SEAHORSE_PGP_SUBKEY_H__
+
+#include <glib-object.h>
+
+#include <gpgme.h>
+
+#include "pgp/seahorse-pgp-module.h"
+#include "pgp/seahorse-gpgmex.h"
+
+#define SEAHORSE_TYPE_PGP_SUBKEY            (seahorse_pgp_subkey_get_type ())
+
+#define SEAHORSE_PGP_SUBKEY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_SUBKEY, SeahorsePgpSubkey))
+#define SEAHORSE_PGP_SUBKEY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PGP_SUBKEY, SeahorsePgpSubkeyClass))
+#define SEAHORSE_IS_PGP_SUBKEY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_PGP_SUBKEY))
+#define SEAHORSE_IS_PGP_SUBKEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PGP_SUBKEY))
+#define SEAHORSE_PGP_SUBKEY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PGP_SUBKEY, SeahorsePgpSubkeyClass))
+
+typedef struct _SeahorsePgpSubkey SeahorsePgpSubkey;
+typedef struct _SeahorsePgpSubkeyClass SeahorsePgpSubkeyClass;
+typedef struct _SeahorsePgpSubkeyPrivate SeahorsePgpSubkeyPrivate;
+
+struct _SeahorsePgpSubkey {
+	GObject parent;
+	SeahorsePgpSubkeyPrivate *pv;
+};
+
+struct _SeahorsePgpSubkeyClass {
+	GObjectClass parent_class;
+};
+
+GType               seahorse_pgp_subkey_get_type          (void);
+
+SeahorsePgpSubkey*  seahorse_pgp_subkey_new               (gpgme_key_t pubkey,
+                                                           gpgme_subkey_t subkey);
+
+gpgme_key_t         seahorse_pgp_subkey_get_pubkey        (SeahorsePgpSubkey *self);
+
+gpgme_subkey_t      seahorse_pgp_subkey_get_subkey        (SeahorsePgpSubkey *self);
+
+void                seahorse_pgp_subkey_set_subkey        (SeahorsePgpSubkey *self,
+                                                           gpgme_subkey_t subkey);
+
+guint               seahorse_pgp_subkey_get_index         (SeahorsePgpSubkey *self);
+
+const gchar*        seahorse_pgp_subkey_get_keyid         (SeahorsePgpSubkey *self);
+
+const gchar*        seahorse_pgp_subkey_get_algorithm     (SeahorsePgpSubkey *self);
+
+gulong              seahorse_pgp_subkey_get_expires       (SeahorsePgpSubkey *self);
+
+gchar*              seahorse_pgp_subkey_get_description   (SeahorsePgpSubkey *self);
+
+#endif /* __SEAHORSE_PGP_SUBKEY_H__ */

Modified: trunk/pgp/seahorse-pgp-uid.c
==============================================================================
--- trunk/pgp/seahorse-pgp-uid.c	(original)
+++ trunk/pgp/seahorse-pgp-uid.c	Fri Dec 12 23:54:26 2008
@@ -21,6 +21,7 @@
 
 #include "config.h"
 
+#include "seahorse-pgp.h"
 #include "seahorse-gpgmex.h"
 #include "seahorse-pgp-key.h"
 #include "seahorse-pgp-uid.h"
@@ -33,12 +34,23 @@
 	PROP_0,
 	PROP_PUBKEY,
 	PROP_USERID,
-	PROP_INDEX,
+	PROP_GPGME_INDEX,
+	PROP_ACTUAL_INDEX,
 	PROP_VALIDITY,
-	PROP_VALIDITY_STR
+	PROP_VALIDITY_STR,
+	PROP_NAME,
+	PROP_EMAIL,
+	PROP_COMMENT
 };
 
-G_DEFINE_TYPE (SeahorsePGPUid, seahorse_pgp_uid, SEAHORSE_TYPE_OBJECT);
+G_DEFINE_TYPE (SeahorsePgpUid, seahorse_pgp_uid, SEAHORSE_TYPE_OBJECT);
+
+struct _SeahorsePgpUidPrivate {
+	gpgme_key_t pubkey;         /* The public key that this uid is part of */
+	gpgme_user_id_t userid;     /* The userid referred to */
+	guint gpgme_index;          /* The GPGME index of the UID */
+	gint actual_index;          /* The actual index of this UID */
+};
 
 /* -----------------------------------------------------------------------------
  * INTERNAL HELPERS
@@ -71,17 +83,17 @@
 }
 
 static void
-changed_uid (SeahorsePGPUid *self)
+changed_uid (SeahorsePgpUid *self)
 {
 	SeahorseObject *obj = SEAHORSE_OBJECT (self);
 	SeahorseLocation loc;
-	GQuark id = 0;
 	gchar *name, *markup;
 	
-	if (!self->userid || !self->pubkey) {
+	g_return_if_fail (self->pv->pubkey);
+	
+	if (!self->pv->userid) {
         
 		g_object_set (self,
-		              "id", id,
 		              "label", "",
 		              "usage", SEAHORSE_USAGE_NONE,
 		              "markup", "",
@@ -92,24 +104,19 @@
 		
 	} 
 		
-	/* The key id */
-	if (self->pubkey->subkeys)
-		id = seahorse_pgp_key_get_cannonical_id (self->pubkey->subkeys->keyid);
-
 	/* The location */
 	loc = seahorse_object_get_location (obj);
-	if (self->pubkey->keylist_mode & GPGME_KEYLIST_MODE_EXTERN && 
+	if (self->pv->pubkey->keylist_mode & GPGME_KEYLIST_MODE_EXTERN && 
 	    loc <= SEAHORSE_LOCATION_REMOTE)
 		loc = SEAHORSE_LOCATION_REMOTE;
 
 	else if (loc <= SEAHORSE_LOCATION_LOCAL)
 		loc = SEAHORSE_LOCATION_LOCAL;
 
-	name = seahorse_pgp_uid_get_display_name (self);
-	markup = seahorse_pgp_uid_get_markup (self, 0);
+	name = seahorse_pgp_uid_calc_label (self->pv->userid);
+	markup = seahorse_pgp_uid_calc_markup (self->pv->userid, 0);
 	
 	g_object_set (self,
-		      "id", id,
 		      "label", name,
 		      "markup", markup,
 		      "usage", SEAHORSE_USAGE_IDENTITY,
@@ -125,34 +132,61 @@
  */
 
 static void
-seahorse_pgp_uid_init (SeahorsePGPUid *uid)
+seahorse_pgp_uid_init (SeahorsePgpUid *self)
+{
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_PGP_UID, SeahorsePgpUidPrivate);
+	self->pv->gpgme_index = 0;
+	self->pv->actual_index = -1;
+	g_object_set (self, "icon", "", NULL);
+}
+
+static GObject*
+seahorse_pgp_uid_constructor (GType type, guint n_props, GObjectConstructParam *props)
 {
-	g_object_set (uid, 
-	              "icon", "",
-	              NULL);
+	GObject *obj = G_OBJECT_CLASS (seahorse_pgp_uid_parent_class)->constructor (type, n_props, props);
+	SeahorsePgpUid *self = NULL;
+	
+	if (obj) {
+		self = SEAHORSE_PGP_UID (obj);
+		g_return_val_if_fail (self->pv->pubkey, NULL);
+	}
+	
+	return obj;
 }
 
 static void
 seahorse_pgp_uid_get_property (GObject *object, guint prop_id,
                                GValue *value, GParamSpec *pspec)
 {
-	SeahorsePGPUid *uid = SEAHORSE_PGP_UID (object);
+	SeahorsePgpUid *self = SEAHORSE_PGP_UID (object);
 	
 	switch (prop_id) {
 	case PROP_PUBKEY:
-		g_value_set_pointer (value, uid->pubkey);
+		g_value_set_boxed (value, seahorse_pgp_uid_get_pubkey (self));
 		break;
 	case PROP_USERID:
-		g_value_set_pointer (value, uid->userid);
+		g_value_set_pointer (value, seahorse_pgp_uid_get_userid (self));
+		break;
+	case PROP_GPGME_INDEX:
+		g_value_set_uint (value, seahorse_pgp_uid_get_gpgme_index (self));
 		break;
-	case PROP_INDEX:
-		g_value_set_uint (value, uid->index);
+	case PROP_ACTUAL_INDEX:
+		g_value_set_uint (value, seahorse_pgp_uid_get_actual_index (self));
 		break;
 	case PROP_VALIDITY:
-		g_value_set_uint (value, seahorse_pgp_uid_get_validity (uid));
+		g_value_set_uint (value, seahorse_pgp_uid_get_validity (self));
 		break;
 	case PROP_VALIDITY_STR:
-		g_value_set_string (value, seahorse_validity_get_string (seahorse_pgp_uid_get_validity (uid)));
+		g_value_set_string (value, seahorse_pgp_uid_get_validity_str (self));
+		break;
+	case PROP_NAME:
+		g_value_take_string (value, seahorse_pgp_uid_get_name (self));
+		break;
+	case PROP_EMAIL:
+		g_value_take_string (value, seahorse_pgp_uid_get_email (self));
+		break;
+	case PROP_COMMENT:
+		g_value_take_string (value, seahorse_pgp_uid_get_comment (self));
 		break;
 	}
 }
@@ -161,21 +195,20 @@
 seahorse_pgp_uid_set_property (GObject *object, guint prop_id, const GValue *value, 
                                GParamSpec *pspec)
 {
-	SeahorsePGPUid *uid = SEAHORSE_PGP_UID (object);
+	SeahorsePgpUid *self = SEAHORSE_PGP_UID (object);
 
 	switch (prop_id) {
 	case PROP_PUBKEY:
-		g_return_if_fail (!uid->pubkey);
-		uid->pubkey = g_value_get_pointer (value);
-		if (uid->pubkey)
-			gpgmex_key_ref (uid->pubkey);
+		g_return_if_fail (!self->pv->pubkey);
+		self->pv->pubkey = g_value_get_boxed (value);
+		if (self->pv->pubkey)
+			gpgmex_key_ref (self->pv->pubkey);
 		break;
-	case PROP_INDEX:
-		uid->index = g_value_get_uint (value);
+	case PROP_ACTUAL_INDEX:
+		seahorse_pgp_uid_set_actual_index (self, g_value_get_uint (value));
 		break;
 	case PROP_USERID:
-		uid->userid = g_value_get_pointer (value);
-		changed_uid (uid);
+		seahorse_pgp_uid_set_userid (self, g_value_get_pointer (value));
 		break;
 	}
 }
@@ -183,37 +216,44 @@
 static void
 seahorse_pgp_uid_object_finalize (GObject *gobject)
 {
-	SeahorsePGPUid *uid = SEAHORSE_PGP_UID (gobject);
+	SeahorsePgpUid *self = SEAHORSE_PGP_UID (gobject);
 
 	/* Unref the key */
-	if (uid->pubkey)
-		gpgmex_key_unref (uid->pubkey);
-	uid->pubkey = NULL;
-	uid->userid = NULL;
+	if (self->pv->pubkey)
+		gpgmex_key_unref (self->pv->pubkey);
+	self->pv->pubkey = NULL;
+	self->pv->userid = NULL;
     
 	G_OBJECT_CLASS (seahorse_pgp_uid_parent_class)->finalize (gobject);
 }
 
 static void
-seahorse_pgp_uid_class_init (SeahorsePGPUidClass *klass)
+seahorse_pgp_uid_class_init (SeahorsePgpUidClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);    
+
 	seahorse_pgp_uid_parent_class = g_type_class_peek_parent (klass);
-    
+	g_type_class_add_private (klass, sizeof (SeahorsePgpUidPrivate));
+
+	gobject_class->constructor = seahorse_pgp_uid_constructor;
 	gobject_class->finalize = seahorse_pgp_uid_object_finalize;
 	gobject_class->set_property = seahorse_pgp_uid_set_property;
 	gobject_class->get_property = seahorse_pgp_uid_get_property;
     
 	g_object_class_install_property (gobject_class, PROP_PUBKEY,
-	        g_param_spec_pointer ("pubkey", "Gpgme Public Key", "Gpgme Public Key that this uid is on",
-	                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	        g_param_spec_boxed ("pubkey", "Public Key", "GPGME Public Key that this uid is on",
+	                            SEAHORSE_PGP_BOXED_KEY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 	g_object_class_install_property (gobject_class, PROP_USERID,
-	        g_param_spec_pointer ("userid", "Gpgme User ID", "Gpgme User ID",
+	        g_param_spec_pointer ("userid", "User ID", "GPGME User ID",
 	                              G_PARAM_READWRITE));
                       
-	g_object_class_install_property (gobject_class, PROP_INDEX,
-	        g_param_spec_uint ("index", "Index", "Gpgme User ID Index",
+	g_object_class_install_property (gobject_class, PROP_GPGME_INDEX,
+	        g_param_spec_uint ("gpgme-index", "GPGME Index", "GPGME User ID Index",
+	                           0, G_MAXUINT, 0, G_PARAM_READWRITE));
+	
+	g_object_class_install_property (gobject_class, PROP_ACTUAL_INDEX,
+	        g_param_spec_uint ("actual-index", "Actual Index", "Actual GPG Index",
 	                           0, G_MAXUINT, 0, G_PARAM_READWRITE));
          
 	g_object_class_install_property (gobject_class, PROP_VALIDITY,
@@ -223,41 +263,176 @@
         g_object_class_install_property (gobject_class, PROP_VALIDITY_STR,
                 g_param_spec_string ("validity-str", "Validity String", "Validity of this identity as a string",
                                      "", G_PARAM_READABLE));
+        
+        g_object_class_install_property (gobject_class, PROP_NAME,
+                g_param_spec_string ("name", "Name", "User ID name",
+                                     "", G_PARAM_READABLE));
+
+        g_object_class_install_property (gobject_class, PROP_EMAIL,
+                g_param_spec_string ("email", "Email", "User ID email",
+                                     "", G_PARAM_READABLE));
+
+        g_object_class_install_property (gobject_class, PROP_COMMENT,
+                g_param_spec_string ("comment", "Comment", "User ID comment",
+                                     "", G_PARAM_READABLE));
 }
 
 /* -----------------------------------------------------------------------------
  * PUBLIC 
  */
 
-SeahorsePGPUid* 
+SeahorsePgpUid* 
 seahorse_pgp_uid_new (gpgme_key_t pubkey, gpgme_user_id_t userid) 
 {
-	return g_object_new (SEAHORSE_TYPE_PGP_UID, "pubkey", pubkey, "userid", userid, NULL);
+	return g_object_new (SEAHORSE_TYPE_PGP_UID, 
+	                     "pubkey", pubkey, 
+	                     "userid", userid, NULL);
+}
+
+
+gpgme_key_t
+seahorse_pgp_uid_get_pubkey (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), NULL);
+	g_return_val_if_fail (self->pv->pubkey, NULL);
+	return self->pv->pubkey;
+}
+
+gpgme_user_id_t
+seahorse_pgp_uid_get_userid (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), NULL);
+	g_return_val_if_fail (self->pv->userid, NULL);
+	return self->pv->userid;
+}
+
+void
+seahorse_pgp_uid_set_userid (SeahorsePgpUid *self, gpgme_user_id_t userid)
+{
+	GObject *obj;
+	gpgme_user_id_t uid;
+	gint index, i;
+	
+	g_return_if_fail (SEAHORSE_IS_PGP_UID (self));
+	g_return_if_fail (userid);
+	
+	/* Make sure that this userid is in the pubkey */
+	index = -1;
+	for (i = 0, uid = self->pv->pubkey->uids; uid; ++i, uid = uid->next) {
+		if(userid == uid) {
+			index = i;
+			break;
+		}
+	}
+	
+	g_return_if_fail (index >= 0);
+	
+	self->pv->userid = userid;
+	self->pv->gpgme_index = index;
+	
+	obj = G_OBJECT (self);
+	g_object_freeze_notify (obj);
+	changed_uid (self);
+	g_object_notify (obj, "userid");
+	g_object_notify (obj, "gpgme_index");
+	g_object_notify (obj, "name");
+	g_object_notify (obj, "email");
+	g_object_notify (obj, "comment");
+	g_object_notify (obj, "validity");
+	g_object_notify (obj, "validity-str");
+	g_object_thaw_notify (obj);
+}
+
+guint
+seahorse_pgp_uid_get_gpgme_index (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), 0);
+	return self->pv->gpgme_index;
+}
+
+guint
+seahorse_pgp_uid_get_actual_index (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), 0);
+	if(self->pv->actual_index < 0)
+		return self->pv->gpgme_index;
+	return self->pv->actual_index;
+}
+
+void
+seahorse_pgp_uid_set_actual_index (SeahorsePgpUid *self, guint actual_index)
+{
+	g_return_if_fail (SEAHORSE_IS_PGP_UID (self));
+	self->pv->actual_index = actual_index;
+	g_object_notify (G_OBJECT (self), "actual-index");
+}
+
+SeahorseValidity
+seahorse_pgp_uid_get_validity (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), SEAHORSE_VALIDITY_UNKNOWN);
+	g_return_val_if_fail (self->pv->userid, SEAHORSE_VALIDITY_UNKNOWN);
+	return gpgmex_validity_to_seahorse (self->pv->userid->validity);
+}
+
+const gchar*
+seahorse_pgp_uid_get_validity_str (SeahorsePgpUid *self)
+{
+	return seahorse_validity_get_string (seahorse_pgp_uid_get_validity (self));
+}
+
+gchar*
+seahorse_pgp_uid_get_name (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), NULL);
+	g_return_val_if_fail (self->pv->userid, NULL);
+	return convert_string (self->pv->userid->name, FALSE);
+}
+
+gchar*
+seahorse_pgp_uid_get_email (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), NULL);
+	g_return_val_if_fail (self->pv->userid, NULL);
+	return convert_string (self->pv->userid->email, FALSE);
+}
+
+gchar*
+seahorse_pgp_uid_get_comment (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), NULL);
+	g_return_val_if_fail (self->pv->userid, NULL);
+	return convert_string (self->pv->userid->comment, FALSE);
+}
+
+gchar*
+seahorse_pgp_uid_calc_label (gpgme_user_id_t userid)
+{
+	g_return_val_if_fail (userid, NULL);
+	return convert_string (userid->uid, FALSE);
 }
 
 gchar*
-seahorse_pgp_uid_get_display_name (SeahorsePGPUid *uid)
+seahorse_pgp_uid_calc_name (gpgme_user_id_t userid)
 {
-	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), NULL);
-	g_return_val_if_fail (uid->userid, NULL);
-	return convert_string (uid->userid->uid, FALSE);
+	g_return_val_if_fail (userid, NULL);
+	return convert_string (userid->name, FALSE);
 }
 
 gchar*
-seahorse_pgp_uid_get_markup (SeahorsePGPUid *uid, guint flags)
+seahorse_pgp_uid_calc_markup (gpgme_user_id_t userid, guint flags)
 {
 	gchar *email, *name, *comment, *ret;
 	const gchar *format;
 	gboolean strike = FALSE;
 
-	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), NULL);
-	g_return_val_if_fail (uid->userid, NULL);
+	g_return_val_if_fail (userid, NULL);
 	
-	name = convert_string (uid->userid->name, TRUE);
-	email = convert_string (uid->userid->email, TRUE);
-	comment = convert_string (uid->userid->comment, TRUE);
+	name = convert_string (userid->name, TRUE);
+	email = convert_string (userid->email, TRUE);
+	comment = convert_string (userid->comment, TRUE);
 
-	if (uid->userid->revoked || flags & CRYPTUI_FLAG_EXPIRED || 
+	if (userid->revoked || flags & CRYPTUI_FLAG_EXPIRED || 
 	    flags & CRYPTUI_FLAG_REVOKED || flags & CRYPTUI_FLAG_DISABLED)
 		strike = TRUE;
 	    
@@ -280,42 +455,37 @@
 	return ret;
 }
 
-gchar*
-seahorse_pgp_uid_get_name (SeahorsePGPUid *uid)
-{
-	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), NULL);
-	g_return_val_if_fail (uid->userid, NULL);
-	return convert_string (uid->userid->name, FALSE);
-}
-
-
-gchar*
-seahorse_pgp_uid_get_email (SeahorsePGPUid *uid)
+void
+seahorse_pgp_uid_signature_get_text (gpgme_key_sig_t signature,
+                                     gchar **name, gchar **email, gchar **comment)
 {
-	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), NULL);
-	g_return_val_if_fail (uid->userid, NULL);
-	return convert_string (uid->userid->email, FALSE);
+	g_return_if_fail (signature != NULL);
+    
+	if (name)
+		*name = signature->name ? convert_string (signature->name, FALSE) : NULL;
+	if (email)
+		*email = signature->email ? convert_string (signature->email, FALSE) : NULL;
+	if (comment)
+		*comment = signature->comment ? convert_string (signature->comment, FALSE) : NULL;
 }
 
-gchar*
-seahorse_pgp_uid_get_comment (SeahorsePGPUid *uid)
+guint         
+seahorse_pgp_uid_signature_get_type (gpgme_key_sig_t signature)
 {
-	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), NULL);
-	g_return_val_if_fail (uid->userid, NULL);
-	return convert_string (uid->userid->comment, FALSE);
-}
+	SeahorseObject *sobj;
+	GQuark id;
 
-SeahorseValidity
-seahorse_pgp_uid_get_validity (SeahorsePGPUid *uid)
-{
-	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), SEAHORSE_VALIDITY_UNKNOWN);
-	g_return_val_if_fail (uid->userid, SEAHORSE_VALIDITY_UNKNOWN);
-	return gpgmex_validity_to_seahorse (uid->userid->validity);
-}
+	g_return_val_if_fail (signature != NULL, 0);
+    
+	id = seahorse_pgp_key_get_cannonical_id (signature->keyid);
+	sobj = seahorse_context_find_object (SCTX_APP (), id, SEAHORSE_LOCATION_LOCAL);
+    
+	if (sobj) {
+		if (seahorse_object_get_usage (sobj) == SEAHORSE_USAGE_PRIVATE_KEY) 
+			return SKEY_PGPSIG_TRUSTED | SKEY_PGPSIG_PERSONAL;
+		if (seahorse_object_get_flags (sobj) & SEAHORSE_FLAG_TRUSTED)
+			return SKEY_PGPSIG_TRUSTED;
+	}
 
-guint
-seahorse_pgp_uid_get_index (SeahorsePGPUid *uid)
-{
-	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (uid), 0);
-	return uid->index;
+	return 0;
 }

Modified: trunk/pgp/seahorse-pgp-uid.h
==============================================================================
--- trunk/pgp/seahorse-pgp-uid.h	(original)
+++ trunk/pgp/seahorse-pgp-uid.h	Fri Dec 12 23:54:26 2008
@@ -35,50 +35,69 @@
 /* For vala's sake */
 #define SEAHORSE_PGP_TYPE_UID 		SEAHORSE_TYPE_PGP_UID
 
-#define SEAHORSE_PGP_UID(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_UID, SeahorsePGPUid))
-#define SEAHORSE_PGP_UID_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PGP_UID, SeahorsePGPUidClass))
+#define SEAHORSE_PGP_UID(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_UID, SeahorsePgpUid))
+#define SEAHORSE_PGP_UID_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_PGP_UID, SeahorsePgpUidClass))
 #define SEAHORSE_IS_PGP_UID(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_PGP_UID))
 #define SEAHORSE_IS_PGP_UID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_PGP_UID))
-#define SEAHORSE_PGP_UID_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PGP_UID, SeahorsePGPUidClass))
+#define SEAHORSE_PGP_UID_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_PGP_UID, SeahorsePgpUidClass))
 
+typedef struct _SeahorsePgpUid SeahorsePgpUid;
+typedef struct _SeahorsePgpUidClass SeahorsePgpUidClass;
+typedef struct _SeahorsePgpUidPrivate SeahorsePgpUidPrivate;
 
-typedef struct _SeahorsePGPUid SeahorsePGPUid;
-typedef struct _SeahorsePGPUidClass SeahorsePGPUidClass;
-
-struct _SeahorsePGPUid {
+struct _SeahorsePgpUid {
 	SeahorseObject parent;
-
-	/*< public >*/
-	gpgme_key_t pubkey;         /* The public key that this uid is part of */
-	gpgme_user_id_t userid;     /* The userid referred to */
-	guint index;                /* The index of the UID */
+	SeahorsePgpUidPrivate *pv;
 };
 
-struct _SeahorsePGPUidClass {
+struct _SeahorsePgpUidClass {
 	SeahorseObjectClass parent_class;
 };
 
-SeahorsePGPUid*   seahorse_pgp_uid_new                  (gpgme_key_t pubkey,
+GType             seahorse_pgp_uid_get_type             (void);
+
+SeahorsePgpUid*   seahorse_pgp_uid_new                  (gpgme_key_t pubkey,
                                                          gpgme_user_id_t userid);
 
-GType             seahorse_pgp_uid_get_type             (void);
+gpgme_key_t       seahorse_pgp_uid_get_pubkey           (SeahorsePgpUid *self);
 
-gboolean          seahorse_pgp_uid_equal                (SeahorsePGPUid *uid,
+gpgme_user_id_t   seahorse_pgp_uid_get_userid           (SeahorsePgpUid *self);
+
+void              seahorse_pgp_uid_set_userid           (SeahorsePgpUid *self,
                                                          gpgme_user_id_t userid);
 
-gchar*            seahorse_pgp_uid_get_display_name     (SeahorsePGPUid *uid);
+guint             seahorse_pgp_uid_get_gpgme_index      (SeahorsePgpUid *self);
 
-gchar*            seahorse_pgp_uid_get_markup           (SeahorsePGPUid *uid, 
-                                                         guint flags);
+guint             seahorse_pgp_uid_get_actual_index     (SeahorsePgpUid *self);
+
+void              seahorse_pgp_uid_set_actual_index     (SeahorsePgpUid *self,
+                                                         guint actual_index);
+
+SeahorseValidity  seahorse_pgp_uid_get_validity         (SeahorsePgpUid *self);
 
-gchar*            seahorse_pgp_uid_get_name             (SeahorsePGPUid *uid);
+const gchar*      seahorse_pgp_uid_get_validity_str     (SeahorsePgpUid *self);
+
+
+gchar*            seahorse_pgp_uid_get_name             (SeahorsePgpUid *self);
+
+gchar*            seahorse_pgp_uid_get_email            (SeahorsePgpUid *self);
+
+gchar*            seahorse_pgp_uid_get_comment          (SeahorsePgpUid *self);
+
+gchar*            seahorse_pgp_uid_calc_name            (gpgme_user_id_t userid);
+
+gchar*            seahorse_pgp_uid_calc_label           (gpgme_user_id_t userid);
+
+gchar*            seahorse_pgp_uid_calc_markup          (gpgme_user_id_t userid,
+                                                         guint flags);
 
-gchar*            seahorse_pgp_uid_get_email            (SeahorsePGPUid *uid);
+guint             seahorse_pgp_uid_signature_get_type   (gpgme_key_sig_t  signature);
 
-gchar*            seahorse_pgp_uid_get_comment          (SeahorsePGPUid *uid);
-                                  
-SeahorseValidity  seahorse_pgp_uid_get_validity         (SeahorsePGPUid *uid);
+void              seahorse_pgp_uid_signature_get_text   (gpgme_key_sig_t  signature,
+                                                         gchar            **name,
+                                                         gchar            **email,
+                                                         gchar            **comment);
 
-guint             seahorse_pgp_uid_get_index            (SeahorsePGPUid *uid);
+GQuark            seahorse_pgp_uid_get_cannonical_id    (const gchar *id);
 
 #endif /* __SEAHORSE_PGP_UID_H__ */

Modified: trunk/pgp/seahorse-pgp.c
==============================================================================
--- trunk/pgp/seahorse-pgp.c	(original)
+++ trunk/pgp/seahorse-pgp.c	Fri Dec 12 23:54:26 2008
@@ -20,14 +20,15 @@
  */
 
 #include "seahorse-pgp.h"
-#include <stdlib.h>
-#include <string.h>
-
-
-
-
-
-
-
-
+#include "seahorse-gpgmex.h"
 
+GType
+seahorse_pgp_boxed_key_type (void)
+{
+	static GType type = 0;
+	if (!type)
+		type = g_boxed_type_register_static ("gpgme_key_t", 
+		                                     (GBoxedCopyFunc)gpgmex_key_ref,
+		                                     (GBoxedFreeFunc)gpgmex_key_unref);
+	return type;
+}

Modified: trunk/pgp/seahorse-pgp.h
==============================================================================
--- trunk/pgp/seahorse-pgp.h	(original)
+++ trunk/pgp/seahorse-pgp.h	Fri Dec 12 23:54:26 2008
@@ -33,6 +33,9 @@
 #define SEAHORSE_PGP_TYPE g_quark_from_string ("openpgp")
 #define SEAHORSE_PGP_STOCK_ICON "seahorse-key-personal"
 
+#define     SEAHORSE_PGP_BOXED_KEY               (seahorse_pgp_boxed_key_type ())
+
+GType       seahorse_pgp_boxed_key_type          (void);
 
 G_END_DECLS
 

Modified: trunk/pgp/seahorse-server-source.c
==============================================================================
--- trunk/pgp/seahorse-server-source.c	(original)
+++ trunk/pgp/seahorse-server-source.c	Fri Dec 12 23:54:26 2008
@@ -273,18 +273,19 @@
 seahorse_server_source_add_key (SeahorseServerSource *ssrc, gpgme_key_t key)
 {
     SeahorseObject *prev;
-    SeahorsePGPKey *pkey;
+    SeahorsePgpKey *pkey;
     GQuark keyid;
        
     g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (ssrc));
+    g_return_if_fail (key && key->subkeys && key->subkeys->keyid);
 
-    keyid = seahorse_pgp_key_get_cannonical_id (seahorse_pgp_key_get_id (key, 0));
+    keyid = seahorse_pgp_key_get_cannonical_id (key->subkeys->keyid);
     prev = seahorse_context_get_object (SCTX_APP (), SEAHORSE_SOURCE (ssrc), keyid);
     
     /* TODO: This function needs reworking after we get more key types */
     if (prev != NULL) {
         g_return_if_fail (SEAHORSE_IS_PGP_KEY (prev));
-        combine_keys (ssrc, SEAHORSE_PGP_KEY (prev)->pubkey, key);
+        combine_keys (ssrc, seahorse_pgp_key_get_public (SEAHORSE_PGP_KEY (prev)), key);
         return;
     }
 

Modified: trunk/pgp/seahorse-signer.c
==============================================================================
--- trunk/pgp/seahorse-signer.c	(original)
+++ trunk/pgp/seahorse-signer.c	Fri Dec 12 23:54:26 2008
@@ -37,7 +37,7 @@
 #include "pgp/seahorse-pgp-key.h"
 #include "pgp/seahorse-pgp-keysets.h"
 
-SeahorsePGPKey*
+SeahorsePgpKey*
 seahorse_signer_get (GtkWindow *parent)
 {
     SeahorseWidget *swidget;

Modified: trunk/pgp/vala-build.stamp
==============================================================================
--- trunk/pgp/vala-build.stamp	(original)
+++ trunk/pgp/vala-build.stamp	Fri Dec 12 23:54:26 2008
@@ -1 +1 @@
-1228006945
+1229107544

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Fri Dec 12 23:54:26 2008
@@ -67,6 +67,7 @@
 pgp/seahorse-pgp-revoke.c
 pgp/seahorse-pgp-sign.c
 pgp/seahorse-pgp-source.c
+pgp/seahorse-pgp-subkey.c
 pgp/seahorse-revoke.glade
 pgp/seahorse-server-source.c
 pgp/seahorse-sign.glade

Modified: trunk/po/POTFILES.skip
==============================================================================
--- trunk/po/POTFILES.skip	(original)
+++ trunk/po/POTFILES.skip	Fri Dec 12 23:54:26 2008
@@ -1,3 +1,4 @@
+daemon/seahorse-daemon.desktop.in
 libcryptui/crui-x509-cert-basics.ui
 pkcs11/seahorse-pkcs11-source.c
 pgp/seahorse-pgp-commands.c

Modified: trunk/src/seahorse-key-manager-store.c
==============================================================================
--- trunk/src/seahorse-key-manager-store.c	(original)
+++ trunk/src/seahorse-key-manager-store.c	Fri Dec 12 23:54:26 2008
@@ -58,7 +58,7 @@
     N_COLS
 };
 
-static const SeahorseSetModelColumn column_info[] = {
+static SeahorseSetModelColumn column_info[] = {
 	{ "usage", G_TYPE_UINT, "usage" },
 	{ "icon", G_TYPE_STRING, NULL },
 	{ "markup", G_TYPE_STRING, "label" },



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