[seahorse/refactor: 3/33] Implement GcrCollection on PGP Keys and GKR keyrings



commit 4620961603272e32efccacd91bad30e3cea1a477
Author: Stef Walter <stefw collabora co uk>
Date:   Mon Sep 5 15:26:41 2011 +0200

    Implement GcrCollection on PGP Keys and GKR keyrings
    
     * This way they show up properly as folders with tehir nested
       contents inside.
     * Fine tune some bits about how PGP keys are displayed.

 gkr/seahorse-gkr-item.c           |   24 +++++-
 gkr/seahorse-gkr-item.h           |    3 +-
 gkr/seahorse-gkr-keyring.c        |  114 +++++++++++++++++---------
 gkr/seahorse-gkr-keyring.h        |    5 +-
 gkr/seahorse-gkr-operation.c      |    3 +-
 libseahorse/seahorse-collection.c |    7 --
 libseahorse/seahorse-object.c     |  160 +------------------------------------
 libseahorse/seahorse-object.h     |    7 --
 pgp/seahorse-gpgme-key.c          |    2 +-
 pgp/seahorse-gpgme-uid.c          |   24 +++---
 pgp/seahorse-gpgme-uid.h          |    3 +-
 pgp/seahorse-hkp-source.c         |    4 +-
 pgp/seahorse-ldap-source.c        |    5 +-
 pgp/seahorse-pgp-commands.c       |   11 +--
 pgp/seahorse-pgp-key.c            |   68 ++++++++++++----
 pgp/seahorse-pgp-uid.c            |   42 ++++++++--
 pgp/seahorse-pgp-uid.h            |    7 ++-
 17 files changed, 225 insertions(+), 264 deletions(-)
---
diff --git a/gkr/seahorse-gkr-item.c b/gkr/seahorse-gkr-item.c
index 8dc61a9..a5604b8 100644
--- a/gkr/seahorse-gkr-item.c
+++ b/gkr/seahorse-gkr-item.c
@@ -34,6 +34,7 @@
 
 #include "seahorse-gkr.h"
 #include "seahorse-gkr-item.h"
+#include "seahorse-gkr-keyring.h"
 #include "seahorse-gkr-operation.h"
 
 /* For gnome-keyring secret type ids */
@@ -552,6 +553,20 @@ seahorse_gkr_item_set_property (GObject *object, guint prop_id, const GValue *va
 }
 
 static void
+seahorse_gkr_item_dispose (GObject *obj)
+{
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (obj);
+	SeahorseSource *source;
+
+	source = seahorse_object_get_source (SEAHORSE_OBJECT (self));
+	if (source != NULL)
+		seahorse_gkr_keyring_remove_item (SEAHORSE_GKR_KEYRING (source),
+		                                  self->pv->item_id);
+
+	G_OBJECT_CLASS (seahorse_gkr_item_parent_class)->dispose (obj);
+}
+
+static void
 seahorse_gkr_item_finalize (GObject *gobject)
 {
 	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (gobject);
@@ -585,6 +600,7 @@ seahorse_gkr_item_class_init (SeahorseGkrItemClass *klass)
 	gobject_class = G_OBJECT_CLASS (klass);
 	
 	gobject_class->constructed = seahorse_gkr_item_constructed;
+	gobject_class->dispose = seahorse_gkr_item_dispose;
 	gobject_class->finalize = seahorse_gkr_item_finalize;
 	gobject_class->set_property = seahorse_gkr_item_set_property;
 	gobject_class->get_property = seahorse_gkr_item_get_property;
@@ -620,10 +636,12 @@ seahorse_gkr_item_class_init (SeahorseGkrItemClass *klass)
  * PUBLIC 
  */
 
-SeahorseGkrItem* 
-seahorse_gkr_item_new (SeahorseSource *source, const gchar *keyring_name, guint32 item_id)
+SeahorseGkrItem *
+seahorse_gkr_item_new (SeahorseGkrKeyring *keyring,
+                       const gchar *keyring_name,
+                       guint32 item_id)
 {
-	return g_object_new (SEAHORSE_TYPE_GKR_ITEM, "source", source, 
+	return g_object_new (SEAHORSE_TYPE_GKR_ITEM, "source", keyring,
 	                     "item-id", item_id, "keyring-name", keyring_name, NULL);
 }
 
diff --git a/gkr/seahorse-gkr-item.h b/gkr/seahorse-gkr-item.h
index aa96504..d5a676f 100644
--- a/gkr/seahorse-gkr-item.h
+++ b/gkr/seahorse-gkr-item.h
@@ -27,6 +27,7 @@
 #include <gnome-keyring.h>
 
 #include "seahorse-gkr-module.h"
+#include "seahorse-gkr-keyring.h"
 
 #include "seahorse-object.h"
 #include "seahorse-source.h"
@@ -63,7 +64,7 @@ struct _SeahorseGkrItemClass {
 
 GType                        seahorse_gkr_item_get_type           (void);
 
-SeahorseGkrItem*             seahorse_gkr_item_new                (SeahorseSource *source,
+SeahorseGkrItem *            seahorse_gkr_item_new                (SeahorseGkrKeyring *keyring,
                                                                    const gchar *keyring_name,
                                                                    guint32 item_id);
 
diff --git a/gkr/seahorse-gkr-keyring.c b/gkr/seahorse-gkr-keyring.c
index d1ddb66..d85cccd 100644
--- a/gkr/seahorse-gkr-keyring.c
+++ b/gkr/seahorse-gkr-keyring.c
@@ -30,6 +30,8 @@
 #include "seahorse-progress.h"
 #include "seahorse-util.h"
 
+#include <gcr/gcr.h>
+
 #include <glib/gi18n.h>
 
 enum {
@@ -42,17 +44,21 @@ enum {
 };
 
 struct _SeahorseGkrKeyringPrivate {
+	GHashTable *items;
 	gchar *keyring_name;
 	gboolean is_default;
-	
+
 	gpointer req_info;
 	GnomeKeyringInfo *keyring_info;
 };
 
-static void seahorse_source_iface (SeahorseSourceIface *iface);
+static void     seahorse_keyring_source_iface        (SeahorseSourceIface *iface);
+static void     seahorse_keyring_collection_iface    (GcrCollectionIface *iface);
 
-G_DEFINE_TYPE_EXTENDED (SeahorseGkrKeyring, seahorse_gkr_keyring, SEAHORSE_TYPE_OBJECT, 0,
-                        G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_SOURCE, seahorse_source_iface));
+G_DEFINE_TYPE_WITH_CODE (SeahorseGkrKeyring, seahorse_gkr_keyring, SEAHORSE_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_SOURCE, seahorse_keyring_source_iface);
+                         G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_keyring_collection_iface);
+);
 
 static GType
 boxed_type_keyring_info (void)
@@ -145,6 +151,24 @@ seahorse_gkr_keyring_refresh (SeahorseGkrKeyring *self)
 		load_keyring_info (self);
 }
 
+void
+seahorse_gkr_keyring_remove_item (SeahorseGkrKeyring *self,
+                                  guint32 item_id)
+{
+	SeahorseGkrItem *item;
+
+	g_return_if_fail (SEAHORSE_IS_GKR_KEYRING (self));
+
+	item = g_hash_table_lookup (self->pv->items, GUINT_TO_POINTER (item_id));
+	if (item != NULL) {
+		g_object_ref (item);
+		g_object_set (item, "source", NULL, NULL);
+		g_hash_table_remove (self->pv->items, GUINT_TO_POINTER (item_id));
+		gcr_collection_emit_removed (GCR_COLLECTION (self), G_OBJECT (item));
+		g_object_unref (item);
+	}
+}
+
 typedef struct {
 	SeahorseGkrKeyring *keyring;
 	gpointer request;
@@ -168,23 +192,13 @@ keyring_load_free (gpointer data)
 
 /* Remove the given key from the context */
 static void
-remove_key_from_context (gpointer kt, SeahorseObject *dummy, SeahorseSource *sksrc)
+remove_key_from_context (gpointer kt,
+                         gpointer value,
+                         gpointer user_data)
 {
 	/* This function gets called as a GHFunc on the self->checks hashtable. */
-	GQuark keyid = GPOINTER_TO_UINT (kt);
-	SeahorseObject *sobj;
-
-	sobj = seahorse_context_get_object (SCTX_APP (), sksrc, keyid);
-	if (sobj != NULL)
-		seahorse_context_remove_object (SCTX_APP (), sobj);
-}
-
-static void
-insert_id_hashtable (SeahorseObject *object, gpointer user_data)
-{
-	g_hash_table_insert ((GHashTable*)user_data,
-	                     GUINT_TO_POINTER (seahorse_object_get_id (object)),
-	                     GUINT_TO_POINTER (TRUE));
+	SeahorseGkrKeyring *self = SEAHORSE_GKR_KEYRING (user_data);
+	seahorse_gkr_keyring_remove_item (self, GPOINTER_TO_UINT (kt));
 }
 
 static void
@@ -194,13 +208,12 @@ on_keyring_load_list_item_ids (GnomeKeyringResult result,
 {
 	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
 	keyring_load_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
-	SeahorsePredicate pred;
-	SeahorseGkrItem *git;
+	SeahorseGkrItem *item;
 	const gchar *keyring_name;
 	GError *error = NULL;
 	GHashTable *checks;
-	guint32 item_id;
-	GQuark id;
+	GHashTableIter iter;
+	gpointer key;
 
 	closure->request = NULL;
 
@@ -214,27 +227,24 @@ on_keyring_load_list_item_ids (GnomeKeyringResult result,
 	g_return_if_fail (keyring_name);
 
 	/* When loading new keys prepare a list of current */
-	checks = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-	seahorse_predicate_clear (&pred);
-	pred.source = SEAHORSE_SOURCE (closure->keyring);
-	pred.type = SEAHORSE_TYPE_GKR_ITEM;
-	seahorse_context_for_objects_full (SCTX_APP (), &pred, insert_id_hashtable, checks);
+	checks = g_hash_table_new (g_direct_hash, g_direct_equal);
+	g_hash_table_iter_init (&iter, closure->keyring->pv->items);
+	while (g_hash_table_iter_next (&iter, &key, NULL))
+		g_hash_table_insert (checks, key, key);
 
 	while (list) {
-		item_id = GPOINTER_TO_UINT (list->data);
-		id = seahorse_gkr_item_get_cannonical (keyring_name, item_id);
+		item = g_hash_table_lookup (closure->keyring->pv->items, list->data);
 
-		git = SEAHORSE_GKR_ITEM (seahorse_context_get_object (seahorse_context_instance (),
-		                                                      SEAHORSE_SOURCE (closure->keyring), id));
-		if (!git) {
-			git = seahorse_gkr_item_new (SEAHORSE_SOURCE (closure->keyring), keyring_name, item_id);
+		if (item == NULL) {
+			item = seahorse_gkr_item_new (closure->keyring, keyring_name,
+			                              GPOINTER_TO_UINT (list->data));
 
 			/* Add to context */
-			seahorse_object_set_parent (SEAHORSE_OBJECT (git), SEAHORSE_OBJECT (closure->keyring));
-			seahorse_context_take_object (seahorse_context_instance (), SEAHORSE_OBJECT (git));
+			g_hash_table_insert (closure->keyring->pv->items, list->data, item);
+			gcr_collection_emit_added (GCR_COLLECTION (closure->keyring), G_OBJECT (item));
 		}
 
-		g_hash_table_remove (checks, GUINT_TO_POINTER (id));
+		g_hash_table_remove (checks, list->data);
 		list = g_list_next (list);
 	}
 
@@ -364,6 +374,7 @@ static void
 seahorse_gkr_keyring_init (SeahorseGkrKeyring *self)
 {
 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_GKR_KEYRING, SeahorseGkrKeyringPrivate);
+	self->pv->items = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
 	g_object_set (self, "tag", SEAHORSE_GKR_TYPE, "location", SEAHORSE_LOCATION_LOCAL, NULL);
 }
 
@@ -371,7 +382,9 @@ static void
 seahorse_gkr_keyring_finalize (GObject *obj)
 {
 	SeahorseGkrKeyring *self = SEAHORSE_GKR_KEYRING (obj);
-	
+
+	g_hash_table_destroy (self->pv->items);
+
 	if (self->pv->keyring_info)
 		gnome_keyring_info_free (self->pv->keyring_info);
 	self->pv->keyring_info = NULL;
@@ -468,13 +481,34 @@ seahorse_gkr_keyring_class_init (SeahorseGkrKeyringClass *klass)
 	                                 FALSE, G_PARAM_READWRITE));
 }
 
-static void 
-seahorse_source_iface (SeahorseSourceIface *iface)
+static void
+seahorse_keyring_source_iface (SeahorseSourceIface *iface)
 {
 	iface->load_async = seahorse_gkr_keyring_load_async;
 	iface->load_finish = seahorse_gkr_keyring_load_finish;
 }
 
+static guint
+seahorse_gkr_keyring_get_length (GcrCollection *collection)
+{
+	SeahorseGkrKeyring *self = SEAHORSE_GKR_KEYRING (collection);
+	return g_hash_table_size (self->pv->items);
+}
+
+static GList *
+seahorse_gkr_keyring_get_objects (GcrCollection *collection)
+{
+	SeahorseGkrKeyring *self = SEAHORSE_GKR_KEYRING (collection);
+	return g_hash_table_get_values (self->pv->items);
+}
+
+static void
+seahorse_keyring_collection_iface (GcrCollectionIface *iface)
+{
+	iface->get_length = seahorse_gkr_keyring_get_length;
+	iface->get_objects = seahorse_gkr_keyring_get_objects;
+}
+
 /* -----------------------------------------------------------------------------
  * PUBLIC 
  */
diff --git a/gkr/seahorse-gkr-keyring.h b/gkr/seahorse-gkr-keyring.h
index a99eaf9..ff61e80 100644
--- a/gkr/seahorse-gkr-keyring.h
+++ b/gkr/seahorse-gkr-keyring.h
@@ -38,7 +38,7 @@
 typedef struct _SeahorseGkrKeyring SeahorseGkrKeyring;
 typedef struct _SeahorseGkrKeyringClass SeahorseGkrKeyringClass;
 typedef struct _SeahorseGkrKeyringPrivate SeahorseGkrKeyringPrivate;
-    
+
 struct _SeahorseGkrKeyring {
 	SeahorseObject parent;
 	SeahorseGkrKeyringPrivate *pv;
@@ -56,6 +56,9 @@ void                 seahorse_gkr_keyring_refresh          (SeahorseGkrKeyring *
 
 void                 seahorse_gkr_keyring_realize          (SeahorseGkrKeyring *self);
 
+void                 seahorse_gkr_keyring_remove_item      (SeahorseGkrKeyring *self,
+                                                            guint32 item_id);
+
 const gchar*         seahorse_gkr_keyring_get_name         (SeahorseGkrKeyring *self);
 
 GnomeKeyringInfo*    seahorse_gkr_keyring_get_info         (SeahorseGkrKeyring *self);
diff --git a/gkr/seahorse-gkr-operation.c b/gkr/seahorse-gkr-operation.c
index d310fd8..775c2ba 100644
--- a/gkr/seahorse-gkr-operation.c
+++ b/gkr/seahorse-gkr-operation.c
@@ -400,8 +400,7 @@ on_delete_gkr_complete (GnomeKeyringResult result,
 		g_simple_async_result_complete_in_idle (res);
 
 	} else {
-		seahorse_context_remove_object (seahorse_context_instance (),
-		                                object);
+		g_object_run_dispose (G_OBJECT (object));
 		delete_gkr_one_object (res);
 	}
 
diff --git a/libseahorse/seahorse-collection.c b/libseahorse/seahorse-collection.c
index 457060a..eed6424 100644
--- a/libseahorse/seahorse-collection.c
+++ b/libseahorse/seahorse-collection.c
@@ -283,13 +283,6 @@ seahorse_collection_has_object (SeahorseCollection *self,
 	if (g_hash_table_lookup (self->pv->objects, object))
 		return TRUE;
 
-	/*
-	 * This happens when the object has changed state, but we have
-	 * not yet received the signal.
-	 */
-	if (maybe_add_object (self, object))
-		return TRUE;
-
 	return FALSE;
 }
 
diff --git a/libseahorse/seahorse-object.c b/libseahorse/seahorse-object.c
index a0dbc73..e56373a 100644
--- a/libseahorse/seahorse-object.c
+++ b/libseahorse/seahorse-object.c
@@ -76,7 +76,6 @@ enum _SeahorseObjectProps {
  * @context:
  * @preferred: Points to the object to prefer over this one
  * @parent: the object's parent
- * @children: a list of children the object has
  * @label: DBUS: "display-name"
  * @markup: Markup text
  * @markup_explicit: If TRUE the markup will not be set automatically
@@ -97,9 +96,7 @@ struct _SeahorseObjectPrivate {
 	SeahorseSource *source;
 	SeahorseContext *context;
 	SeahorseObject *preferred;
-	SeahorseObject *parent;
-	GList *children;
-	
+
     gchar *label;             
     gchar *markup;
     gboolean markup_explicit;
@@ -121,46 +118,6 @@ G_DEFINE_TYPE (SeahorseObject, seahorse_object, G_TYPE_OBJECT);
  */
 
 /**
- * register_child:
- * @self: The parent
- * @child: The new child
- *
- *
- * Sets @child as a child of @self
- */
-static void 
-register_child (SeahorseObject* self, SeahorseObject* child) 
-{
-	g_assert (SEAHORSE_IS_OBJECT (self));
-	g_assert (SEAHORSE_IS_OBJECT (child));
-	g_assert (self != child);
-	g_assert (child->pv->parent == NULL);
-	
-	child->pv->parent = self;
-	self->pv->children = g_list_append (self->pv->children, child);
-}
-
-/**
- * unregister_child:
- * @self: The parent
- * @child: child to remove
- *
- *
- * removes @child from the children list in @self
- */
-static void 
-unregister_child (SeahorseObject* self, SeahorseObject* child) 
-{
-	g_assert (SEAHORSE_IS_OBJECT (self));
-	g_assert (SEAHORSE_IS_OBJECT (child));
-	g_assert (self != child);
-	g_assert (child->pv->parent == self);
-	
-	child->pv->parent = NULL;
-	self->pv->children = g_list_remove (self->pv->children, child);
-}
-
-/**
  * set_string_storage:
  * @value: The value to store
  * @storage: The datastore to write the value to
@@ -316,16 +273,13 @@ seahorse_object_init (SeahorseObject *self)
  * seahorse_object_dispose:
  * @obj: A #SeahorseObject to dispose
  *
- * Before this object is disposed, all it's children get new parents
  *
  */
 static void
 seahorse_object_dispose (GObject *obj)
 {
 	SeahorseObject *self = SEAHORSE_OBJECT (obj);
-	SeahorseObject *parent;
-	GList *l, *children;
-	
+
 	if (self->pv->context != NULL) {
 		seahorse_context_remove_object (self->pv->context, self);
 		g_assert (self->pv->context == NULL);
@@ -341,31 +295,6 @@ seahorse_object_dispose (GObject *obj)
 		self->pv->preferred = NULL;
 	}
 
-	/* 
-	 * When an object is destroyed, we reparent all
-	 * children to this objects parent. If no parent
-	 * of this object, all children become root objects.
-	 */
-
-	parent = self->pv->parent;
-	if (parent)
-		g_object_ref (parent);
-
-	children = g_list_copy (self->pv->children);
-	for (l = children; l; l = g_list_next (l)) {
-		g_return_if_fail (SEAHORSE_IS_OBJECT (l->data));
-		seahorse_object_set_parent (l->data, parent);
-	}
-	g_list_free (children);
-
-	if (parent)
-		g_object_unref (parent);
-	
-	g_assert (self->pv->children == NULL);
-	
-	/* Now remove this object from its parent */
-	seahorse_object_set_parent (self, NULL);
-	
 	G_OBJECT_CLASS (seahorse_object_parent_class)->dispose (obj);	
 }
 
@@ -381,10 +310,8 @@ seahorse_object_finalize (GObject *obj)
 	
 	g_assert (self->pv->source == NULL);
 	g_assert (self->pv->preferred == NULL);
-	g_assert (self->pv->parent == NULL);
 	g_assert (self->pv->context == NULL);
-	g_assert (self->pv->children == NULL);
-	
+
 	g_free (self->pv->label);
 	self->pv->label = NULL;
 	
@@ -429,9 +356,6 @@ seahorse_object_get_property (GObject *obj, guint prop_id, GValue *value,
 	case PROP_PREFERRED:
 		g_value_set_object (value, seahorse_object_get_preferred (self));
 		break;
-	case PROP_PARENT:
-		g_value_set_object (value, seahorse_object_get_parent (self));
-		break;
 	case PROP_ID:
 		g_value_set_uint (value, seahorse_object_get_id (self));
 		break;
@@ -503,9 +427,6 @@ seahorse_object_set_property (GObject *obj, guint prop_id, const GValue *value,
 	case PROP_PREFERRED:
 		seahorse_object_set_preferred (self, SEAHORSE_OBJECT (g_value_get_object (value)));
 		break;
-	case PROP_PARENT:
-		seahorse_object_set_parent (self, SEAHORSE_OBJECT (g_value_get_object (value)));
-		break;
 	case PROP_ID:
 		quark = g_value_get_uint (value);
 		if (quark != self->pv->id) {
@@ -615,11 +536,7 @@ seahorse_object_class_init (SeahorseObjectClass *klass)
 	g_object_class_install_property (gobject_class, PROP_PREFERRED,
 	           g_param_spec_object ("preferred", "Preferred Object", "An object to prefer over this one", 
 	                                SEAHORSE_TYPE_OBJECT, G_PARAM_READWRITE));
-    
-	g_object_class_install_property (gobject_class, PROP_PREFERRED,
-	           g_param_spec_object ("parent", "Parent Object", "This object's parent in the tree.", 
-	                                SEAHORSE_TYPE_OBJECT, G_PARAM_READWRITE));
-	
+
 	g_object_class_install_property (gobject_class, PROP_ID,
 	           g_param_spec_uint ("id", "Object ID", "This object's ID.", 
 	                              0, G_MAXUINT, 0, G_PARAM_READWRITE));
@@ -782,75 +699,6 @@ seahorse_object_set_preferred (SeahorseObject *self, SeahorseObject *value)
 }
 
 /**
- * seahorse_object_get_parent:
- * @self: Object
- *
- * Returns: the parent of the object @self
- */
-SeahorseObject*
-seahorse_object_get_parent (SeahorseObject *self)
-{
-	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
-	return self->pv->parent;
-}
-
-/**
- * seahorse_object_set_parent:
- * @self: the child
- * @value: the parent
- *
- * register @value as the parent of @self:
- */
-void
-seahorse_object_set_parent (SeahorseObject *self, SeahorseObject *value)
-{
-	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
-	g_return_if_fail (self->pv->parent != self);
-	g_return_if_fail (value != self);
-	
-	if (value == self->pv->parent)
-		return;
-	
-	/* Set the new parent/child relationship */
-	if (self->pv->parent != NULL)
-		unregister_child (self->pv->parent, self);
-
-	if (value != NULL)
-		register_child (value, self);
-	
-	g_assert (self->pv->parent == value);
-
-	g_object_notify (G_OBJECT (self), "parent");
-}
-
-/**
- * seahorse_object_get_children:
- * @self: Object
- *
- * Returns: the children of the object @self
- */
-GList*
-seahorse_object_get_children (SeahorseObject *self)
-{
-	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
-	return g_list_copy (self->pv->children);
-}
-
-/**
- * seahorse_object_get_nth_child:
- * @self: Object
- * @index: the number of the child to return
- *
- * Returns: the child number @index
- */
-SeahorseObject*
-seahorse_object_get_nth_child (SeahorseObject *self, guint index)
-{
-	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
-	return SEAHORSE_OBJECT (g_list_nth_data (self->pv->children, index));
-}
-
-/**
  * seahorse_object_get_label:
  * @self: Object
  *
diff --git a/libseahorse/seahorse-object.h b/libseahorse/seahorse-object.h
index c00ce32..8eb819f 100644
--- a/libseahorse/seahorse-object.h
+++ b/libseahorse/seahorse-object.h
@@ -88,14 +88,7 @@ SeahorseObject*     seahorse_object_get_preferred          (SeahorseObject *self
 
 void                seahorse_object_set_preferred          (SeahorseObject *self, 
                                                             SeahorseObject *value);
-
-SeahorseObject*     seahorse_object_get_parent             (SeahorseObject *self);
-
-void                seahorse_object_set_parent             (SeahorseObject *self, 
-                                                            SeahorseObject *value);
  
-GList*              seahorse_object_get_children           (SeahorseObject *self);
-
 SeahorseObject*     seahorse_object_get_nth_child          (SeahorseObject *self,
                                                             guint index);
 
diff --git a/pgp/seahorse-gpgme-key.c b/pgp/seahorse-gpgme-key.c
index 4f7ebcd..dcdc340 100644
--- a/pgp/seahorse-gpgme-key.c
+++ b/pgp/seahorse-gpgme-key.c
@@ -260,7 +260,7 @@ realize_uids (SeahorseGpgmeKey *self)
 
 	/* Add new UIDs */
 	while (guid != NULL) {
-		uid = seahorse_gpgme_uid_new (self->pv->pubkey, guid);
+		uid = seahorse_gpgme_uid_new (self, guid);
 		changed = TRUE;
 		results = seahorse_object_list_append (results, uid);
 		g_object_unref (uid);
diff --git a/pgp/seahorse-gpgme-uid.c b/pgp/seahorse-gpgme-uid.c
index c5e3b54..b324429 100644
--- a/pgp/seahorse-gpgme-uid.c
+++ b/pgp/seahorse-gpgme-uid.c
@@ -260,10 +260,12 @@ seahorse_gpgme_uid_class_init (SeahorseGpgmeUidClass *klass)
  */
 
 SeahorseGpgmeUid* 
-seahorse_gpgme_uid_new (gpgme_key_t pubkey, gpgme_user_id_t userid) 
+seahorse_gpgme_uid_new (SeahorseGpgmeKey *parent,
+                        gpgme_user_id_t userid)
 {
-	return g_object_new (SEAHORSE_TYPE_GPGME_UID, 
-	                     "pubkey", pubkey, 
+	return g_object_new (SEAHORSE_TYPE_GPGME_UID,
+	                     "parent", parent,
+	                     "pubkey", seahorse_gpgme_key_get_public (parent),
 	                     "userid", userid, NULL);
 }
 
@@ -318,19 +320,19 @@ seahorse_gpgme_uid_set_userid (SeahorseGpgmeUid *self, gpgme_user_id_t userid)
 	g_object_notify (obj, "gpgme_index");
 	
 	base = SEAHORSE_PGP_UID (self);
-	
-	string = convert_string (userid->name);
-	seahorse_pgp_uid_set_name (base, string);
+
+	string = convert_string (userid->comment);
+	seahorse_pgp_uid_set_comment (base, string);
 	g_free (string);
-	
+
 	string = convert_string (userid->email);
 	seahorse_pgp_uid_set_email (base, string);
 	g_free (string);
-	
-	string = convert_string (userid->comment);
-	seahorse_pgp_uid_set_comment (base, string);
+
+	string = convert_string (userid->name);
+	seahorse_pgp_uid_set_name (base, string);
 	g_free (string);
-	
+
 	realize_signatures (self);
 
 	seahorse_pgp_uid_set_validity (base, seahorse_gpgme_convert_validity (userid->validity));
diff --git a/pgp/seahorse-gpgme-uid.h b/pgp/seahorse-gpgme-uid.h
index 6cb0fa1..976f553 100644
--- a/pgp/seahorse-gpgme-uid.h
+++ b/pgp/seahorse-gpgme-uid.h
@@ -28,6 +28,7 @@
 
 #include "seahorse-object.h"
 
+#include "pgp/seahorse-gpgme-key.h"
 #include "pgp/seahorse-pgp-uid.h"
 
 #define SEAHORSE_TYPE_GPGME_UID            (seahorse_gpgme_uid_get_type ())
@@ -52,7 +53,7 @@ struct _SeahorseGpgmeUidClass {
 
 GType               seahorse_gpgme_uid_get_type             (void);
 
-SeahorseGpgmeUid*   seahorse_gpgme_uid_new                  (gpgme_key_t pubkey,
+SeahorseGpgmeUid*   seahorse_gpgme_uid_new                  (SeahorseGpgmeKey *parent,
                                                              gpgme_user_id_t userid);
 
 gpgme_key_t         seahorse_gpgme_uid_get_pubkey           (SeahorseGpgmeUid *self);
diff --git a/pgp/seahorse-hkp-source.c b/pgp/seahorse-hkp-source.c
index 95226cd..eb6046b 100644
--- a/pgp/seahorse-hkp-source.c
+++ b/pgp/seahorse-hkp-source.c
@@ -434,7 +434,7 @@ parse_hkp_index (const gchar *response)
 
 				/* And the UID if one was found */                
 				if (has_uid) {
-					SeahorsePgpUid *uid = seahorse_pgp_uid_new (v[2]);
+					SeahorsePgpUid *uid = seahorse_pgp_uid_new (key, v[2]);
 					uids = g_list_prepend (uids, uid);
 				}
 			}
@@ -447,7 +447,7 @@ parse_hkp_index (const gchar *response)
 			SeahorsePgpUid *uid;
 			
 			g_strstrip (line);
-			uid = seahorse_pgp_uid_new (line);
+			uid = seahorse_pgp_uid_new (key, line);
 			uids = g_list_prepend (uids, uid);
             
 		/* Signatures */
diff --git a/pgp/seahorse-ldap-source.c b/pgp/seahorse-ldap-source.c
index 24a18b3..0520a44 100644
--- a/pgp/seahorse-ldap-source.c
+++ b/pgp/seahorse-ldap-source.c
@@ -886,13 +886,14 @@ search_parse_key_from_ldap_entry (SeahorseLDAPSource *self,
 			flags |= SEAHORSE_FLAG_DISABLED;
 		seahorse_pgp_subkey_set_flags (subkey, flags);
 
+		key = seahorse_pgp_key_new ();
+
 		/* Build up a uid */
-		uid = seahorse_pgp_uid_new (uidstr);
+		uid = seahorse_pgp_uid_new (key, uidstr);
 		if (revoked)
 			seahorse_pgp_uid_set_validity (uid, SEAHORSE_VALIDITY_REVOKED);
 
 		/* Now build them into a key */
-		key = seahorse_pgp_key_new ();
 		list = g_list_prepend (NULL, uid);
 		seahorse_pgp_key_set_uids (key, list);
 		seahorse_object_list_free (list);
diff --git a/pgp/seahorse-pgp-commands.c b/pgp/seahorse-pgp-commands.c
index 8c35037..1df23c2 100644
--- a/pgp/seahorse-pgp-commands.c
+++ b/pgp/seahorse-pgp-commands.c
@@ -113,10 +113,9 @@ static void
 seahorse_pgp_commands_show_properties (SeahorseCommands* base, SeahorseObject* obj) 
 {
 	g_return_if_fail (SEAHORSE_IS_OBJECT (obj));
-	
-	if (G_TYPE_FROM_INSTANCE (G_OBJECT (obj)) == SEAHORSE_TYPE_PGP_UID || 
-	    G_TYPE_FROM_INSTANCE (G_OBJECT (obj)) == SEAHORSE_TYPE_GPGME_UID)
-		obj = seahorse_object_get_parent (obj);
+
+	if (SEAHORSE_IS_PGP_UID (obj))
+		obj = SEAHORSE_OBJECT (seahorse_pgp_uid_get_parent (SEAHORSE_PGP_UID (obj)));
 
 	g_return_if_fail (G_TYPE_FROM_INSTANCE (G_OBJECT (obj)) == SEAHORSE_TYPE_PGP_KEY || 
 	                  G_TYPE_FROM_INSTANCE (G_OBJECT (obj)) == SEAHORSE_TYPE_GPGME_KEY);
@@ -154,8 +153,8 @@ seahorse_pgp_commands_delete_objects (SeahorseCommands* base, GList* objects)
 
 	for (l = objects; l; l = g_list_next (l)) {
 		obj = SEAHORSE_OBJECT (l->data);
-		if (G_OBJECT_TYPE (obj) == SEAHORSE_TYPE_GPGME_UID) {
-			if (g_list_find (objects, seahorse_object_get_parent (obj)) == NULL) {
+		if (SEAHORSE_IS_PGP_UID (obj)) {
+			if (g_list_find (objects, seahorse_pgp_uid_get_parent (SEAHORSE_PGP_UID (obj))) == NULL) {
 				to_delete = g_list_prepend (to_delete, obj);
 				++num_identities;
 			}
diff --git a/pgp/seahorse-pgp-key.c b/pgp/seahorse-pgp-key.c
index 9e640ec..dc39574 100644
--- a/pgp/seahorse-pgp-key.c
+++ b/pgp/seahorse-pgp-key.c
@@ -34,6 +34,8 @@
 #include "pgp/seahorse-pgp-uid.h"
 #include "pgp/seahorse-pgp-subkey.h"
 
+#include <gcr/gcr.h>
+
 enum {
 	PROP_0,
 	PROP_PHOTOS,
@@ -47,7 +49,11 @@ enum {
 	PROP_ALGO
 };
 
-G_DEFINE_TYPE (SeahorsePgpKey, seahorse_pgp_key, SEAHORSE_TYPE_OBJECT);
+static void      seahorse_pgp_key_collection_iface_init (GcrCollectionIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (SeahorsePgpKey, seahorse_pgp_key, SEAHORSE_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_pgp_key_collection_iface_init);
+);
 
 struct _SeahorsePgpKeyPrivate {
 	GList *uids;			/* All the UID objects */
@@ -98,28 +104,38 @@ _seahorse_pgp_key_get_uids (SeahorsePgpKey *self)
 static void
 _seahorse_pgp_key_set_uids (SeahorsePgpKey *self, GList *uids)
 {
+	GHashTable *checks;
+	GHashTableIter iter;
+	GObject *uid;
 	guint index;
 	GQuark id;
 	GList *l;
-	
+
 	g_return_if_fail (SEAHORSE_IS_PGP_KEY (self));
 
 	id = seahorse_object_get_id (SEAHORSE_OBJECT (self));
-	
-	/* 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);
+
+	checks = g_hash_table_new (g_direct_hash, g_direct_equal);
+	for (l = self->pv->uids; l; l = g_list_next (l)) {
+		g_hash_table_insert (checks, l->data, l->data);
+	}
 
 	seahorse_object_list_free (self->pv->uids);
 	self->pv->uids = seahorse_object_list_copy (uids);
 	
 	/* Set parent and source on each new one, except the first */
 	for (l = self->pv->uids, index = 0; l; l = g_list_next (l), ++index) {
-		g_object_set (l->data, "id", seahorse_pgp_uid_calc_id (id, index), NULL);
-		if (l != self->pv->uids)
-			seahorse_object_set_parent (l->data, SEAHORSE_OBJECT (self));
+		uid = l->data;
+		g_object_set (uid, "id", seahorse_pgp_uid_calc_id (id, index), NULL);
+		if (!g_hash_table_remove (checks, uid))
+			gcr_collection_emit_added (GCR_COLLECTION (self), uid);
 	}
-	
+
+	g_hash_table_iter_init (&iter, checks);
+	while (g_hash_table_iter_next (&iter, (gpointer *)&uid, NULL))
+		gcr_collection_emit_removed (GCR_COLLECTION (self), uid);
+	g_hash_table_destroy (checks);
+
 	g_object_notify (G_OBJECT (self), "uids");
 }
 
@@ -280,12 +296,6 @@ seahorse_pgp_key_object_dispose (GObject *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;
 
@@ -369,6 +379,32 @@ seahorse_pgp_key_class_init (SeahorsePgpKeyClass *klass)
  	                             "", G_PARAM_READABLE));
 }
 
+static guint
+seahorse_pgp_key_collection_get_length (GcrCollection *collection)
+{
+	SeahorsePgpKey *self = SEAHORSE_PGP_KEY (collection);
+	guint length = g_list_length (self->pv->uids);
+
+	/* First UID is displayed as the key itself */
+	return length ? length - 1 : 0;
+}
+
+static GList *
+seahorse_pgp_key_collection_get_objects (GcrCollection *collection)
+{
+	SeahorsePgpKey *self = SEAHORSE_PGP_KEY (collection);
+
+	/* First UID is displayed as the key itself */
+	return g_list_copy (self->pv->uids ? self->pv->uids->next : NULL);
+}
+
+static void
+seahorse_pgp_key_collection_iface_init (GcrCollectionIface *iface)
+{
+	iface->get_length = seahorse_pgp_key_collection_get_length;
+	iface->get_objects = seahorse_pgp_key_collection_get_objects;
+}
+
 
 /* -----------------------------------------------------------------------------
  * PUBLIC 
diff --git a/pgp/seahorse-pgp-uid.c b/pgp/seahorse-pgp-uid.c
index 44684d8..7959480 100644
--- a/pgp/seahorse-pgp-uid.c
+++ b/pgp/seahorse-pgp-uid.c
@@ -34,6 +34,7 @@
 
 enum {
 	PROP_0,
+	PROP_PARENT,
 	PROP_SIGNATURES,
 	PROP_VALIDITY,
 	PROP_NAME,
@@ -44,6 +45,7 @@ enum {
 G_DEFINE_TYPE (SeahorsePgpUid, seahorse_pgp_uid, SEAHORSE_TYPE_OBJECT);
 
 struct _SeahorsePgpUidPrivate {
+	SeahorsePgpKey *parent;
 	GList *signatures;
 	SeahorseValidity validity;
 	gboolean realized;
@@ -202,6 +204,7 @@ void
 seahorse_pgp_uid_realize (SeahorsePgpUid *self)
 {
 	gchar *markup;
+	gchar *label;
 
 	/* Don't realize if no name present */
 	if (!self->pv->name)
@@ -209,10 +212,11 @@ seahorse_pgp_uid_realize (SeahorsePgpUid *self)
 
 	self->pv->realized = TRUE;
 
-	g_object_set (self, "label", self->pv->name ? self->pv->name : "", NULL);
+	label = seahorse_pgp_uid_calc_label (self->pv->name, self->pv->email, self->pv->comment);
 	markup = seahorse_pgp_uid_calc_markup (self->pv->name, self->pv->email, self->pv->comment, 0);
-	g_object_set (self, "markup", markup, NULL);
+	g_object_set (self, "markup", markup, "label", label, NULL);
 	g_free (markup);
+	g_free (label);
 }
 
 static void
@@ -240,6 +244,9 @@ seahorse_pgp_uid_get_property (GObject *object, guint prop_id,
 	case PROP_SIGNATURES:
 		g_value_set_boxed (value, seahorse_pgp_uid_get_signatures (self));
 		break;
+	case PROP_PARENT:
+		g_value_set_object (value, seahorse_pgp_uid_get_parent (self));
+		break;
 	case PROP_VALIDITY:
 		g_value_set_uint (value, seahorse_pgp_uid_get_validity (self));
 		break;
@@ -265,6 +272,10 @@ seahorse_pgp_uid_set_property (GObject *object, guint prop_id, const GValue *val
 	case PROP_SIGNATURES:
 		seahorse_pgp_uid_set_signatures (self, g_value_get_boxed (value));
 		break;
+	case PROP_PARENT:
+		g_return_if_fail (self->pv->parent == NULL);
+		self->pv->parent = g_value_get_object (value);
+		break;
 	case PROP_VALIDITY:
 		seahorse_pgp_uid_set_validity (self, g_value_get_uint (value));
 		break;
@@ -317,6 +328,10 @@ seahorse_pgp_uid_class_init (SeahorsePgpUidClass *klass)
 	        g_param_spec_uint ("validity", "Validity", "Validity of this identity",
 	                           0, G_MAXUINT, 0, G_PARAM_READWRITE));
 
+	g_object_class_install_property (gobject_class, PROP_PARENT,
+	        g_param_spec_object ("parent", "Parent Key", "Parent Key",
+	                             SEAHORSE_TYPE_PGP_KEY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
         g_object_class_install_property (gobject_class, PROP_NAME,
                 g_param_spec_string ("name", "Name", "User ID name",
                                      "", G_PARAM_READWRITE));
@@ -338,8 +353,9 @@ seahorse_pgp_uid_class_init (SeahorsePgpUidClass *klass)
  * PUBLIC 
  */
 
-SeahorsePgpUid*
-seahorse_pgp_uid_new (const gchar *uid_string)
+SeahorsePgpUid *
+seahorse_pgp_uid_new (SeahorsePgpKey *parent,
+                      const gchar *uid_string)
 {
 	SeahorsePgpUid *uid;
 	gchar *name = NULL;
@@ -348,9 +364,14 @@ seahorse_pgp_uid_new (const gchar *uid_string)
 	
 	if (uid_string)
 		parse_user_id (uid_string, &name, &email, &comment);
-	
-	uid = g_object_new (SEAHORSE_TYPE_PGP_UID, "name", name, "email", email, "comment", comment, NULL);
-	
+
+	uid = g_object_new (SEAHORSE_TYPE_PGP_UID,
+	                    "parent", parent,
+	                    "name", name,
+	                    "email", email,
+	                    "comment", comment,
+	                    NULL);
+
 	g_free (name);
 	g_free (comment);
 	g_free (email);
@@ -358,6 +379,13 @@ seahorse_pgp_uid_new (const gchar *uid_string)
 	return uid;
 }
 
+SeahorsePgpKey *
+seahorse_pgp_uid_get_parent (SeahorsePgpUid *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_PGP_UID (self), NULL);
+	return self->pv->parent;
+}
+
 GList*
 seahorse_pgp_uid_get_signatures (SeahorsePgpUid *self)
 {
diff --git a/pgp/seahorse-pgp-uid.h b/pgp/seahorse-pgp-uid.h
index fbad76d..b4ef7bb 100644
--- a/pgp/seahorse-pgp-uid.h
+++ b/pgp/seahorse-pgp-uid.h
@@ -27,6 +27,8 @@
 #include "seahorse-object.h"
 #include "seahorse-validity.h"
 
+#include "seahorse-pgp-key.h"
+
 #define SEAHORSE_TYPE_PGP_UID            (seahorse_pgp_uid_get_type ())
 
 #define SEAHORSE_PGP_UID(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_PGP_UID, SeahorsePgpUid))
@@ -50,7 +52,10 @@ struct _SeahorsePgpUidClass {
 
 GType             seahorse_pgp_uid_get_type             (void);
 
-SeahorsePgpUid*   seahorse_pgp_uid_new                  (const gchar *uid_string);
+SeahorsePgpUid*   seahorse_pgp_uid_new                  (SeahorsePgpKey *parent,
+                                                         const gchar *uid_string);
+
+SeahorsePgpKey *  seahorse_pgp_uid_get_parent           (SeahorsePgpUid *self);
 
 void              seahorse_pgp_uid_realize              (SeahorsePgpUid *self);
 



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