seahorse r2637 - in trunk: . gkr libseahorse src



Author: nnielsen
Date: Sat Nov 29 23:46:10 2008
New Revision: 2637
URL: http://svn.gnome.org/viewvc/seahorse?rev=2637&view=rev

Log:
	* libseahorse/seahorse-object.c:
	* libseahorse/seahorse-object.h: Better checks to not notify if the 
	value being set on a property is the same.

	* libseahorse/seahorse-operation.c: Some additional 
	safety debugging checks.
	
	* gkr/seahorse-gkr-item.c:
	* gkr/seahorse-gkr-item.h:
	* gkr/seahorse-gkr-item-properties.c:
	* gkr/seahorse-gkr-module.c:
	* gkr/seahorse-gkr-operation.c:
	* gkr/seahorse-gkr-source.c: Load item info, attributes and ACL 
	on demand. Rework dialog so it's more event driven.
	
	* src/main.c:
	* src/seahorse-key-manager.vala: Load gnome-keyring items on startup.


Modified:
   trunk/ChangeLog
   trunk/gkr/seahorse-gkr-item-properties.c
   trunk/gkr/seahorse-gkr-item.c
   trunk/gkr/seahorse-gkr-item.h
   trunk/gkr/seahorse-gkr-module.c
   trunk/gkr/seahorse-gkr-operation.c
   trunk/gkr/seahorse-gkr-source.c
   trunk/libseahorse/seahorse-object.c
   trunk/libseahorse/seahorse-object.h
   trunk/libseahorse/seahorse-operation.c
   trunk/src/main.c
   trunk/src/seahorse-key-manager.c
   trunk/src/seahorse-key-manager.vala
   trunk/src/vala-build.stamp

Modified: trunk/gkr/seahorse-gkr-item-properties.c
==============================================================================
--- trunk/gkr/seahorse-gkr-item-properties.c	(original)
+++ trunk/gkr/seahorse-gkr-item-properties.c	Sat Nov 29 23:46:10 2008
@@ -35,29 +35,21 @@
 
 #include "common/seahorse-bind.h"
 
+GType
+boxed_access_control_type (void)
+{
+	static GType type = 0;
+	if (!type)
+		type = g_boxed_type_register_static ("GnomeKeyringAccessControl", 
+		                                     (GBoxedCopyFunc)gnome_keyring_access_control_copy,
+		                                     (GBoxedFreeFunc)gnome_keyring_access_control_free);
+	return type;
+}
+
 /* -----------------------------------------------------------------------------
  * MAIN TAB 
  */
 
-static void
-update_password (SeahorseWidget *swidget, SeahorseGkrItem *git)
-{
-    SeahorseSecureEntry *entry;
-    gchar *secret;
-    
-    entry = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (swidget), 
-                                   "secure-password-entry"));
-    if (entry) {
-        
-        /* Retrieve initial password. Try to keep it safe */
-        WITH_SECURE_MEM ((secret = gnome_keyring_item_info_get_secret (git->info)));
-        seahorse_secure_entry_set_text (entry, secret ? secret : "");
-        g_free (secret);
-    
-        seahorse_secure_entry_reset_changed (entry);
-    }
-}
-
 static gboolean
 transform_item_use (const GValue *from, GValue *to)
 {
@@ -85,6 +77,7 @@
 		label = _("Saved password or login");
 		break;
 	default:
+		label = "";
 	        g_return_val_if_reached (FALSE);
 	};
 	
@@ -113,6 +106,7 @@
 		label = _("Password");
 		break;
 	default:
+		label = "";
 	        g_return_val_if_reached (FALSE);
 	};
 	
@@ -152,11 +146,11 @@
 transform_attributes_server (const GValue *from, GValue *to)
 {
 	GnomeKeyringAttributeList *attrs;
-	g_return_val_if_fail (G_VALUE_TYPE (from) == G_TYPE_POINTER, FALSE);
-	g_return_val_if_fail (G_VALUE_TYPE (to) == G_TYPE_STRING, FALSE);
-	attrs = g_value_get_pointer (from);
+	attrs = g_value_get_boxed (from);
 	if (attrs)
 		g_value_set_string (to, seahorse_gkr_find_string_attribute (attrs, "server"));
+	if (!g_value_get_string (to))
+		g_value_set_string (to, "");
 	return TRUE;
 }
 
@@ -164,103 +158,95 @@
 transform_attributes_user (const GValue *from, GValue *to)
 {
 	GnomeKeyringAttributeList *attrs;
-	g_return_val_if_fail (G_VALUE_TYPE (from) == G_TYPE_POINTER, FALSE);
-	g_return_val_if_fail (G_VALUE_TYPE (to) == G_TYPE_STRING, FALSE);
-	attrs = g_value_get_pointer (from);
+	attrs = g_value_get_boxed (from);
 	if (attrs)
 		g_value_set_string (to, seahorse_gkr_find_string_attribute (attrs, "user"));
+	if (!g_value_get_string (to))
+		g_value_set_string (to, "");
 	return TRUE;
 }
 
 static void
-setup_main (SeahorseWidget *swidget)
+transfer_password (SeahorseGkrItem *git, SeahorseWidget *swidget)
 {
-	SeahorseObject *object;
-	
-	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-
-	/* Setup the image properly */
-	seahorse_bind_property ("icon", object, "stock", 
-	                        seahorse_widget_get_widget (swidget, "key-image"));
-	
-	/* Setup the label properly */
-	seahorse_bind_property ("label", object, "text", 
-	                        seahorse_widget_get_widget (swidget, "description-field") );
-	
-	/* Window title */
-	seahorse_bind_property ("label", object, "title", 
-	                        seahorse_widget_get_toplevel (swidget));
-	
-	/* Usage */
-	seahorse_bind_property_full ("use", object, transform_item_use, "label", 
-	                             seahorse_widget_get_widget (swidget, "use-field"), NULL);
-	
-	/* Item Type */
-	seahorse_bind_property_full ("use", object, transform_item_type, "label", 
-	                             seahorse_widget_get_widget (swidget, "type-field"), NULL);
-	
-	/* Network field visibility */
-	seahorse_bind_property_full ("use", object, transform_network_visible, "visible",
-	                             seahorse_widget_get_widget (swidget, "server-label"),
-	                             seahorse_widget_get_widget (swidget, "server-field"),
-	                             seahorse_widget_get_widget (swidget, "login-label"),
-	                             seahorse_widget_get_widget (swidget, "login-field"), NULL);
-
-	/* Server name */
-	seahorse_bind_property_full ("item-attributes", object, transform_attributes_server, "label", 
-	                             seahorse_widget_get_widget (swidget, "server-field"), NULL);
-	
-	/* User name */
-	seahorse_bind_property_full ("item-attributes", object, transform_attributes_user, "label", 
-	                             seahorse_widget_get_widget (swidget, "login-field"), NULL);
+	GtkWidget *expander;
+	SeahorseSecureEntry *entry;
+	const gchar *secret;
+	
+	expander = seahorse_widget_get_widget (swidget, "password-expander");
+	g_return_if_fail (expander);
+
+	entry = g_object_get_data (G_OBJECT (swidget), "secure-password-entry");
+	g_return_if_fail (entry);
+
+	if (gtk_expander_get_expanded (GTK_EXPANDER (expander))) {
+		secret = seahorse_gkr_item_get_secret (git);
+		seahorse_secure_entry_set_text (entry, secret ? secret : "");
+	} else {
+		seahorse_secure_entry_set_text (entry, "");
+	}
+	seahorse_secure_entry_reset_changed (entry);
 }
 
 static void
 password_activate (SeahorseSecureEntry *entry, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorseGkrItem *git;
-    SeahorseOperation *op;
-    GnomeKeyringItemInfo *info;
-    GtkWidget *widget;
-    GError *err = NULL;
+	SeahorseObject *object;
+	SeahorseGkrItem *git;
+	SeahorseOperation *op;
+	GnomeKeyringItemInfo *info;
+	GtkWidget *expander;
     
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    if (!object)
-	    return;
-    git = SEAHORSE_GKR_ITEM (object);
+	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+	if (!object)
+		return;
 
-    widget = seahorse_widget_get_widget (swidget, "password-expander");
-    g_return_if_fail (widget);
-    if (!gtk_expander_get_expanded (GTK_EXPANDER (widget)))
-        return;
+	git = SEAHORSE_GKR_ITEM (object);
+
+	expander = seahorse_widget_get_widget (swidget, "password-expander");
+	g_return_if_fail (expander);
+	if (!gtk_expander_get_expanded (GTK_EXPANDER (expander)))
+		return;
+
+	entry = g_object_get_data (G_OBJECT (swidget), "secure-password-entry");
+	if (!seahorse_secure_entry_get_changed (entry))
+		return;
+
+	if (g_object_get_data (G_OBJECT (swidget), "updating-password"))
+		return;
+	g_object_set_data (G_OBJECT (swidget), "updating-password", "updating");
+
+	g_object_ref (git);
+	g_object_ref (entry);
+	gtk_widget_set_sensitive (expander, FALSE);
+    	
+	/* Make sure we've loaded the information */
+	seahorse_util_wait_until (seahorse_gkr_item_get_info (git));
+    
+	info = gnome_keyring_item_info_copy (seahorse_gkr_item_get_info (git));
+	gnome_keyring_item_info_set_secret (info, seahorse_secure_entry_get_text (entry));
+
+	op = seahorse_gkr_operation_update_info (git, info);
+	gnome_keyring_item_info_free (info);
+    
+	/* This is usually a quick operation */
+	seahorse_operation_wait (op);
+	
+	/* Set the password back if failed */
+	if (!seahorse_operation_is_successful (op))
+		transfer_password (git, swidget);
+
+	gtk_widget_set_sensitive (expander, TRUE);
+	g_object_unref (entry);
+	g_object_unref (git);
+    
+	if (!seahorse_operation_is_successful (op))
+		seahorse_operation_display_error (op, _("Couldn't change password."),
+		                                  seahorse_widget_get_toplevel (swidget));
+	
+	g_object_unref (op);
+	g_object_set_data (G_OBJECT (swidget), "updating-description", NULL);
 
-    entry = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (swidget), 
-                                                "secure-password-entry"));
-    if (!entry || !seahorse_secure_entry_get_changed (entry))
-        return;
-        
-    /* Setup for saving */
-    WITH_SECURE_MEM (info = gnome_keyring_item_info_copy (git->info));
-    WITH_SECURE_MEM (gnome_keyring_item_info_set_secret (info, 
-                            seahorse_secure_entry_get_text (entry)));
-
-    gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE);
-    
-    op = seahorse_gkr_operation_update_info (git, info);
-    gnome_keyring_item_info_free (info);
-    
-    /* This is usually a quick operation */
-    seahorse_operation_wait (op);
-    
-    if (!seahorse_operation_is_successful (op)) {
-        seahorse_operation_copy_error (op, &err);
-        seahorse_util_handle_error (err, _("Couldn't change password."));
-        g_clear_error (&err);
-        update_password (swidget, git);
-    }
-    
-    gtk_widget_set_sensitive (GTK_WIDGET (entry), TRUE);
 }
 
 static gboolean
@@ -275,10 +261,7 @@
 {
     GtkWidget *widget;
     
-    widget = GTK_WIDGET (g_object_get_data (G_OBJECT (swidget), "secure-password-entry"));
-    if (!widget)
-        return;
-    
+    widget = g_object_get_data (G_OBJECT (swidget), "secure-password-entry");
     seahorse_secure_entry_set_visibility (SEAHORSE_SECURE_ENTRY (widget), 
                                           gtk_toggle_button_get_active (button));
 }
@@ -289,85 +272,84 @@
     SeahorseObject *object;
     SeahorseGkrItem *git;
     GtkWidget *widget;
-    GtkWidget *box;
 
     object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+    if (!object)
+	    return;
     git = SEAHORSE_GKR_ITEM (object);
 
     if (!gtk_expander_get_expanded (expander))
         return;
 
-    widget = GTK_WIDGET (g_object_get_data (G_OBJECT (swidget), "secure-password-entry"));
-    if (!widget) {
-        widget = seahorse_secure_entry_new ();
-        
-        box = seahorse_widget_get_widget (swidget, "password-box-area");
-        g_return_if_fail (box != NULL);
-        gtk_container_add (GTK_CONTAINER (box), widget);
-        g_object_set_data (G_OBJECT (swidget), "secure-password-entry", widget);
-        gtk_widget_show (widget);
-        
-        /* Retrieve initial password */
-        update_password (swidget, git);
-        
-        /* Now watch for changes in the password */
-        g_signal_connect (widget, "activate", G_CALLBACK (password_activate), swidget);
-        g_signal_connect_after (widget, "focus-out-event", G_CALLBACK (password_focus_out), swidget);
-    }
-    
     /* Always have a hidden password when opening box */
     widget = seahorse_widget_get_widget (swidget, "show-password-check");
     g_return_if_fail (widget != NULL);
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+    
+    /* Make sure to trigger retrieving the secret */
+    transfer_password (git, swidget);
 }
 
 static void
 description_activate (GtkWidget *entry, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorseGkrItem *git;
-    SeahorseOperation *op;
-    GnomeKeyringItemInfo *info;
-    const gchar *text;
-    gchar *original;
-    GError *err = NULL;
-    
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    if (!object)
-	    return;
+	SeahorseObject *object;
+	SeahorseGkrItem *git;
+	SeahorseOperation *op = NULL;
+	GnomeKeyringItemInfo *info;
+	const gchar *text;
+	gchar *original;
     
-    git = SEAHORSE_GKR_ITEM (object);
+	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+	if (!object)
+		return;
 
-    text = gtk_entry_get_text (GTK_ENTRY (entry));
-    original = seahorse_gkr_item_get_description (git);
-    
-    /* Make sure not the same */
-    if (text == original || g_utf8_collate (text, original ? original : "") == 0) {
-        g_free (original);
-        return;
-    }
+	if (g_object_get_data (G_OBJECT (swidget), "updating-description"))
+		return;
+	g_object_set_data (G_OBJECT (swidget), "updating-description", "updating");
+
+	git = SEAHORSE_GKR_ITEM (object);
+	
+	g_object_ref (git);
+	g_object_ref (entry);
+	gtk_widget_set_sensitive (entry, FALSE);
+
+	/* Make sure we've loaded the information */
+	seahorse_util_wait_until (seahorse_gkr_item_get_info (git));
+	info = seahorse_gkr_item_get_info (git);
+    
+	/* Make sure not the same */
+	text = gtk_entry_get_text (GTK_ENTRY (entry));
+	original = gnome_keyring_item_info_get_display_name (info);
+	if (text != original && g_utf8_collate (text, original ? original : "") != 0) {
+		
+		info = gnome_keyring_item_info_copy (info);
+		gnome_keyring_item_info_set_display_name (info, text);
+		
+		op = seahorse_gkr_operation_update_info (git, info);
+		gnome_keyring_item_info_free (info);
 
-    gtk_widget_set_sensitive (entry, FALSE);
-    
-    WITH_SECURE_MEM (info = gnome_keyring_item_info_copy (git->info));
-    gnome_keyring_item_info_set_display_name (info, text);
-    
-    op = seahorse_gkr_operation_update_info (git, info);
-    gnome_keyring_item_info_free (info);
-    
-    /* This is usually a quick operation */
-    seahorse_operation_wait (op);
-    
-    if (!seahorse_operation_is_successful (op)) {
-        seahorse_operation_copy_error (op, &err);
-        seahorse_util_handle_error (err, _("Couldn't set description."));
-        g_clear_error (&err);
-        gtk_entry_set_text (GTK_ENTRY (entry), original);
-    }
-    
-    gtk_widget_set_sensitive (entry, TRUE);
-    
-    g_free (original);
+		/* This is usually a quick operation */
+		seahorse_operation_wait (op);
+
+		if (!seahorse_operation_is_successful (op)) 
+			gtk_entry_set_text (GTK_ENTRY (entry), original);
+
+	}
+
+	gtk_widget_set_sensitive (entry, TRUE);
+	g_object_unref (entry);
+	g_object_unref (git);
+	g_free (original);
+    
+	if (op) {
+		if (!seahorse_operation_is_successful (op)) 
+			seahorse_operation_display_error (op, _("Couldn't set description."),
+			                                  seahorse_widget_get_toplevel (swidget));
+		g_object_unref (op);
+	}
+	
+	g_object_set_data (G_OBJECT (swidget), "updating-description", NULL);
 }
 
 static gboolean
@@ -377,6 +359,83 @@
 	return FALSE;
 }
 
+
+static void
+setup_main (SeahorseWidget *swidget)
+{
+	SeahorseObject *object;
+	GtkWidget *widget;
+	GtkWidget *box;
+	
+	widget = seahorse_widget_get_widget (swidget, "password-expander");
+	g_return_if_fail (widget);
+	g_signal_connect_after (widget, "activate", G_CALLBACK (password_expander_activate), swidget);
+
+	glade_xml_signal_connect_data (swidget->xml, "show_password_toggled", 
+	                               G_CALLBACK (show_password_toggled), swidget);
+
+	widget = seahorse_widget_get_widget (swidget, "description-field");
+	g_return_if_fail (widget != NULL);
+	g_signal_connect (widget, "activate", G_CALLBACK (description_activate), swidget);
+	g_signal_connect (widget, "focus-out-event", G_CALLBACK (description_focus_out), swidget);
+
+	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+
+	/* Setup the image properly */
+	seahorse_bind_property ("icon", object, "stock", 
+	                        seahorse_widget_get_widget (swidget, "key-image"));
+	
+	/* Setup the label properly */
+	seahorse_bind_property ("label", object, "text", 
+	                        seahorse_widget_get_widget (swidget, "description-field") );
+	
+	/* Window title */
+	seahorse_bind_property ("label", object, "title", 
+	                        seahorse_widget_get_toplevel (swidget));
+	
+	/* Usage */
+	seahorse_bind_property_full ("use", object, transform_item_use, "label", 
+	                             seahorse_widget_get_widget (swidget, "use-field"), NULL);
+	
+	/* Item Type */
+	seahorse_bind_property_full ("use", object, transform_item_type, "label", 
+	                             seahorse_widget_get_widget (swidget, "type-field"), NULL);
+	
+	/* Network field visibility */
+	seahorse_bind_property_full ("use", object, transform_network_visible, "visible",
+	                             seahorse_widget_get_widget (swidget, "server-label"),
+	                             seahorse_widget_get_widget (swidget, "server-field"),
+	                             seahorse_widget_get_widget (swidget, "login-label"),
+	                             seahorse_widget_get_widget (swidget, "login-field"), NULL);
+
+	/* Server name */
+	seahorse_bind_property_full ("item-attributes", object, transform_attributes_server, "label", 
+	                             seahorse_widget_get_widget (swidget, "server-field"), NULL);
+	
+	/* User name */
+	seahorse_bind_property_full ("item-attributes", object, transform_attributes_user, "label", 
+	                             seahorse_widget_get_widget (swidget, "login-field"), NULL);
+	
+	/* Create the password entry */
+	widget = seahorse_secure_entry_new ();
+	        
+	box = seahorse_widget_get_widget (swidget, "password-box-area");
+	g_return_if_fail (box != NULL);
+	gtk_container_add (GTK_CONTAINER (box), widget);
+	g_object_set_data (G_OBJECT (swidget), "secure-password-entry", widget);
+	gtk_widget_show (widget);
+	        
+	/* Now watch for changes in the password */
+	g_signal_connect (widget, "activate", G_CALLBACK (password_activate), swidget);
+	g_signal_connect_after (widget, "focus-out-event", G_CALLBACK (password_focus_out), swidget);
+	    
+	/* Sensitivity of the password entry */
+	seahorse_bind_property ("has-secret", object, "sensitive", widget);
+	
+	/* Updating of the password entry */
+	seahorse_bind_objects ("has-secret", object, (SeahorseTransfer)transfer_password, swidget);
+}
+
 /* -----------------------------------------------------------------------------
  * DETAILS TAB
  */
@@ -389,9 +448,8 @@
 	GString *details;
 	guint i;
 
-	g_return_val_if_fail (G_VALUE_TYPE (from) == G_TYPE_POINTER, FALSE);
 	g_return_val_if_fail (G_VALUE_TYPE (to) == G_TYPE_STRING, FALSE);
-	attrs = g_value_get_pointer (from);
+	attrs = g_value_get_boxed (from);
 	
 	details = g_string_new (NULL);
 	if (attrs) {
@@ -437,215 +495,228 @@
  * APPLICATIONS TAB 
  */
 
-static gint
-selected_application_index (SeahorseWidget *swidget)
-{
-    GtkTreeView *tree;
-    GtkTreePath *path;
-    GtkTreeModel *model;
-    GtkTreeSelection *selection;
-    GtkTreeIter iter;
-    gint* indices;
-    gint ret;
-    
-    tree = GTK_TREE_VIEW (seahorse_widget_get_widget (swidget, "application-list"));
-    g_return_val_if_fail (GTK_IS_TREE_VIEW (tree), -1);
-    
-    selection = gtk_tree_view_get_selection (tree);
-    if (!gtk_tree_selection_get_selected (selection, &model, &iter))
-        return -1;
-        
-    path = gtk_tree_model_get_path (model, &iter);
-    g_return_val_if_fail (path, -1);
-    
-    indices = gtk_tree_path_get_indices (path);
-    g_return_val_if_fail (indices, -1);
-    
-    ret = *indices;
-    gtk_tree_path_free (path);
-    
-    return ret;
-}
+enum {
+	APPS_ACCESS,
+	APPS_NAME,
+	APPS_N_COLUMNS
+};
 
 static void
 update_application_details (SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorseGkrItem *git;
-    GnomeKeyringAccessControl *ac;
-    GtkLabel *label;
-    GtkToggleButton *toggle;
-    GnomeKeyringAccessType access;
-    gint index;
-    gchar *path;
+	GnomeKeyringAccessControl *ac;
+	GtkLabel *label;
+	GtkToggleButton *toggle;
+	GnomeKeyringAccessType access;
+	GtkTreeView *tree;
+	GtkTreePath *path;
+	GtkTreeModel *model;
+	GtkTreeSelection *selection;
+	GtkTreeIter iter;
+	gchar *filename;
     
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    git = SEAHORSE_GKR_ITEM (object);
-
-    index = selected_application_index (swidget);
-    if (index < 0) {
-        ac = NULL;
-    } else {
-        ac = (GnomeKeyringAccessControl*)g_list_nth_data (git->acl, index);
-        g_return_if_fail (ac);
-    }
-        
-    seahorse_widget_set_sensitive (swidget, "application-details", ac != NULL);
-    
-    label = GTK_LABEL (seahorse_widget_get_widget (swidget, "application-path"));
-    g_return_if_fail (GTK_IS_LABEL (label));
-    path = ac ? gnome_keyring_item_ac_get_path_name (ac) : NULL;
-    gtk_label_set_text (label, path ? path : "");
-    g_free (path);
-
-    g_object_set_data (G_OBJECT (swidget), "updating", "updating");
-    access = ac ? gnome_keyring_item_ac_get_access_type (ac) : 0;
-    
-    toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, "application-read"));
-    g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
-    gtk_toggle_button_set_active (toggle, access & GNOME_KEYRING_ACCESS_READ);    
-
-    toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, "application-write"));
-    g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));    
-    gtk_toggle_button_set_active (toggle, access & GNOME_KEYRING_ACCESS_WRITE);    
-
-    toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, "application-delete"));
-    g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
-    gtk_toggle_button_set_active (toggle, access & GNOME_KEYRING_ACCESS_REMOVE);
+	tree = GTK_TREE_VIEW (seahorse_widget_get_widget (swidget, "application-list"));
+	g_return_if_fail (GTK_IS_TREE_VIEW (tree));
+	    
+	selection = gtk_tree_view_get_selection (tree);
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+		return;
+	        
+	path = gtk_tree_model_get_path (model, &iter);
+	g_return_if_fail (path);
+	
+	/* Dig out the current value */
+	gtk_tree_model_get (model, &iter, APPS_ACCESS, &ac, -1);
+	
+	seahorse_widget_set_sensitive (swidget, "application-details", ac != NULL);
+    
+	label = GTK_LABEL (seahorse_widget_get_widget (swidget, "application-path"));
+	g_return_if_fail (GTK_IS_LABEL (label));
+	filename = ac ? gnome_keyring_item_ac_get_path_name (ac) : NULL;
+	gtk_label_set_text (label, filename ? filename : "");
+	g_free (filename);
+
+	g_object_set_data (G_OBJECT (swidget), "updating", "updating");
+	access = ac ? gnome_keyring_item_ac_get_access_type (ac) : 0;
+    
+	toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, "application-read"));
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
+	gtk_toggle_button_set_active (toggle, access & GNOME_KEYRING_ACCESS_READ);    
+
+	toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, "application-write"));
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));    
+	gtk_toggle_button_set_active (toggle, access & GNOME_KEYRING_ACCESS_WRITE);    
+
+	toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, "application-delete"));
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
+	gtk_toggle_button_set_active (toggle, access & GNOME_KEYRING_ACCESS_REMOVE);
     
-    g_object_set_data (G_OBJECT (swidget), "updating", NULL);
+	g_object_set_data (G_OBJECT (swidget), "updating", NULL);
+	gnome_keyring_access_control_free (ac);
 }
 
 static void
 application_selection_changed (GtkTreeSelection *selection, SeahorseWidget *swidget)
 {
-    update_application_details (swidget);
+	update_application_details (swidget);
 }
 
 static void 
 merge_toggle_button_access (SeahorseWidget *swidget, const gchar *identifier, 
                             GnomeKeyringAccessType *access, GnomeKeyringAccessType type)
 {
-    GtkToggleButton *toggle;
+	GtkToggleButton *toggle;
     
-    toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, identifier));
-    g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
-    if (gtk_toggle_button_get_active (toggle))
-        *access |= type;
-    else
-        *access &= ~type;
+	toggle = GTK_TOGGLE_BUTTON (seahorse_widget_get_widget (swidget, identifier));
+	g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle));
+	if (gtk_toggle_button_get_active (toggle))
+		*access |= type;
+	else
+		*access &= ~type;
 }
 
 static void
 application_access_toggled (GtkCheckButton *check, SeahorseWidget *swidget)
 {
-    SeahorseObject *object;
-    SeahorseGkrItem *git;
-    SeahorseOperation *op;
-    GnomeKeyringAccessType access;
-    GnomeKeyringAccessControl *ac;
-    GError *err = NULL;
-    GList *acl;
-    guint index;
-    
-    /* Just us setting up the controls, not the user */
-    if (g_object_get_data (G_OBJECT (swidget), "updating"))
-        return;
-    
-    object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
-    git = SEAHORSE_GKR_ITEM (object);
-
-    index = selected_application_index (swidget);
-    g_return_if_fail (index >= 0);
-    
-    acl = gnome_keyring_acl_copy (git->acl);
-    ac = (GnomeKeyringAccessControl*)g_list_nth_data (acl, index);
-    g_return_if_fail (ac);
-    
-    access = gnome_keyring_item_ac_get_access_type (ac);
+	SeahorseObject *object;
+	SeahorseGkrItem *git;
+	SeahorseOperation *op;
+	GnomeKeyringAccessType access;
+	GnomeKeyringAccessControl *ac;
+	GtkTreeView *tree;
+	GtkTreePath *path;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+	GError *err = NULL;
+	GList *acl;
+    
+	/* Just us setting up the controls, not the user */
+	if (g_object_get_data (G_OBJECT (swidget), "updating"))
+		return;
     
-    merge_toggle_button_access (swidget, "application-read", &access, GNOME_KEYRING_ACCESS_READ);    
-    merge_toggle_button_access (swidget, "application-write", &access, GNOME_KEYRING_ACCESS_WRITE);    
-    merge_toggle_button_access (swidget, "application-delete", &access, GNOME_KEYRING_ACCESS_REMOVE);    
-
-    if (access != gnome_keyring_item_ac_get_access_type (ac)) {
-        
-        gnome_keyring_item_ac_set_access_type (ac, access);
+	object = SEAHORSE_OBJECT_WIDGET (swidget)->object;
+	git = SEAHORSE_GKR_ITEM (object);
 
-        seahorse_widget_set_sensitive (swidget, "application-details", FALSE);
-        
-        op = seahorse_gkr_operation_update_acl (git, acl);
-        g_return_if_fail (op);
-        
-        seahorse_operation_wait (op);
-        if (!seahorse_operation_is_successful (op)) {
-            seahorse_operation_copy_error (op, &err);
-            seahorse_util_handle_error (err, _("Couldn't set application access."));
-            g_clear_error (&err);
-            update_application_details (swidget);
-        }
-                
-        seahorse_widget_set_sensitive (swidget, "application-details", TRUE);        
-    }
-    
-    gnome_keyring_acl_free (acl);
+	tree = GTK_TREE_VIEW (seahorse_widget_get_widget (swidget, "application-list"));
+	g_return_if_fail (GTK_IS_TREE_VIEW (tree));
+	    
+	selection = gtk_tree_view_get_selection (tree);
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+		g_return_if_reached ();
+	        
+	path = gtk_tree_model_get_path (model, &iter);
+	g_return_if_fail (path);
+	
+	/* Update the access control on that one */
+	gtk_tree_model_get (model, &iter, APPS_ACCESS, &ac, -1);
+	access = gnome_keyring_item_ac_get_access_type (ac);
+	merge_toggle_button_access (swidget, "application-read", &access, GNOME_KEYRING_ACCESS_READ);    
+	merge_toggle_button_access (swidget, "application-write", &access, GNOME_KEYRING_ACCESS_WRITE);    
+	merge_toggle_button_access (swidget, "application-delete", &access, GNOME_KEYRING_ACCESS_REMOVE);
+	
+	/* If it's changed */
+	if (access != gnome_keyring_item_ac_get_access_type (ac)) {
+		
+		/* Update the store with this new stuff */
+	        gnome_keyring_item_ac_set_access_type (ac, access);
+	        gtk_list_store_set (GTK_LIST_STORE (model), &iter, APPS_ACCESS, ac, -1);
+	        gnome_keyring_access_control_free (ac);
+		
+	        /* Build up a full ACL from what we have */
+	        acl = NULL;
+	        if (!gtk_tree_model_get_iter_first (model, &iter))
+	        	g_return_if_reached ();
+        	do {
+        		gtk_tree_model_get (model, &iter, APPS_ACCESS, &ac, -1);
+        		acl = g_list_append (acl, ac);
+        	} while (gtk_tree_model_iter_next (model, &iter));
+
+        	seahorse_widget_set_sensitive (swidget, "application-details", FALSE);
+        	g_object_ref (git);
+        
+        	op = seahorse_gkr_operation_update_acl (git, acl);
+        	g_return_if_fail (op);
+        
+        	seahorse_operation_wait (op);
+        	
+        	gnome_keyring_acl_free (acl);
+        	
+        	if (!seahorse_operation_is_successful (op))
+        		update_application_details (swidget);
+
+                seahorse_widget_set_sensitive (swidget, "application-details", TRUE);
+                g_object_unref (git);
+
+        	if (!seahorse_operation_is_successful (op)) {
+        		seahorse_operation_copy_error (op, &err);
+        		seahorse_util_handle_error (err, _("Couldn't set application access."));
+        		g_clear_error (&err);
+        	}
+        	
+        	g_object_unref (op);
+	}
 }
 
 static void 
 update_application (SeahorseGkrItem *git, SeahorseWidget *swidget)
 {
-    GtkTreeView *tree;
-    GtkListStore *store;
-    GtkTreeModel *model;
-    GtkTreeIter iter;
-    GtkCellRenderer *renderer;
-    GnomeKeyringAccessControl *ac;
-    GtkTreeViewColumn *column;
-    GList *acl;
-    gboolean valid;
-    gchar *display;
-
-    tree = GTK_TREE_VIEW (seahorse_widget_get_widget (swidget, "application-list"));
-    g_return_if_fail (tree);
-    
-    model = gtk_tree_view_get_model (tree);
-    if (!model) {
-        store = gtk_list_store_new (1, GTK_TYPE_STRING);
-        model = GTK_TREE_MODEL (store);
-        gtk_tree_view_set_model (tree, model);
-        
-        renderer = gtk_cell_renderer_text_new ();
-        column = gtk_tree_view_column_new_with_attributes ("name", renderer, "text", 0, NULL);
-        gtk_tree_view_append_column (tree, column);
-    } else {
-        store = GTK_LIST_STORE (model);
-    }
-    
-    acl = git->acl;
+	GtkTreeView *tree;
+	GtkListStore *store;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkCellRenderer *renderer;
+	GnomeKeyringAccessControl *ac;
+	GtkTreeViewColumn *column;
+	GList *acl;
+	gboolean valid;
+	gchar *display;
+
+	tree = GTK_TREE_VIEW (seahorse_widget_get_widget (swidget, "application-list"));
+	g_return_if_fail (tree);
+    
+	model = gtk_tree_view_get_model (tree);
+	if (!model) {
+		g_assert (2 == APPS_N_COLUMNS);
+		store = gtk_list_store_new (2, boxed_access_control_type (), GTK_TYPE_STRING);
+		model = GTK_TREE_MODEL (store);
+		gtk_tree_view_set_model (tree, model);
+
+		renderer = gtk_cell_renderer_text_new ();
+		column = gtk_tree_view_column_new_with_attributes ("name", renderer, "text", APPS_NAME, NULL);
+		gtk_tree_view_append_column (tree, column);
+	} else {
+		store = GTK_LIST_STORE (model);
+	}
     
-    /* Fill in the tree store, replacing any rows already present */
-    valid = gtk_tree_model_get_iter_first (model, &iter);
-    for ( ; acl; acl = g_list_next (acl)) {
+	acl = seahorse_gkr_item_get_acl (git);
     
-        ac = (GnomeKeyringAccessControl*)acl->data;
-        g_return_if_fail (ac);
-        
-        if (!valid)
-            gtk_list_store_append (store, &iter);
-
-        display = gnome_keyring_item_ac_get_display_name (ac);
-        gtk_list_store_set (store, &iter, 0, display ? display : "", -1);
-        g_free (display);
+	/* Fill in the tree store, replacing any rows already present */
+	valid = gtk_tree_model_get_iter_first (model, &iter);
+	for ( ; acl; acl = g_list_next (acl)) {
+    
+		ac = (GnomeKeyringAccessControl*)acl->data;
+		g_return_if_fail (ac);
+        
+		if (!valid)
+			gtk_list_store_append (store, &iter);
+
+		display = gnome_keyring_item_ac_get_display_name (ac);
+		gtk_list_store_set (store, &iter, 
+		                    APPS_NAME, display ? display : "", 
+		                    APPS_ACCESS, ac,
+		                    -1);
+		g_free (display);
         
-        if (valid)
-            valid = gtk_tree_model_iter_next (model, &iter);
-    }
+		if (valid)
+			valid = gtk_tree_model_iter_next (model, &iter);
+	}
     
-    /* Remove all the remaining rows */
-    while (valid)
-        valid = gtk_list_store_remove (store, &iter);
+	/* Remove all the remaining rows */
+	while (valid)
+		valid = gtk_list_store_remove (store, &iter);
         
-    update_application_details (swidget);
+	update_application_details (swidget);
 }
 
 static void 
@@ -701,18 +772,6 @@
     setup_details (swidget);
     setup_application (swidget);
     
-    widget = seahorse_widget_get_widget (swidget, "password-expander");
-    g_return_if_fail (widget);
-    g_signal_connect_after (widget, "activate", G_CALLBACK (password_expander_activate), swidget);
-
-    glade_xml_signal_connect_data (swidget->xml, "show_password_toggled", 
-                                   G_CALLBACK (show_password_toggled), swidget);
-
-    widget = seahorse_widget_get_widget (swidget, "description-field");
-    g_return_if_fail (widget != NULL);
-    g_signal_connect (widget, "activate", G_CALLBACK (description_activate), swidget);
-    g_signal_connect (widget, "focus-out-event", G_CALLBACK (description_focus_out), swidget);
-
     glade_xml_signal_connect_data (swidget->xml, "application_access_toggled", 
                                    G_CALLBACK (application_access_toggled), swidget);
 

Modified: trunk/gkr/seahorse-gkr-item.c
==============================================================================
--- trunk/gkr/seahorse-gkr-item.c	(original)
+++ trunk/gkr/seahorse-gkr-item.c	Sat Nov 29 23:46:10 2008
@@ -47,19 +47,200 @@
 
 enum {
     PROP_0,
+    PROP_KEYRING_NAME,
     PROP_ITEM_ID,
     PROP_ITEM_INFO,
     PROP_ITEM_ATTRIBUTES,
     PROP_ITEM_ACL,
+    PROP_HAS_SECRET,
     PROP_USE
 };
 
+struct _SeahorseGkrItemPrivate {
+	gchar *keyring_name;
+	guint32 item_id;
+	
+	gpointer req_info;
+	GnomeKeyringItemInfo *item_info;
+	
+	gpointer req_attrs;
+	GnomeKeyringAttributeList *item_attrs;
+	
+	gpointer req_acl;
+	GList *item_acl;
+	
+	gpointer req_secret;
+	gchar *item_secret;
+};
+
 G_DEFINE_TYPE (SeahorseGkrItem, seahorse_gkr_item, SEAHORSE_TYPE_OBJECT);
 
 /* -----------------------------------------------------------------------------
  * INTERNAL HELPERS
  */
 
+GType
+boxed_item_info_type (void)
+{
+	static GType type = 0;
+	if (!type)
+		type = g_boxed_type_register_static ("GnomeKeyringItemInfo", 
+		                                     (GBoxedCopyFunc)gnome_keyring_item_info_copy,
+		                                     (GBoxedFreeFunc)gnome_keyring_item_info_free);
+	return type;
+}
+
+GType
+boxed_attributes_type (void)
+{
+	static GType type = 0;
+	if (!type)
+		type = g_boxed_type_register_static ("GnomeKeyringAttributeList", 
+		                                     (GBoxedCopyFunc)gnome_keyring_attribute_list_copy,
+		                                     (GBoxedFreeFunc)gnome_keyring_attribute_list_free);
+	return type;
+}
+
+GType
+boxed_acl_type (void)
+{
+	static GType type = 0;
+	if (!type)
+		type = g_boxed_type_register_static ("GnomeKeyringAcl", 
+		                                     (GBoxedCopyFunc)gnome_keyring_acl_copy,
+		                                     (GBoxedFreeFunc)gnome_keyring_acl_free);
+	return type;
+}
+
+static gboolean 
+received_result (SeahorseGkrItem *self, GnomeKeyringResult result)
+{
+	if (result == GNOME_KEYRING_RESULT_CANCELLED)
+		return FALSE;
+	
+	if (result == GNOME_KEYRING_RESULT_OK)
+		return TRUE;
+
+	/* TODO: Implement so that we can display an error icon, along with some text */
+	g_message ("failed to retrieve item %d from keyring %s: %s",
+	           self->pv->item_id, self->pv->keyring_name, 
+	           gnome_keyring_result_to_message (result));
+	return FALSE;
+}
+
+static void
+received_item_info (GnomeKeyringResult result, GnomeKeyringItemInfo *info, gpointer data)
+{
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (data);
+	self->pv->req_info = NULL;
+	if (received_result (self, result))
+		seahorse_gkr_item_set_info (self, info);
+}
+
+static gboolean
+require_item_info (SeahorseGkrItem *self)
+{
+	if (self->pv->item_info)
+		return TRUE;
+	
+	/* Already in progress */
+	if (!self->pv->req_info) {
+		g_object_ref (self);
+		self->pv->req_info = gnome_keyring_item_get_info_full (self->pv->keyring_name,
+		                                                       self->pv->item_id,
+		                                                       GNOME_KEYRING_ITEM_INFO_BASICS,
+		                                                       received_item_info,
+		                                                       self, g_object_unref);
+	}
+	
+	return self->pv->item_info != NULL;
+}
+
+static void
+received_item_secret (GnomeKeyringResult result, GnomeKeyringItemInfo *info, gpointer data)
+{
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (data);
+	self->pv->req_secret = NULL;
+	if (received_result (self, result)) {
+		g_free (self->pv->item_secret);
+		WITH_SECURE_MEM (self->pv->item_secret = gnome_keyring_item_info_get_secret (info));
+		g_object_notify (G_OBJECT (self), "has-secret");
+	}
+}
+
+static gboolean
+require_item_secret (SeahorseGkrItem *self)
+{
+	if (self->pv->item_secret)
+		return TRUE;
+	
+	/* Already in progress */
+	if (!self->pv->req_secret) {
+		g_object_ref (self);
+		self->pv->req_secret = gnome_keyring_item_get_info_full (self->pv->keyring_name,
+		                                                         self->pv->item_id,
+		                                                         GNOME_KEYRING_ITEM_INFO_SECRET,
+		                                                         received_item_secret,
+		                                                         self, g_object_unref);
+	}
+	
+	return self->pv->item_secret != NULL;
+}
+
+static void
+received_item_attrs (GnomeKeyringResult result, GnomeKeyringAttributeList *attrs, gpointer data)
+{
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (data);
+	self->pv->req_attrs = NULL;
+	if (received_result (self, result))
+		seahorse_gkr_item_set_attributes (self, attrs);
+}
+
+static gboolean
+require_item_attrs (SeahorseGkrItem *self)
+{
+	if (self->pv->item_attrs)
+		return TRUE;
+	
+	/* Already in progress */
+	if (!self->pv->req_attrs) {
+		g_object_ref (self);
+		self->pv->req_attrs = gnome_keyring_item_get_attributes (self->pv->keyring_name,
+		                                                         self->pv->item_id,
+		                                                         received_item_attrs,
+		                                                         self, g_object_unref);
+	}
+	
+	return self->pv->item_attrs != NULL;
+}
+
+static void
+received_item_acl (GnomeKeyringResult result, GList *acl, gpointer data)
+{
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (data);
+	self->pv->req_acl = NULL;
+	if (received_result (self, result))
+		seahorse_gkr_item_set_acl (self, acl);
+}
+
+static gboolean
+require_item_acl (SeahorseGkrItem *self)
+{
+	if (self->pv->item_acl)
+		return TRUE;
+	
+	/* Already in progress */
+	if (!self->pv->req_acl) {
+		g_object_ref (self);
+		self->pv->req_acl = gnome_keyring_item_get_acl (self->pv->keyring_name,
+		                                                self->pv->item_id,
+		                                                received_item_acl,
+		                                                self, g_object_unref);
+	}
+	
+	return self->pv->item_acl != NULL;
+}
+
 static guint32
 find_attribute_int (GnomeKeyringAttributeList *attrs, const gchar *name)
 {
@@ -80,360 +261,422 @@
 
 
 static gboolean
-is_network_item (SeahorseGkrItem *git, const gchar *match)
+is_network_item (SeahorseGkrItem *self, const gchar *match)
 {
-    const gchar *protocol;
-    if(gnome_keyring_item_info_get_type (git->info) != GNOME_KEYRING_ITEM_NETWORK_PASSWORD)
-        return FALSE;
+	const gchar *protocol;
+	
+	if (!require_item_info (self))
+		return FALSE;
+	
+	if (gnome_keyring_item_info_get_type (self->pv->item_info) != GNOME_KEYRING_ITEM_NETWORK_PASSWORD)
+		return FALSE;
     
-    if (!match)
-        return TRUE;
+	if (!match)
+		return TRUE;
     
-    protocol = seahorse_gkr_item_get_attribute (git, "protocol");
-    return protocol && g_ascii_strncasecmp (protocol, match, strlen (match)) == 0;
+	protocol = seahorse_gkr_item_get_attribute (self, "protocol");
+	return protocol && g_ascii_strncasecmp (protocol, match, strlen (match)) == 0;
 }
 
 static gboolean 
-is_custom_display_name (SeahorseGkrItem *git, const gchar *display)
+is_custom_display_name (SeahorseGkrItem *self, const gchar *display)
 {
-    const gchar *user;
-    const gchar *server;
-    const gchar *object;
-    guint32 port;
-    GString *generated;
-    gboolean ret;
-    
-    if (gnome_keyring_item_info_get_type (git->info) != GNOME_KEYRING_ITEM_NETWORK_PASSWORD)
-        return TRUE;
-    
-    if (!git->attributes || !display)
-        return TRUE;
-    
-    /* 
-     * For network passwords gnome-keyring generates in a funky looking display 
-     * name that's generated from login credentials. We simulate that generating 
-     * here and return FALSE if it matches. This allows us to display user 
-     * customized display names and ignore the generated ones.
-     */
-    
-    user = seahorse_gkr_item_get_attribute (git, "user");
-    server = seahorse_gkr_item_get_attribute (git, "server");
-    object = seahorse_gkr_item_get_attribute (git, "object");
-    port = find_attribute_int (git->attributes, "port");
-    
-    if (!server)
-        return TRUE;
-    
-    generated = g_string_new (NULL);
-    if (user != NULL)
-        g_string_append_printf (generated, "%s@", user);
-    g_string_append (generated, server);
-    if (port != 0)
-        g_string_append_printf (generated, ":%d", port);
-    if (object != NULL)
-        g_string_append_printf (generated, "/%s", object);
+	const gchar *user;
+	const gchar *server;
+	const gchar *object;
+	guint32 port;
+	GString *generated;
+	gboolean ret;
+	
+	if (require_item_info (self) && gnome_keyring_item_info_get_type (self->pv->item_info) != 
+					    GNOME_KEYRING_ITEM_NETWORK_PASSWORD)
+		return TRUE;
+    
+	if (!require_item_attrs (self) || !display)
+		return TRUE;
+    
+	/* 
+	 * For network passwords gnome-keyring generates in a funky looking display 
+	 * name that's generated from login credentials. We simulate that generating 
+	 * here and return FALSE if it matches. This allows us to display user 
+	 * customized display names and ignore the generated ones.
+	 */
+    
+	user = seahorse_gkr_item_get_attribute (self, "user");
+	server = seahorse_gkr_item_get_attribute (self, "server");
+	object = seahorse_gkr_item_get_attribute (self, "object");
+	port = find_attribute_int (self->pv->item_attrs, "port");
+    
+	if (!server)
+		return TRUE;
+    
+	generated = g_string_new (NULL);
+	if (user != NULL)
+		g_string_append_printf (generated, "%s@", user);
+	g_string_append (generated, server);
+	if (port != 0)
+		g_string_append_printf (generated, ":%d", port);
+	if (object != NULL)
+		g_string_append_printf (generated, "/%s", object);
 
-    ret = strcmp (display, generated->str) != 0;
-    g_string_free (generated, TRUE);
+	ret = strcmp (display, generated->str) != 0;
+	g_string_free (generated, TRUE);
     
-    return ret;
+	return ret;
 }
 
 static gchar*
-calc_display_name (SeahorseGkrItem *git, gboolean always)
+calc_display_name (SeahorseGkrItem *self, gboolean always)
 {
-    const gchar *val;
-    gchar *display;
+	const gchar *val;
+	gchar *display;
     
-    display = gnome_keyring_item_info_get_display_name (git->info);
+	if (!require_item_info (self))
+		return NULL;
+	
+	display = gnome_keyring_item_info_get_display_name (self->pv->item_info);
     
-    /* If it's customized by the application or user then display that */
-    if (is_custom_display_name (git, display))
-        return display;
+	/* If it's customized by the application or user then display that */
+	if (is_custom_display_name (self, display))
+		return display;
     
-    /* If it's a network item ... */
-    if (gnome_keyring_item_info_get_type (git->info) == GNOME_KEYRING_ITEM_NETWORK_PASSWORD) {
+	/* If it's a network item ... */
+	if (gnome_keyring_item_info_get_type (self->pv->item_info) == GNOME_KEYRING_ITEM_NETWORK_PASSWORD) {
         
-        /* HTTP usually has a the realm as the "object" display that */
-        if (is_network_item (git, "http") && git->attributes) {
-            val = seahorse_gkr_item_get_attribute (git, "object");
-            if (val && val[0]) {
-                g_free (display);
-                return g_strdup (val);
-            }
-        }
+		/* HTTP usually has a the realm as the "object" display that */
+		if (is_network_item (self, "http") && self->pv->item_attrs) {
+			val = seahorse_gkr_item_get_attribute (self, "object");
+			if (val && val[0]) {
+				g_free (display);
+				return g_strdup (val);
+			}
+		}
         
-        /* Display the server name as a last resort */
-        if (always) {
-            val = seahorse_gkr_item_get_attribute (git, "server");
-            if (val && val[0]) {
-                g_free (display);
-                return g_strdup (val);
-            }
-        }
-    }
+		/* Display the server name as a last resort */
+		if (always) {
+			val = seahorse_gkr_item_get_attribute (self, "server");
+			if (val && val[0]) {
+				g_free (display);
+				return g_strdup (val);
+			}
+		}
+	}
     
-    return always ? display : NULL;
+	return always ? display : NULL;
 }
 
 static gchar*
-calc_network_item_markup (SeahorseGkrItem *git)
+calc_network_item_markup (SeahorseGkrItem *self)
 {
-    const gchar *object;
-    const gchar *user;
-    const gchar *protocol;
-    const gchar *server;
-    
-    gchar *uri = NULL;
-    gchar *display = NULL;
-    gchar *ret;
-    
-    server = seahorse_gkr_item_get_attribute (git, "server");
-    protocol = seahorse_gkr_item_get_attribute (git, "protocol");
-    object = seahorse_gkr_item_get_attribute (git, "object");
-    user = seahorse_gkr_item_get_attribute (git, "user");
-
-    if (!protocol)
-        return NULL;
-    
-    /* The object in HTTP often isn't a path at all */
-    if (is_network_item (git, "http"))
-        object = NULL;
-    
-    display = calc_display_name (git, TRUE);
-    
-    if (server && protocol) {
-        uri = g_strdup_printf ("  %s://%s%s%s/%s", 
-                               protocol, 
-                               user ? user : "",
-                               user ? "@" : "",
-                               server,
-                               object ? object : "");
-    }
+	const gchar *object;
+	const gchar *user;
+	const gchar *protocol;
+	const gchar *server;
+    
+	gchar *uri = NULL;
+	gchar *display = NULL;
+	gchar *ret;
+    
+	server = seahorse_gkr_item_get_attribute (self, "server");
+	protocol = seahorse_gkr_item_get_attribute (self, "protocol");
+	object = seahorse_gkr_item_get_attribute (self, "object");
+	user = seahorse_gkr_item_get_attribute (self, "user");
+
+	if (!protocol)
+		return NULL;
+    
+	/* The object in HTTP often isn't a path at all */
+	if (is_network_item (self, "http"))
+		object = NULL;
+    
+	display = calc_display_name (self, TRUE);
+    
+	if (server && protocol) {
+		uri = g_strdup_printf ("  %s://%s%s%s/%s", 
+		                       protocol, 
+		                       user ? user : "",
+		                       user ? "@" : "",
+		                       server,
+		                       object ? object : "");
+	}
     
-    ret = g_markup_printf_escaped ("%s<span foreground='#555555' size='small' rise='0'>%s</span>",
-                                   display, uri ? uri : "");
-    g_free (display);
-    g_free (uri);
+	ret = g_markup_printf_escaped ("%s<span foreground='#555555' size='small' rise='0'>%s</span>",
+	                               display, uri ? uri : "");
+	g_free (display);
+	g_free (uri);
     
-    return ret;
+	return ret;
 }
 
 static gchar* 
-calc_name_markup (SeahorseGkrItem *git)
+calc_name_markup (SeahorseGkrItem *self)
 {
-    gchar *t, *markup = NULL;
-    
-    g_return_val_if_fail (git->info != NULL, NULL);
-    
-    /* Only do our special markup for network passwords */
-    if (is_network_item (git, NULL))
-        markup = calc_network_item_markup (git);
+	gchar *name, *markup = NULL;
+	
+	if (!require_item_info (self))
+		return NULL;
     
-    if (!markup) {
-        t = calc_display_name (git, TRUE);
-        markup = g_markup_escape_text (t, -1);
-        g_free (t);
-    }
+	/* Only do our special markup for network passwords */
+	if (is_network_item (self, NULL))
+        markup = calc_network_item_markup (self);
+    
+	if (!markup) {
+		name = calc_display_name (self, TRUE);
+		markup = g_markup_escape_text (name, -1);
+		g_free (name);
+	}
+
+	return markup;
+}
 
-    return markup;
+static gint
+calc_item_type (SeahorseGkrItem *self)
+{
+	if (!require_item_info (self))
+		return -1;
+	return gnome_keyring_item_info_get_type (self->pv->item_info);
 }
 
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
 static void
-changed_key (SeahorseGkrItem *git)
+seahorse_gkr_item_realize (SeahorseObject *obj)
 {
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (obj);
 	const gchar *description;
-	gboolean loaded;
-	gchar *secret;
 	gchar *display;
 	gchar *markup;
 	gchar *identifier;
 	const gchar *icon;
 
-	if (!git->info) {
-        
-		g_object_set (git,
-		              "id", 0,
-		              "label", "",
-		              "icon", NULL,
-		              "markup", "",
-		              "identifier", "",
-		              "description", _("Invalid"),
-		              "flags", SEAHORSE_FLAG_DISABLED,
-		              NULL);
-		return;
-	}
-
-	WITH_SECURE_MEM ((secret = gnome_keyring_item_info_get_secret (git->info)));
-	loaded = (secret == NULL);
-	g_free (secret);
-	
-	if (is_network_item (git, "http")) 
+	if (is_network_item (self, "http")) 
 		description = _("Web Password");
-	else if (is_network_item (git, NULL)) 
+	else if (is_network_item (self, NULL)) 
 		description = _("Network Password");
 	else
 		description = _("Password");
 
-	display = calc_display_name (git, TRUE);
-	markup = calc_name_markup(git);
-	identifier = g_strdup_printf ("%u", git->item_id);
+	display = calc_display_name (self, TRUE);
+	markup = calc_name_markup(self);
+	identifier = g_strdup_printf ("%u", self->pv->item_id);
 
 	/* We use a pointer so we don't copy the string every time */
-	switch (git->info ? gnome_keyring_item_info_get_type (git->info) : -1)
+	switch (calc_item_type (self))
 	{
 	case GNOME_KEYRING_ITEM_GENERIC_SECRET:
 		icon = GNOME_STOCK_AUTHENTICATION;
 		break;
 	case GNOME_KEYRING_ITEM_NETWORK_PASSWORD:
-		icon = is_network_item (git, "http") ? SEAHORSE_THEMED_WEBBROWSER : GTK_STOCK_NETWORK;
+		icon = is_network_item (self, "http") ? SEAHORSE_THEMED_WEBBROWSER : GTK_STOCK_NETWORK;
 		break;
 	case GNOME_KEYRING_ITEM_NOTE:
 		icon = GNOME_STOCK_BOOK_OPEN;
 		break;
 	default:
-        	icon = GNOME_STOCK_BLANK;
-        	break;
-        }
-	
-	g_object_set (git,
-	              "id", seahorse_gkr_item_get_cannonical (git->item_id),
-	              "label", display,
-	              "icon", icon,
-	              "markup", markup,
-	              "identifier", identifier,
-	              "description", description,
-	              "flags", 0,
-	              NULL);
+		icon = GNOME_STOCK_BLANK;
+		break;
+	}
+	
+	g_object_set (self,
+		      "label", display,
+		      "icon", icon,
+		      "markup", markup,
+		      "identifier", identifier,
+		      "description", description,
+		      "flags", 0,
+		      NULL);
 	
 	g_free (display);
 	g_free (markup);
 	g_free (identifier);
+	
+	g_object_notify (G_OBJECT (self), "has-secret");
+	g_object_notify (G_OBJECT (self), "use");
+	
+	SEAHORSE_OBJECT_CLASS (seahorse_gkr_item_parent_class)->realize (obj);
 }
 
-/* -----------------------------------------------------------------------------
- * OBJECT 
- */
+static void
+seahorse_gkr_item_flush (SeahorseObject *obj)
+{
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (obj);
+
+	if (self->pv->item_info)
+		gnome_keyring_item_info_free (self->pv->item_info);
+	self->pv->item_info = NULL;
+	g_assert (self->pv->req_info == NULL);
+    
+	if (self->pv->item_attrs)
+		gnome_keyring_attribute_list_free (self->pv->item_attrs);
+	self->pv->item_attrs = NULL;
+	g_assert (self->pv->req_attrs == NULL);
+    
+	gnome_keyring_acl_free (self->pv->item_acl);
+	self->pv->item_acl = NULL;
+	g_assert (self->pv->req_acl == NULL);
+	
+	g_free (self->pv->item_secret);
+	self->pv->item_secret = NULL;
+	g_assert (self->pv->req_secret == NULL);
+	
+	SEAHORSE_OBJECT_CLASS (seahorse_gkr_item_parent_class)->flush (obj);
+}
 
 static void
-seahorse_gkr_item_init (SeahorseGkrItem *git)
+seahorse_gkr_item_init (SeahorseGkrItem *self)
 {
-	g_object_set (git, 
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_GKR_ITEM, SeahorseGkrItemPrivate);
+	g_object_set (self, 
 	              "usage", SEAHORSE_USAGE_CREDENTIALS,
 	              NULL);
 }
 
+static GObject* 
+seahorse_gkr_item_constructor (GType type, guint n_props, GObjectConstructParam *props) 
+{
+	GObject *obj = G_OBJECT_CLASS (seahorse_gkr_item_parent_class)->constructor (type, n_props, props);
+	SeahorseGkrItem *self = NULL;
+	GQuark id;
+	
+	if (obj) {
+		self = SEAHORSE_GKR_ITEM (obj);
+		
+		id = seahorse_gkr_item_get_cannonical (self->pv->keyring_name, 
+		                                        self->pv->item_id);
+		g_object_set (self, "id", id, 
+		              "usage", SEAHORSE_USAGE_CREDENTIALS, NULL); 
+	}
+	
+	return obj;
+}
+
 static void
 seahorse_gkr_item_get_property (GObject *object, guint prop_id,
                                 GValue *value, GParamSpec *pspec)
 {
-    SeahorseGkrItem *git = SEAHORSE_GKR_ITEM (object);
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (object);
     
-    switch (prop_id) {
-    case PROP_ITEM_ID:
-        g_value_set_uint (value, git->item_id);
-        break;
-    case PROP_ITEM_INFO:
-        g_value_set_pointer (value, git->info);
-        break;
-    case PROP_ITEM_ATTRIBUTES:
-        g_value_set_pointer (value, git->attributes);
-        break;
-    case PROP_ITEM_ACL:
-    	g_value_set_pointer (value, git->acl);
-    	break;
-    case PROP_USE:
-	g_value_set_uint (value, seahorse_gkr_item_get_use (git));
-	break;
-    }
+	switch (prop_id) {
+	case PROP_KEYRING_NAME:
+		g_value_set_string (value, seahorse_gkr_item_get_keyring_name (self));
+		break;
+	case PROP_ITEM_ID:
+		g_value_set_uint (value, seahorse_gkr_item_get_item_id (self));
+		break;
+	case PROP_ITEM_INFO:
+		g_value_set_boxed (value, seahorse_gkr_item_get_info (self));
+		break;
+	case PROP_ITEM_ATTRIBUTES:
+		g_value_set_boxed (value, seahorse_gkr_item_get_attributes (self));
+		break;
+	case PROP_ITEM_ACL:
+		g_value_set_boxed (value, seahorse_gkr_item_get_acl (self));
+		break;
+	case PROP_HAS_SECRET:
+		g_value_set_boolean (value, self->pv->item_secret != NULL);
+		break;
+	case PROP_USE:
+		g_value_set_uint (value, seahorse_gkr_item_get_use (self));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;		
+	}
 }
 
 static void
 seahorse_gkr_item_set_property (GObject *object, guint prop_id, const GValue *value, 
                                 GParamSpec *pspec)
 {
-    SeahorseGkrItem *git = SEAHORSE_GKR_ITEM (object);
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (object);
     
-    switch (prop_id) {
-    case PROP_ITEM_ID:
-        git->item_id = g_value_get_uint (value);
-        break;
-    case PROP_ITEM_INFO:
-        if (git->info != g_value_get_pointer (value)) {
-            if (git->info)
-                gnome_keyring_item_info_free (git->info);
-            git->info = g_value_get_pointer (value);
-            changed_key (git);
-        }
-        break;
-    case PROP_ITEM_ATTRIBUTES:
-        if (git->attributes != g_value_get_pointer (value)) {
-            if (git->attributes)
-                gnome_keyring_attribute_list_free (git->attributes);
-            git->attributes = g_value_get_pointer (value);
-            changed_key (git);
-        }
-        break;
-    case PROP_ITEM_ACL:
-        if (git->acl != g_value_get_pointer (value)) {
-            gnome_keyring_acl_free (git->acl);
-            git->acl = g_value_get_pointer (value);
-            changed_key (git);
-        }
-        break;
-    }
+	switch (prop_id) {
+	case PROP_KEYRING_NAME:
+		g_return_if_fail (self->pv->keyring_name == NULL);
+		self->pv->keyring_name = g_value_dup_string (value);
+		break;
+	case PROP_ITEM_ID:
+		g_return_if_fail (self->pv->item_id == 0);
+		self->pv->item_id = g_value_get_uint (value);
+		break;
+	case PROP_ITEM_INFO:
+		seahorse_gkr_item_set_info (self, g_value_get_boxed (value));
+		break;
+	case PROP_ITEM_ATTRIBUTES:
+		seahorse_gkr_item_set_attributes (self, g_value_get_boxed (value));
+		break;
+	case PROP_ITEM_ACL:
+		seahorse_gkr_item_set_acl (self, g_value_get_boxed (value));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
 }
 
 static void
-seahorse_gkr_item_object_finalize (GObject *gobject)
+seahorse_gkr_item_finalize (GObject *gobject)
 {
-    SeahorseGkrItem *git = SEAHORSE_GKR_ITEM (gobject);
-    
-    if (git->info)
-        gnome_keyring_item_info_free (git->info);
-    git->info = NULL;
-    
-    if (git->attributes)
-        gnome_keyring_attribute_list_free (git->attributes);
-    git->attributes = NULL;
+	SeahorseGkrItem *self = SEAHORSE_GKR_ITEM (gobject);
+	
+	g_free (self->pv->keyring_name);
+	self->pv->keyring_name = NULL;
     
-    gnome_keyring_acl_free (git->acl);
-    git->acl = NULL;
+	g_object_freeze_notify (gobject);
+	seahorse_gkr_item_flush (SEAHORSE_OBJECT (self));
     
-    G_OBJECT_CLASS (seahorse_gkr_item_parent_class)->finalize (gobject);
+	G_OBJECT_CLASS (seahorse_gkr_item_parent_class)->finalize (gobject);
 }
 
 static void
 seahorse_gkr_item_class_init (SeahorseGkrItemClass *klass)
 {
-    GObjectClass *gobject_class;
+	GObjectClass *gobject_class;
+	SeahorseObjectClass *seahorse_class;
     
-    seahorse_gkr_item_parent_class = g_type_class_peek_parent (klass);
-    gobject_class = G_OBJECT_CLASS (klass);
+	seahorse_gkr_item_parent_class = g_type_class_peek_parent (klass);
+	gobject_class = G_OBJECT_CLASS (klass);
+	
+	gobject_class->constructor = seahorse_gkr_item_constructor;
+	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;
+	
+	seahorse_class = SEAHORSE_OBJECT_CLASS (klass);
+	seahorse_class->realize = seahorse_gkr_item_realize;
+	seahorse_class->flush = seahorse_gkr_item_flush;
+	
+	g_type_class_add_private (klass, sizeof (SeahorseGkrItemPrivate));
     
-    gobject_class->finalize = seahorse_gkr_item_object_finalize;
-    gobject_class->set_property = seahorse_gkr_item_set_property;
-    gobject_class->get_property = seahorse_gkr_item_get_property;
-    
-    g_object_class_install_property (gobject_class, PROP_ITEM_ID,
-        g_param_spec_uint ("item-id", "Item ID", "GNOME Keyring Item ID", 
-                           0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-    g_object_class_install_property (gobject_class, PROP_ITEM_INFO,
-        g_param_spec_pointer ("item-info", "Item Info", "GNOME Keyring Item Info",
-                              G_PARAM_READWRITE));
+	g_object_class_install_property (gobject_class, PROP_KEYRING_NAME,
+	        g_param_spec_string("keyring-name", "Keyring Name", "Keyring this item is in", 
+	                            "", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (gobject_class, PROP_ITEM_ID,
+	        g_param_spec_uint ("item-id", "Item ID", "GNOME Keyring Item ID", 
+	                           0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (gobject_class, PROP_ITEM_INFO,
+                g_param_spec_boxed ("item-info", "Item Info", "GNOME Keyring Item Info",
+                                    boxed_item_info_type (),  G_PARAM_READWRITE));
                               
-    g_object_class_install_property (gobject_class, PROP_ITEM_ATTRIBUTES,
-        g_param_spec_pointer ("item-attributes", "Item Attributes", "GNOME Keyring Item Attributes",
-                              G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class, PROP_ITEM_ACL,
-        g_param_spec_pointer ("item-acl", "Item ACL", "GNOME Keyring Item ACL",
-                              G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class, PROP_USE,
-        g_param_spec_uint ("use", "Use", "Item is used for", 
-                           0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (gobject_class, PROP_ITEM_ATTRIBUTES,
+                g_param_spec_boxed ("item-attributes", "Item Attributes", "GNOME Keyring Item Attributes",
+                                    boxed_attributes_type (), G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_ITEM_ACL,
+                g_param_spec_boxed ("item-acl", "Item ACL", "GNOME Keyring Item ACL",
+                                    boxed_acl_type (),  G_PARAM_READWRITE));
+
+	g_object_class_install_property (gobject_class, PROP_USE,
+	        g_param_spec_uint ("use", "Use", "Item is used for", 
+	                           0, G_MAXUINT, 0, G_PARAM_READABLE));
+
+	g_object_class_install_property (gobject_class, PROP_HAS_SECRET,
+	        g_param_spec_boolean ("has-secret", "Has Secret", "Secret has been loaded", 
+	                              FALSE, G_PARAM_READABLE));
 }
 
 /* -----------------------------------------------------------------------------
@@ -441,70 +684,115 @@
  */
 
 SeahorseGkrItem* 
-seahorse_gkr_item_new (SeahorseSource *sksrc, guint32 item_id, GnomeKeyringItemInfo *info, 
-                       GnomeKeyringAttributeList *attributes, GList *acl)
+seahorse_gkr_item_new (SeahorseSource *source, const gchar *keyring_name, guint32 item_id)
 {
-    SeahorseGkrItem *git;
-    git = g_object_new (SEAHORSE_TYPE_GKR_ITEM, "source", sksrc, 
-                        "item-id", item_id, "item-info", info, 
-                        "item-attributes", attributes, "item-acl", acl, NULL);
-    return git;
+	return g_object_new (SEAHORSE_TYPE_GKR_ITEM, "source", source, 
+	                     "item-id", item_id, "keyring-name", keyring_name, NULL);
 }
 
-gchar*
-seahorse_gkr_item_get_description  (SeahorseGkrItem *git)
+guint32
+seahorse_gkr_item_get_item_id (SeahorseGkrItem *self)
 {
-	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (git), NULL);
-	return calc_display_name (git, FALSE);
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), 0);
+	return self->pv->item_id;
 }
 
 const gchar*
-seahorse_gkr_item_get_attribute (SeahorseGkrItem *git, const gchar *name)
+seahorse_gkr_item_get_keyring_name (SeahorseGkrItem *self)
 {
-    g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (git), NULL);
-    if (!git->attributes)
-        return NULL;
-    return seahorse_gkr_find_string_attribute (git->attributes, name);
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), NULL);
+	return self->pv->keyring_name;
 }
 
-SeahorseGkrUse
-seahorse_gkr_item_get_use (SeahorseGkrItem *git)
+GnomeKeyringItemInfo*
+seahorse_gkr_item_get_info (SeahorseGkrItem *self)
 {
-    const gchar *val;
-    
-    /* Network passwords */
-    if (gnome_keyring_item_info_get_type (git->info) == GNOME_KEYRING_ITEM_NETWORK_PASSWORD) {
-        if (is_network_item (git, "http"))
-            return SEAHORSE_GKR_USE_WEB;
-        return SEAHORSE_GKR_USE_NETWORK;
-    }
-    
-    if (git->attributes) {
-        val = seahorse_gkr_item_get_attribute (git, "seahorse-key-type");
-        if (val) {
-#ifdef WITH_PGP
-        	if (strcmp (val, SEAHORSE_PGP_TYPE_STR) == 0)
-        		return SEAHORSE_GKR_USE_PGP;
-#endif
-#ifdef WITH_SSH
-        	if (strcmp (val, SEAHORSE_SSH_TYPE_STR) == 0)
-        		return SEAHORSE_GKR_USE_SSH;
-#endif
-        }
-    }
-    
-    return SEAHORSE_GKR_USE_OTHER;
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), NULL);
+	require_item_info (self);
+	return self->pv->item_info;
 }
 
-GQuark
-seahorse_gkr_item_get_cannonical (guint32 item_id)
+void
+seahorse_gkr_item_set_info (SeahorseGkrItem *self, GnomeKeyringItemInfo* info)
 {
-    #define BUF_LEN (G_N_ELEMENTS (SEAHORSE_GKR_STR) + 16)
-    gchar buf[BUF_LEN];
-    
-    snprintf(buf, BUF_LEN - 1, "%s:%08X", SEAHORSE_GKR_STR, item_id);
-    buf[BUF_LEN - 1] = 0;
-    return g_quark_from_string (buf);
+	GObject *obj;
+	
+	g_return_if_fail (SEAHORSE_IS_GKR_ITEM (self));
+	
+	if (self->pv->item_info)
+		gnome_keyring_item_info_free (self->pv->item_info);
+	if (info)
+		self->pv->item_info = gnome_keyring_item_info_copy (info);
+	else
+		self->pv->item_info = NULL;
+	
+	obj = G_OBJECT (self);
+	g_object_freeze_notify (obj);
+	seahorse_gkr_item_realize (SEAHORSE_OBJECT (self));
+	g_object_notify (obj, "item-info");
+	g_object_notify (obj, "use");
+	
+	/* Get the secret out of the item info, if not already loaded */
+	if (!self->pv->item_secret && self->pv->item_info && !self->pv->req_secret) {
+		WITH_SECURE_MEM (self->pv->item_secret = gnome_keyring_item_info_get_secret (self->pv->item_info));
+		g_object_notify (obj, "has-secret");
+	}
+		
+	g_object_thaw_notify (obj);
+}
+
+gboolean
+seahorse_gkr_item_has_secret (SeahorseGkrItem *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), FALSE);
+	return self->pv->item_secret != NULL;
+}
+
+const gchar*
+seahorse_gkr_item_get_secret (SeahorseGkrItem *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), NULL);
+	require_item_secret (self);
+	return self->pv->item_secret;
+}
+
+GnomeKeyringAttributeList*
+seahorse_gkr_item_get_attributes (SeahorseGkrItem *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), NULL);
+	require_item_attrs (self);
+	return self->pv->item_attrs;
+}
+
+void
+seahorse_gkr_item_set_attributes (SeahorseGkrItem *self, GnomeKeyringAttributeList* attrs)
+{
+	GObject *obj;
+	
+	g_return_if_fail (SEAHORSE_IS_GKR_ITEM (self));
+	
+	if (self->pv->item_attrs)
+		gnome_keyring_attribute_list_free (self->pv->item_attrs);
+	if (attrs)
+		self->pv->item_attrs = gnome_keyring_attribute_list_copy (attrs);
+	else
+		self->pv->item_attrs = NULL;
+	
+	obj = G_OBJECT (self);
+	g_object_freeze_notify (obj);
+	seahorse_gkr_item_realize (SEAHORSE_OBJECT (self));
+	g_object_notify (obj, "item-attributes");
+	g_object_notify (obj, "use");
+	g_object_thaw_notify (obj);
+}
+
+const gchar*
+seahorse_gkr_item_get_attribute (SeahorseGkrItem *self, const gchar *name)
+{
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), NULL);
+	if (!require_item_attrs (self))
+		return NULL;
+	return seahorse_gkr_find_string_attribute (self->pv->item_attrs, name);
 }
 
 const gchar*
@@ -522,5 +810,74 @@
 			return attr->value.string;
 	}
 	    
-	return NULL;
+	return NULL;	
+}
+
+GList*
+seahorse_gkr_item_get_acl (SeahorseGkrItem *self)
+{
+	g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (self), NULL);
+	require_item_acl (self);
+	return self->pv->item_acl;
+}
+
+void
+seahorse_gkr_item_set_acl (SeahorseGkrItem *self, GList* acl)
+{
+	GObject *obj;
+	
+	g_return_if_fail (SEAHORSE_IS_GKR_ITEM (self));
+	
+	if (self->pv->item_acl)
+		gnome_keyring_acl_free (self->pv->item_acl);
+	if (acl)
+		self->pv->item_acl = gnome_keyring_acl_copy (acl);
+	else
+		self->pv->item_acl = NULL;
+	
+	obj = G_OBJECT (self);
+	g_object_freeze_notify (obj);
+	seahorse_gkr_item_realize (SEAHORSE_OBJECT (self));
+	g_object_notify (obj, "item-acl");
+	g_object_thaw_notify (obj);
+}
+
+GQuark
+seahorse_gkr_item_get_cannonical (const gchar *keyring_name, guint32 item_id)
+{
+	gchar *buf = g_strdup_printf ("%s:%s-%08X", SEAHORSE_GKR_STR, keyring_name, item_id);
+	GQuark id = g_quark_from_string (buf);
+	g_free (buf);
+	return id;
+}
+
+SeahorseGkrUse
+seahorse_gkr_item_get_use (SeahorseGkrItem *self)
+{
+	const gchar *val;
+    
+	/* Network passwords */
+	if (require_item_info (self)) {
+		if (gnome_keyring_item_info_get_type (self->pv->item_info) == GNOME_KEYRING_ITEM_NETWORK_PASSWORD) {
+			if (is_network_item (self, "http"))
+				return SEAHORSE_GKR_USE_WEB;
+			return SEAHORSE_GKR_USE_NETWORK;
+		}
+	}
+    
+	if (require_item_attrs (self)) {
+		val = seahorse_gkr_item_get_attribute (self, "seahorse-key-type");
+		if (val) {
+#ifdef WITH_PGP
+			if (strcmp (val, SEAHORSE_PGP_TYPE_STR) == 0)
+				return SEAHORSE_GKR_USE_PGP;
+#endif
+#ifdef WITH_SSH
+			if (strcmp (val, SEAHORSE_SSH_TYPE_STR) == 0)
+				return SEAHORSE_GKR_USE_SSH;
+#endif
+		}
+	}
+    
+	return SEAHORSE_GKR_USE_OTHER;
 }

Modified: trunk/gkr/seahorse-gkr-item.h
==============================================================================
--- trunk/gkr/seahorse-gkr-item.h	(original)
+++ trunk/gkr/seahorse-gkr-item.h	Sat Nov 29 23:46:10 2008
@@ -49,38 +49,55 @@
 
 typedef struct _SeahorseGkrItem SeahorseGkrItem;
 typedef struct _SeahorseGkrItemClass SeahorseGkrItemClass;
+typedef struct _SeahorseGkrItemPrivate SeahorseGkrItemPrivate;
 
 struct _SeahorseGkrItem {
-    SeahorseObject              parent;
-
-    /*< public >*/
-    guint32                     item_id;
-    GnomeKeyringItemInfo        *info;
-    GnomeKeyringAttributeList   *attributes;
-    GList                       *acl;
+	SeahorseObject parent;
+	SeahorseGkrItemPrivate *pv;
 };
 
 struct _SeahorseGkrItemClass {
     SeahorseObjectClass         parent_class;
 };
 
-SeahorseGkrItem*        seahorse_gkr_item_new              (SeahorseSource *sksrc,
-                                                            guint32 item_id, 
-                                                            GnomeKeyringItemInfo *info,
-                                                            GnomeKeyringAttributeList *attributes,
-                                                            GList *acl);
+GType                        seahorse_gkr_item_get_type           (void);
+
+SeahorseGkrItem*             seahorse_gkr_item_new                (SeahorseSource *source,
+                                                                   const gchar *keyring_name,
+                                                                   guint32 item_id);
+
+guint32                      seahorse_gkr_item_get_item_id        (SeahorseGkrItem *self);
+
+const gchar*                 seahorse_gkr_item_get_keyring_name   (SeahorseGkrItem *self);
+
+GnomeKeyringItemInfo*        seahorse_gkr_item_get_info           (SeahorseGkrItem *self);
+
+void                         seahorse_gkr_item_set_info           (SeahorseGkrItem *self,
+                                                                   GnomeKeyringItemInfo* info);
+
+gboolean                     seahorse_gkr_item_has_secret         (SeahorseGkrItem *self);
+
+const gchar*                 seahorse_gkr_item_get_secret         (SeahorseGkrItem *self);
+
+GnomeKeyringAttributeList*   seahorse_gkr_item_get_attributes     (SeahorseGkrItem *self);
+
+void                         seahorse_gkr_item_set_attributes     (SeahorseGkrItem *self,
+                                                                   GnomeKeyringAttributeList* attrs);
 
-GType                   seahorse_gkr_item_get_type         (void);
+const gchar*                 seahorse_gkr_item_get_attribute      (SeahorseGkrItem *self, 
+                                                                   const gchar *name);
 
-GQuark                  seahorse_gkr_item_get_cannonical   (guint32 item_id);
+const gchar* 		     seahorse_gkr_find_string_attribute   (GnomeKeyringAttributeList *attrs, 
+             		                                           const gchar *name);
 
-gchar*                  seahorse_gkr_item_get_description  (SeahorseGkrItem *git);
+GList*                       seahorse_gkr_item_get_acl            (SeahorseGkrItem *self);
 
-const gchar*            seahorse_gkr_item_get_attribute    (SeahorseGkrItem *git, 
-                                                            const gchar *name);
+void                         seahorse_gkr_item_set_acl            (SeahorseGkrItem *self,
+                                                                   GList* acl);
 
-SeahorseGkrUse          seahorse_gkr_item_get_use          (SeahorseGkrItem *git);
+GQuark                       seahorse_gkr_item_get_cannonical     (const gchar *keyring_name, 
+                                                                   guint32 item_id);
 
-const gchar* 		seahorse_gkr_find_string_attribute (GnomeKeyringAttributeList *attrs, const gchar *name);
+SeahorseGkrUse               seahorse_gkr_item_get_use            (SeahorseGkrItem *self);
 
 #endif /* __SEAHORSE_GKR_ITEM_H__ */

Modified: trunk/gkr/seahorse-gkr-module.c
==============================================================================
--- trunk/gkr/seahorse-gkr-module.c	(original)
+++ trunk/gkr/seahorse-gkr-module.c	Sat Nov 29 23:46:10 2008
@@ -28,14 +28,25 @@
 
 #include "seahorse-context.h"
 
+#include <gnome-keyring.h>
+
 void
 seahorse_gkr_module_init (void)
 {
 	SeahorseSource *source;
+	GnomeKeyringResult result;
+	gchar *keyring;
 
-	/* Always have a default keyring source added */
-	source = g_object_new (SEAHORSE_TYPE_GKR_SOURCE, NULL);
-	seahorse_context_take_source (NULL, source);
+	/* Create a keyring for the default gnome keyring */
+	result = gnome_keyring_get_default_keyring_sync (&keyring);
+	if (result != GNOME_KEYRING_RESULT_OK) {
+		g_warning ("couldn't get default gnome-keyring keyring: %s",
+		           gnome_keyring_result_to_message (result));
+	} else {
+		source = SEAHORSE_SOURCE (seahorse_gkr_source_new (keyring));
+		g_free (keyring);
+		seahorse_context_take_source (NULL, source);
+	}
 
 	/* Let these classes register themselves */
 	g_type_class_unref (g_type_class_ref (SEAHORSE_TYPE_GKR_SOURCE));

Modified: trunk/gkr/seahorse-gkr-operation.c
==============================================================================
--- trunk/gkr/seahorse-gkr-operation.c	(original)
+++ trunk/gkr/seahorse-gkr-operation.c	Sat Nov 29 23:46:10 2008
@@ -54,7 +54,7 @@
 typedef struct _SeahorseGkrOperationPrivate {
     
     gpointer request;
-    GQuark keyid;
+    SeahorseObject *object;
     
 } SeahorseGkrOperationPrivate;
 
@@ -151,6 +151,10 @@
         g_object_unref (gop->gsrc);
     gop->gsrc = NULL;
     
+    if (pv->object)
+        g_object_unref (pv->object);
+    pv->object = NULL;
+    
     /* The above cancel should have stopped this */
     g_assert (pv->request == NULL);
     
@@ -243,14 +247,14 @@
 {
     SeahorseGkrOperationPrivate *pv;
 
+    pv = SEAHORSE_GKR_OPERATION_GET_PRIVATE (gop);
+    pv->request = NULL;
+
     if (!check_operation_result (gop, result))
         return;
     
-    pv = SEAHORSE_GKR_OPERATION_GET_PRIVATE (gop);
-
     /* When operation is successful reload the key */
-    g_return_if_fail (pv->keyid != 0);
-    seahorse_source_load_async (SEAHORSE_SOURCE (gop->gsrc), pv->keyid);
+    seahorse_object_refresh (SEAHORSE_OBJECT (pv->object));
 }
 
 SeahorseOperation*
@@ -259,7 +263,6 @@
     SeahorseSource *sksrc;
     SeahorseGkrOperation *gop;
     SeahorseGkrOperationPrivate *pv;
-    const gchar *keyring_name;
     
     g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (git), NULL);
     
@@ -270,13 +273,15 @@
                         "source", SEAHORSE_GKR_SOURCE (sksrc), NULL);
     pv = SEAHORSE_GKR_OPERATION_GET_PRIVATE (gop);
     
-    keyring_name = seahorse_gkr_source_get_keyring_name (SEAHORSE_GKR_SOURCE (sksrc));
-    pv->keyid = seahorse_object_get_id (SEAHORSE_OBJECT (git));
+    g_object_ref (git);
+    pv->object = SEAHORSE_OBJECT (git);
     
     /* Start actual save request */
-    pv->request = gnome_keyring_item_set_info (keyring_name, git->item_id, info, 
+    g_object_ref (gop);
+    pv->request = gnome_keyring_item_set_info (seahorse_gkr_item_get_keyring_name (git),
+                                               seahorse_gkr_item_get_item_id (git), info, 
                                                (GnomeKeyringOperationDoneCallback)basic_operation_done,
-                                               gop, NULL);
+                                               gop, g_object_unref);
     g_return_val_if_fail (pv->request, NULL);
     
     seahorse_operation_mark_start (SEAHORSE_OPERATION (gop));
@@ -291,7 +296,6 @@
     SeahorseSource *sksrc;
     SeahorseGkrOperation *gop;
     SeahorseGkrOperationPrivate *pv;
-    const gchar *keyring_name;
     
     g_return_val_if_fail (SEAHORSE_IS_GKR_ITEM (git), NULL);
     
@@ -302,13 +306,15 @@
                         "source", SEAHORSE_GKR_SOURCE (sksrc), NULL);
     pv = SEAHORSE_GKR_OPERATION_GET_PRIVATE (gop);
     
-    keyring_name = seahorse_gkr_source_get_keyring_name (SEAHORSE_GKR_SOURCE (sksrc));
-    pv->keyid = seahorse_object_get_id (SEAHORSE_OBJECT (git));
+    g_object_ref (git);
+    pv->object = SEAHORSE_OBJECT (git);
     
     /* Start actual save request */
-    pv->request = gnome_keyring_item_set_acl (keyring_name, git->item_id, acl, 
+    g_object_ref (gop);
+    pv->request = gnome_keyring_item_set_acl (seahorse_gkr_item_get_keyring_name (git), 
+                                              seahorse_gkr_item_get_item_id (git), acl, 
                                               (GnomeKeyringOperationDoneCallback)basic_operation_done,
-                                              gop, NULL);
+                                              gop, g_object_unref);
     g_return_val_if_fail (pv->request, NULL);
     
     seahorse_operation_mark_start (SEAHORSE_OPERATION (gop));

Modified: trunk/gkr/seahorse-gkr-source.c
==============================================================================
--- trunk/gkr/seahorse-gkr-source.c	(original)
+++ trunk/gkr/seahorse-gkr-source.c	Sat Nov 29 23:46:10 2008
@@ -84,210 +84,36 @@
 #define SEAHORSE_IS_LIST_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_LIST_OPERATION))
 #define SEAHORSE_LIST_OPERATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_LIST_OPERATION, SeahorseListOperationClass))
 
-enum {
-    PART_INFO = 0x01,
-    PART_ATTRS = 0x02,
-    PART_ACL = 0x04
-};
-
 DECLARE_OPERATION (List, list)
 
     SeahorseGkrSource *gsrc;
-
-    GList *remaining;
-    guint total;
-    
-    guint32 current_parts;
-    guint32 current_id;
-    guint32 info_flags;
-    GnomeKeyringItemInfo *current_info;
-    GnomeKeyringAttributeList *current_attrs;
-    GList *current_acl;
-    
     gpointer request;
-    gpointer request_attrs;
-    gpointer request_acl;
-    
     GHashTable *checks;
 
 END_DECLARE_OPERATION
 
 IMPLEMENT_OPERATION (List, list)
 
-static void     process_next_item       (SeahorseListOperation *lop);
-
-static guint32
-parse_keyid (GQuark keyid)
-{
-    const gchar *string;
-    const gchar *num;
-    gint ret;
-    char *t;
-    
-    string = g_quark_to_string (keyid);
-    if (!string)
-        return 0;
-    
-    num = strchr (string, ':');
-    if (!num)
-        return 0;
-    
-    ret = strtol (num + 1, &t, 16);
-    if (ret < 0 || *t)
-        return 0;
-    
-    return (guint32)ret;
-}
-
 static void
 keyring_operation_failed (SeahorseListOperation *lop, GnomeKeyringResult result)
 {
-    SeahorseOperation *op = SEAHORSE_OPERATION (lop);
-    GError *err = NULL;
-    
-    g_assert (result != GNOME_KEYRING_RESULT_OK);
-    g_assert (result != GNOME_KEYRING_RESULT_CANCELLED);
-    
-    if (!seahorse_operation_is_running (op))
-        return;
-    
-    if (lop->request)
-        gnome_keyring_cancel_request (lop->request);
-    lop->request = NULL;
-
-    if (lop->request_attrs)
-        gnome_keyring_cancel_request (lop->request_attrs);
-    lop->request_attrs = NULL;
-
-    if (lop->request_acl)
-        gnome_keyring_cancel_request (lop->request_acl);
-    lop->request_acl = NULL;
-    
-    seahorse_gkr_operation_parse_error (result, &err);
-    g_assert (err != NULL);
-    
-    seahorse_operation_mark_done (op, FALSE, err);
-}
-
-static gboolean
-have_complete_item (SeahorseListOperation *lop)
-{
-    SeahorseGkrItem *git = NULL;
-    SeahorseGkrItem *prev;
-    GQuark keyid;
-    
-    g_assert (lop->current_id);
-    
-    if (lop->current_parts != (PART_INFO | PART_ATTRS | PART_ACL))
-        return FALSE;
-    
-    g_assert (lop->current_info);
-  
-    keyid = seahorse_gkr_item_get_cannonical (lop->current_id);
-    g_return_val_if_fail (keyid, FALSE);
-    
-    /* Mark this key as seen */
-    if (lop->checks)
-        g_hash_table_remove (lop->checks, GUINT_TO_POINTER (keyid));
-    
-    g_assert (SEAHORSE_IS_GKR_SOURCE (lop->gsrc));
-    prev = SEAHORSE_GKR_ITEM (seahorse_context_get_object (SCTX_APP (), 
-                                   SEAHORSE_SOURCE (lop->gsrc), keyid));
-
-    /* Check if we can just replace the key on the object */
-    if (prev != NULL) {
-        g_object_set (prev, "item-info", lop->current_info, NULL);
-        if (lop->current_attrs)
-            g_object_set (prev, "item-attributes", lop->current_attrs, NULL);
-        g_object_set (prev, "item-acl", lop->current_acl, NULL);
-		
-        lop->current_info = NULL;
-        lop->current_acl = NULL;
-        lop->current_attrs = NULL;
-        return TRUE;
-    }
-    
-    git = seahorse_gkr_item_new (SEAHORSE_SOURCE (lop->gsrc), lop->current_id, 
-                                      lop->current_info, lop->current_attrs, lop->current_acl);
- 
-    /* Add to context */ 
-    seahorse_context_take_object (SCTX_APP (), SEAHORSE_OBJECT (git));
-
-    lop->current_info = NULL;
-    lop->current_acl = NULL;
-    lop->current_attrs = NULL;
-    return TRUE;
-}
-
-static void 
-item_info_ready (GnomeKeyringResult result, GnomeKeyringItemInfo *info, 
-                 SeahorseListOperation *lop)
-{
-    if (result == GNOME_KEYRING_RESULT_CANCELLED)
-        return;
-    
-    lop->request = NULL;
-
-    if (result != GNOME_KEYRING_RESULT_OK) {
-        keyring_operation_failed (lop, result);
-        return;
-    }
-    
-    g_assert (lop->current_id);
-    g_assert (!lop->current_info);
-    
-    lop->current_info = gnome_keyring_item_info_copy (info);
-    lop->current_parts |= PART_INFO;
-    
-    if (have_complete_item (lop))
-        process_next_item (lop);
-}
-
-static void 
-item_attrs_ready (GnomeKeyringResult result, GnomeKeyringAttributeList *attributes, 
-                 SeahorseListOperation *lop)
-{
-    if (result == GNOME_KEYRING_RESULT_CANCELLED)
-        return;
-    
-    lop->request_attrs = NULL;
-
-    if (result != GNOME_KEYRING_RESULT_OK) {
-        keyring_operation_failed (lop, result);
-        return;
-    }
-    
-    g_assert (lop->current_id);
-    g_assert (!lop->current_attrs);
-    
-    lop->current_attrs = gnome_keyring_attribute_list_copy (attributes);
-    lop->current_parts |= PART_ATTRS;
+	SeahorseOperation *op = SEAHORSE_OPERATION (lop);
+	GError *err = NULL;
     
-    if (have_complete_item (lop))
-        process_next_item (lop);
-}
-
-static void 
-item_acl_ready (GnomeKeyringResult result, GList *acl, SeahorseListOperation *lop)
-{
-    if (result == GNOME_KEYRING_RESULT_CANCELLED)
-        return;
+	g_assert (result != GNOME_KEYRING_RESULT_OK);
+	g_assert (result != GNOME_KEYRING_RESULT_CANCELLED);
     
-    lop->request_acl = NULL;
-
-    if (result != GNOME_KEYRING_RESULT_OK) {
-        keyring_operation_failed (lop, result);
-        return;
-    }
+	if (!seahorse_operation_is_running (op))
+		return;
     
-    g_assert (lop->current_id);
-    g_assert (!lop->current_acl);
+	if (lop->request)
+	    gnome_keyring_cancel_request (lop->request);
+	lop->request = NULL;
     
-    lop->current_acl = gnome_keyring_acl_copy (acl);
-    lop->current_parts |= PART_ACL;
+	seahorse_gkr_operation_parse_error (result, &err);
+	g_assert (err != NULL);
     
-    if (have_complete_item (lop))
-        process_next_item (lop);
+	seahorse_operation_mark_done (op, FALSE, err);
 }
 
 /* Remove the given key from the context */
@@ -303,117 +129,83 @@
         seahorse_context_remove_object (SCTX_APP (), sobj);
 }
 
-static void
-process_next_item (SeahorseListOperation *lop)
-{
-    g_assert (lop);
-    g_assert (SEAHORSE_IS_GKR_SOURCE (lop->gsrc));
-
-    seahorse_operation_mark_progress_full (SEAHORSE_OPERATION (lop), NULL, 
-                                           lop->total - g_list_length (lop->remaining), 
-                                           lop->total);
-    
-   lop->current_id = 0;
-   lop->current_parts = 0;
-   g_assert (!lop->current_info);
-   g_assert (!lop->current_attrs);
-   g_assert (!lop->current_acl);
-    
-    /* Check if we're done */
-    if (g_list_length (lop->remaining) == 0) {
-        
-        if (lop->checks)
-            g_hash_table_foreach (lop->checks, (GHFunc)remove_key_from_context, 
-                                  SEAHORSE_SOURCE (lop->gsrc));
-        
-        seahorse_operation_mark_done (SEAHORSE_OPERATION (lop), FALSE, NULL);
-        return;
-    }
-    
-    /* Start the next item */
-    g_assert (lop->current_id == 0);
-    lop->current_id = GPOINTER_TO_UINT (lop->remaining->data);
-    lop->remaining = g_list_delete_link (lop->remaining, lop->remaining);
-    
-    g_assert (!lop->request);
-
-    /* The various callbacks agree on when the item is fully loaded */
-    lop->request = gnome_keyring_item_get_info_full (lop->gsrc->pv->keyring_name, 
-                                lop->current_id, lop->info_flags, 
-                                (GnomeKeyringOperationGetItemInfoCallback)item_info_ready, lop, NULL);
-
-    lop->request_attrs = gnome_keyring_item_get_attributes (lop->gsrc->pv->keyring_name, lop->current_id, 
-                                (GnomeKeyringOperationGetAttributesCallback)item_attrs_ready, lop, NULL);
-	                            
-    lop->request_acl = gnome_keyring_item_get_acl (lop->gsrc->pv->keyring_name, lop->current_id, 
-                                (GnomeKeyringOperationGetListCallback)item_acl_ready, lop, NULL);
-}
-
 static void 
 keyring_ids_ready (GnomeKeyringResult result, GList *list, SeahorseListOperation *lop)
 {
-    if (result == GNOME_KEYRING_RESULT_CANCELLED)
-        return;
+	SeahorseGkrItem *git;
+	gchar *keyring_name;
+	guint32 item_id;
+	GQuark id;
+	
+	if (result == GNOME_KEYRING_RESULT_CANCELLED)
+		return;
     
-    lop->request = NULL;
+	lop->request = NULL;
 
-    if (result != GNOME_KEYRING_RESULT_OK) {
-        keyring_operation_failed (lop, result);
-        return;
-    }
-    
-    g_assert (lop->remaining == NULL);
-    lop->remaining = g_list_copy (list);
-    lop->total = g_list_length (list);
+	if (result != GNOME_KEYRING_RESULT_OK) {
+		keyring_operation_failed (lop, result);
+		return;
+	}
+	
+	g_object_get (lop->gsrc, "keyring-name", &keyring_name, NULL);
+	g_return_if_fail (keyring_name);
     
-    process_next_item (lop);
+	while (list) {
+		item_id = GPOINTER_TO_UINT (list->data);
+		id = seahorse_gkr_item_get_cannonical (keyring_name, item_id);
+		
+		git = SEAHORSE_GKR_ITEM (seahorse_context_get_object (SCTX_APP (), 
+		                                                      SEAHORSE_SOURCE (lop->gsrc), id));
+		if (!git) {
+			git = seahorse_gkr_item_new (SEAHORSE_SOURCE (lop->gsrc), keyring_name, item_id);
+
+			/* Add to context */ 
+			seahorse_context_take_object (SCTX_APP (), SEAHORSE_OBJECT (git));
+		}
+		
+		if (lop->checks)
+			g_hash_table_remove (lop->checks, GUINT_TO_POINTER (id));
+		
+		list = g_list_next (list);
+	}
+	
+	if (lop->checks)
+        	g_hash_table_foreach (lop->checks, (GHFunc)remove_key_from_context, 
+        	                      SEAHORSE_SOURCE (lop->gsrc));
+        
+        seahorse_operation_mark_done (SEAHORSE_OPERATION (lop), FALSE, NULL);
+
 }
 
 static SeahorseListOperation*
-start_list_operation (SeahorseGkrSource *gsrc, GQuark keyid)
+start_list_operation (SeahorseGkrSource *gsrc)
 {
-    SeahorseListOperation *lop;
-    GList *keys, *l;
+	SeahorseListOperation *lop;
+	GList *keys, *l;
 
-    g_assert (SEAHORSE_IS_GKR_SOURCE (gsrc));
+	g_assert (SEAHORSE_IS_GKR_SOURCE (gsrc));
 
-    lop = g_object_new (SEAHORSE_TYPE_LIST_OPERATION, NULL);
-    lop->gsrc = gsrc;
-    
-    seahorse_operation_mark_start (SEAHORSE_OPERATION (lop));
+	lop = g_object_new (SEAHORSE_TYPE_LIST_OPERATION, NULL);
+	lop->gsrc = gsrc;
     
-    /* When we know which key to load go directly to step two */
-    if (keyid) {
-        guint32 id;
-        
-        id = parse_keyid (keyid);
-        g_return_val_if_fail (id != 0, NULL);
-        
-        lop->remaining = g_list_prepend (lop->remaining, GUINT_TO_POINTER (id));
-        lop->total = 1;
-        
-        /* Load everything including the secret */
-        lop->info_flags = GNOME_KEYRING_ITEM_INFO_ALL;
-        
-        seahorse_operation_mark_progress (SEAHORSE_OPERATION (lop), _("Retrieving key"), -1);
-        process_next_item (lop);
-        return lop;
-    }
+	seahorse_operation_mark_start (SEAHORSE_OPERATION (lop));
+  
+	/* When loading new keys prepare a list of current */
+	lop->checks = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
+	keys = seahorse_context_get_objects (SCTX_APP (), SEAHORSE_SOURCE (gsrc));
+	for (l = keys; l; l = g_list_next (l))
+		g_hash_table_insert (lop->checks, GUINT_TO_POINTER (seahorse_object_get_id (l->data)), 
+		                     GUINT_TO_POINTER (TRUE));
+	g_list_free (keys);
     
-    /* When loading new keys prepare a list of current */
-    lop->checks = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-    keys = seahorse_context_get_objects (SCTX_APP (), SEAHORSE_SOURCE (gsrc));
-    for (l = keys; l; l = g_list_next (l))
-        g_hash_table_insert (lop->checks, GUINT_TO_POINTER (seahorse_object_get_id (l->data)), 
-                             GUINT_TO_POINTER (TRUE));
-    g_list_free (keys);
-    
-    /* Start listing of ids */
-    seahorse_operation_mark_progress (SEAHORSE_OPERATION (lop), _("Listing passwords"), -1);
-    lop->request = gnome_keyring_list_item_ids (gsrc->pv->keyring_name, 
-                    (GnomeKeyringOperationGetListCallback)keyring_ids_ready, lop, NULL);
+	/* Start listing of ids */
+	seahorse_operation_mark_progress (SEAHORSE_OPERATION (lop), _("Listing passwords"), -1);
+	g_object_ref (lop);
+	lop->request = gnome_keyring_list_item_ids (gsrc->pv->keyring_name, 
+	                                            (GnomeKeyringOperationGetListCallback)keyring_ids_ready, 
+	                                            lop, g_object_unref);
     
-    return lop;
+	return lop;
 }
 
 static void 
@@ -444,20 +236,6 @@
     SeahorseListOperation *lop = SEAHORSE_LIST_OPERATION (gobject);
     g_assert (!seahorse_operation_is_running (SEAHORSE_OPERATION (lop)));
     
-    if (lop->remaining)
-        g_list_free (lop->remaining);
-    lop->remaining = NULL;
-    
-    if (lop->current_info)
-        gnome_keyring_item_info_free (lop->current_info);
-    lop->current_info = NULL;
-    if (lop->current_attrs)
-        gnome_keyring_attribute_list_free (lop->current_attrs);
-    lop->current_attrs = NULL;
-    if (lop->current_acl)
-        gnome_keyring_acl_free (lop->current_acl);
-    lop->current_acl = NULL;
-    
     if (lop->checks)
         g_hash_table_destroy (lop->checks);
     lop->checks = NULL;
@@ -495,7 +273,7 @@
 DECLARE_OPERATION (Remove, remove)
 
 	SeahorseGkrSource *gsrc;
-	SeahorseGkrItem *gitem;
+	SeahorseGkrItem *item;
 	gpointer request;
 
 END_DECLARE_OPERATION
@@ -520,30 +298,33 @@
 		return;
 	}
     
-	seahorse_context_remove_object (SCTX_APP (), SEAHORSE_OBJECT (rop->gitem));
+	seahorse_context_remove_object (SCTX_APP (), SEAHORSE_OBJECT (rop->item));
 	seahorse_operation_mark_done (SEAHORSE_OPERATION (rop), FALSE, NULL);
 }
 
 static SeahorseRemoveOperation*
-start_remove_operation (SeahorseGkrSource *gsrc, SeahorseGkrItem *gitem)
+start_remove_operation (SeahorseGkrSource *gsrc, SeahorseGkrItem *git)
 {
 	SeahorseRemoveOperation *rop;
 
 	g_assert (SEAHORSE_IS_GKR_SOURCE (gsrc));
-	g_assert (SEAHORSE_IS_GKR_ITEM (gitem));
+	g_assert (SEAHORSE_IS_GKR_ITEM (git));
 	
 	rop = g_object_new (SEAHORSE_TYPE_REMOVE_OPERATION, NULL);
 	rop->gsrc = gsrc;
 	g_object_ref (gsrc);
-	rop->gitem = gitem;
-	g_object_ref (gitem);
+	rop->item = git;
+	g_object_ref (git);
 	
 	seahorse_operation_mark_start (SEAHORSE_OPERATION (rop));
     
 	/* Start listing of ids */
 	seahorse_operation_mark_progress (SEAHORSE_OPERATION (rop), _("Removing item"), -1);
-	rop->request = gnome_keyring_item_delete (gsrc->pv->keyring_name, gitem->item_id, 
-	                    (GnomeKeyringOperationDoneCallback)remove_item_ready, rop, NULL);
+	g_object_ref (rop);
+	rop->request = gnome_keyring_item_delete (seahorse_gkr_item_get_keyring_name (git), 
+	                                          seahorse_gkr_item_get_item_id (git), 
+	                                          (GnomeKeyringOperationDoneCallback)remove_item_ready, 
+	                                          rop, g_object_unref);
     
 	return rop;
 }
@@ -571,9 +352,9 @@
 		g_object_unref (rop->gsrc);
 	rop->gsrc = NULL;
 	
-	if (rop->gitem)
-		g_object_unref (rop->gitem);
-	rop->gitem = NULL;
+	if (rop->item)
+		g_object_unref (rop->item);
+	rop->item = NULL;
 
 	G_OBJECT_CLASS (remove_operation_parent_class)->dispose (gobject);  
 }
@@ -585,7 +366,7 @@
 	g_assert (!seahorse_operation_is_running (SEAHORSE_OPERATION (rop)));
     
 	g_assert (rop->gsrc == NULL);
-	g_assert (rop->gitem == NULL);
+	g_assert (rop->item == NULL);
     
 	/* The above cancel should have stopped this */
 	g_assert (rop->request == NULL);
@@ -679,7 +460,9 @@
     g_assert (SEAHORSE_IS_SOURCE (src));
     gsrc = SEAHORSE_GKR_SOURCE (src);
     
-    lop = start_list_operation (gsrc, keyid);
+    /* TODO: Loading a specific key? */
+    
+    lop = start_list_operation (gsrc);
     seahorse_multi_operation_take (gsrc->pv->operations, SEAHORSE_OPERATION (lop));
     
     g_object_ref (lop);

Modified: trunk/libseahorse/seahorse-object.c
==============================================================================
--- trunk/libseahorse/seahorse-object.c	(original)
+++ trunk/libseahorse/seahorse-object.c	Sat Nov 29 23:46:10 2008
@@ -73,6 +73,8 @@
 	SeahorseLocation location;
 	SeahorseUsage usage;
 	guint flags;
+	
+	gboolean realized;
 };
 
 G_DEFINE_TYPE (SeahorseObject, seahorse_object, G_TYPE_OBJECT);
@@ -105,20 +107,60 @@
 	self->pv->children = g_list_remove (self->pv->children, child);
 }
 
+static gboolean
+set_string_storage (const gchar *value, gchar **storage)
+{
+	g_assert (storage);
+
+	if (value == NULL)
+		value = "";
+	
+	if (!value || !*storage || !g_str_equal (value, *storage)) {
+		g_free (*storage);
+		*storage = g_strdup (value);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+static gboolean
+take_string_storage (gchar *value, gchar **storage)
+{
+	g_assert (storage);
+	
+	if (value == NULL)
+		value = g_strdup ("");
+	
+	if (!value || !*storage || !g_str_equal (value, *storage)) {
+		g_free (*storage);
+		*storage = value;
+		return TRUE;
+	}
+	
+	g_free (value);
+	return FALSE;
+}
+
 static void
 recalculate_id (SeahorseObject *self)
 {
 	const gchar *str;
 	const gchar *at;
+	GQuark tag;
 	gchar *result;
 	gsize len;
 
 	/* No id, clear any tag and auto generated identifer */
 	if (!self->pv->id) {
-		self->pv->tag = 0; 
+		if (self->pv->tag != 0) {
+			self->pv->tag = 0;
+			g_object_notify (G_OBJECT (self), "tag");
+		}
+			
 		if (!self->pv->identifier_explicit) {
-			g_free (self->pv->identifier);
-			self->pv->identifier = g_strdup ("");
+			if (set_string_storage ("", &self->pv->identifier))
+				g_object_notify (G_OBJECT (self), "identifier");
 		}
 		
 	/* Have hande, configure tag and auto generated identifer */
@@ -128,12 +170,17 @@
 		at = strchr (str, ':');
 		
 		result = g_strndup (str, at ? at - str : len);
-		self->pv->tag = g_quark_from_string (result);
+		tag = g_quark_from_string (result);
 		g_free (result);
+
+		if (tag != self->pv->tag) {
+			self->pv->tag = tag;
+			g_object_notify (G_OBJECT (self), "tag");
+		}
 		
 		if (!self->pv->identifier_explicit) {
-			g_free (self->pv->identifier);
-			self->pv->identifier = g_strdup (at ? at + 1 : "");
+			if (set_string_storage (at ? at + 1 : "", &self->pv->identifier))
+				g_object_notify (G_OBJECT (self), "identifier");
 		}
 	}
 }
@@ -142,13 +189,14 @@
 recalculate_label (SeahorseObject *self)
 {
 	if (!self->pv->markup_explicit) {
-		g_free (self->pv->markup);
-		self->pv->markup = g_markup_escape_text (self->pv->label ? self->pv->label : "", -1);
+		if (take_string_storage (g_markup_escape_text (self->pv->label ? self->pv->label : "", -1),
+		                         &self->pv->markup))
+			g_object_notify (G_OBJECT (self), "markup");
 	}
 
 	if (!self->pv->nickname_explicit) {
-		g_free (self->pv->nickname);
-		self->pv->nickname = g_strdup (self->pv->label);
+		if (set_string_storage (self->pv->label, &self->pv->nickname))
+			g_object_notify (G_OBJECT (self), "nickname");
 	}
 }
 
@@ -158,7 +206,6 @@
 	const gchar *desc;
 	
 	if (!self->pv->description_explicit) {
-		g_free (self->pv->description);
 		
 		switch (self->pv->usage) {
 		case SEAHORSE_USAGE_SYMMETRIC_KEY:
@@ -181,7 +228,8 @@
 			break;
 		}
 		
-		self->pv->description = g_strdup (desc); 
+		if (set_string_storage (desc, &self->pv->description))
+			g_object_notify (G_OBJECT (self), "description");
 	}
 }
 
@@ -346,7 +394,11 @@
                               GParamSpec *pspec)
 {
 	SeahorseObject *self = SEAHORSE_OBJECT (obj);
-
+	SeahorseLocation loc;
+	SeahorseUsage usage;
+	guint flags;
+	GQuark id;
+	
 	switch (prop_id) {
 	case PROP_CONTEXT:
 		if (self->pv->context) 
@@ -366,57 +418,74 @@
 		seahorse_object_set_parent (self, SEAHORSE_OBJECT (g_value_get_object (value)));
 		break;
 	case PROP_ID:
-		self->pv->id = g_value_get_uint (value);
-		g_object_notify (obj, "id");
-		recalculate_id (self);
+		id = g_value_get_uint (value);
+		if (id != self->pv->id) {
+			self->pv->id = id;
+			g_object_freeze_notify (obj);
+			g_object_notify (obj, "id");
+			recalculate_id (self);
+			g_object_thaw_notify (obj);
+		}
 		break;
 	case PROP_LABEL:
-		g_free (self->pv->label);
-		self->pv->label = g_value_dup_string (value);
-		g_object_notify (obj, "label");
-		recalculate_label (self);
+		if (set_string_storage (g_value_get_string (value), &self->pv->label)) {
+			g_object_freeze_notify (obj);
+			g_object_notify (obj, "label");
+			recalculate_label (self);
+			g_object_thaw_notify (obj);
+		}
 		break;
 	case PROP_NICKNAME:
-		g_free (self->pv->nickname);
-		self->pv->nickname = g_value_dup_string (value);
-		self->pv->nickname_explicit = TRUE;
-		g_object_notify (obj, "nickname");
+		if (set_string_storage (g_value_get_string (value), &self->pv->nickname)) {
+			self->pv->nickname_explicit = TRUE;
+			g_object_notify (obj, "nickname");
+		}
 		break;
 	case PROP_MARKUP:
-		g_free (self->pv->markup);
-		self->pv->markup = g_value_dup_string (value);
-		self->pv->markup_explicit = TRUE;
-		g_object_notify (obj, "markup");
+		if (set_string_storage (g_value_get_string (value), &self->pv->markup)) {
+			self->pv->markup_explicit = TRUE;
+			g_object_notify (obj, "markup");
+		}
 		break;
 	case PROP_DESCRIPTION:
-		g_free (self->pv->description);
-		self->pv->description = g_value_dup_string (value);
-		self->pv->description_explicit = TRUE;
-		g_object_notify (obj, "description");
+		if (set_string_storage (g_value_get_string (value), &self->pv->description)) {
+			self->pv->description_explicit = TRUE;
+			g_object_notify (obj, "description");
+		}
 		break;
 	case PROP_ICON:
-		g_free (self->pv->icon);
-		self->pv->icon = g_value_dup_string (value);
-		g_object_notify (obj, "icon");
+		if (set_string_storage (g_value_get_string (value), &self->pv->icon))
+			g_object_notify (obj, "icon");
 		break;
 	case PROP_IDENTIFIER:
-		g_free (self->pv->identifier);
-		self->pv->identifier = g_value_dup_string (value);
-		self->pv->identifier_explicit = TRUE;
-		g_object_notify (obj, "identifier");
+		if (set_string_storage (g_value_get_string (value), &self->pv->identifier)) {
+			self->pv->identifier_explicit = TRUE;
+			g_object_notify (obj, "identifier");
+		}
 		break;
 	case PROP_LOCATION:
-		self->pv->location = g_value_get_enum (value);
-		g_object_notify (obj, "location");
+		loc = g_value_get_enum (value);
+		if (loc != self->pv->location) {
+			self->pv->location = loc;
+			g_object_notify (obj, "location");
+		}
 		break;
 	case PROP_USAGE:
-		self->pv->usage = g_value_get_enum (value);
-		g_object_notify (obj, "usage");
-		recalculate_usage (self);
+		usage = g_value_get_enum (value);
+		if (usage != self->pv->usage) {
+			self->pv->usage = usage;
+			g_object_freeze_notify (obj);
+			g_object_notify (obj, "usage");
+			recalculate_usage (self);
+			g_object_thaw_notify (obj);
+		}
 		break;
 	case PROP_FLAGS:
-		self->pv->flags = g_value_get_uint (value);
-		g_object_notify (obj, "flags");
+		flags = g_value_get_uint (value);
+		if (flags != self->pv->flags) {
+			self->pv->flags = flags;
+			g_object_notify (obj, "flags");
+		}
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -424,6 +493,27 @@
 	}
 }
 
+static void 
+seahorse_object_real_realize (SeahorseObject *self)
+{
+	/* 
+	 * We do nothing by default. It's up to the derived class
+	 * to override this and realize themselves when called.
+	 */
+	
+	self->pv->realized = TRUE;
+}
+
+static void 
+seahorse_object_real_flush (SeahorseObject *self)
+{
+	/* 
+	 * We do nothing by default. It's up to the derived class
+	 * to override this and flush themselves when called.
+	 */
+	self->pv->realized = FALSE;
+}
+
 static void
 seahorse_object_class_init (SeahorseObjectClass *klass)
 {
@@ -436,7 +526,10 @@
 	gobject_class->finalize = seahorse_object_finalize;
 	gobject_class->set_property = seahorse_object_set_property;
 	gobject_class->get_property = seahorse_object_get_property;
-    
+	
+	klass->realize = seahorse_object_real_realize;
+	klass->flush = seahorse_object_real_flush;
+	
 	g_object_class_install_property (gobject_class, PROP_SOURCE,
 	           g_param_spec_object ("source", "Object Source", "Source the Object came from", 
 	                                SEAHORSE_TYPE_SOURCE, G_PARAM_READWRITE));
@@ -506,6 +599,7 @@
 seahorse_object_get_id (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), 0);
+	seahorse_object_realize (self);
 	return self->pv->id;
 }
 
@@ -513,6 +607,7 @@
 seahorse_object_get_tag (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), 0);
+	seahorse_object_realize (self);
 	return self->pv->tag;	
 }
 
@@ -520,6 +615,7 @@
 seahorse_object_get_source (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->source;	
 }
 
@@ -545,6 +641,7 @@
 seahorse_object_get_context (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->context;
 }
 
@@ -552,6 +649,7 @@
 seahorse_object_get_preferred (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->preferred;
 }
 
@@ -577,6 +675,7 @@
 seahorse_object_get_parent (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->parent;
 }
 
@@ -606,6 +705,7 @@
 seahorse_object_get_children (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return g_list_copy (self->pv->children);
 }
 
@@ -620,6 +720,7 @@
 seahorse_object_get_label (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->label;
 }
 
@@ -627,6 +728,7 @@
 seahorse_object_get_markup (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->markup;
 }
 
@@ -634,6 +736,7 @@
 seahorse_object_get_nickname (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->nickname;
 }
 
@@ -641,6 +744,7 @@
 seahorse_object_get_description (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->description;
 }
 
@@ -648,6 +752,7 @@
 seahorse_object_get_icon (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->icon;
 }
 
@@ -655,6 +760,7 @@
 seahorse_object_get_identifier (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), NULL);
+	seahorse_object_realize (self);
 	return self->pv->identifier;	
 }
 
@@ -662,6 +768,7 @@
 seahorse_object_get_location (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), SEAHORSE_LOCATION_INVALID);
+	seahorse_object_realize (self);
 	return self->pv->location;
 }
 
@@ -669,6 +776,7 @@
 seahorse_object_get_usage (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), SEAHORSE_USAGE_NONE);
+	seahorse_object_realize (self);
 	return self->pv->usage;	
 }
 
@@ -676,6 +784,7 @@
 seahorse_object_get_flags (SeahorseObject *self)
 {
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (self), 0);
+	seahorse_object_realize (self);
 	return self->pv->flags;	
 }
 
@@ -721,6 +830,39 @@
 	return TRUE; 
 }
 
+void
+seahorse_object_realize (SeahorseObject *self)
+{
+	SeahorseObjectClass *klass;
+	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
+	if (self->pv->realized)
+		return;
+	klass = SEAHORSE_OBJECT_GET_CLASS (self);
+	g_return_if_fail (klass->realize);
+	(klass->realize) (self);
+}
+
+void
+seahorse_object_flush (SeahorseObject *self)
+{
+	SeahorseObjectClass *klass;
+	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
+	klass = SEAHORSE_OBJECT_GET_CLASS (self);
+	g_return_if_fail (klass->flush);
+	(klass->flush) (self);
+}
+
+void
+seahorse_object_refresh (SeahorseObject *self)
+{
+	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
+
+	g_object_freeze_notify (G_OBJECT (self));
+	seahorse_object_flush (self);
+	seahorse_object_realize (self);
+	g_object_thaw_notify (G_OBJECT (self));
+}
+
 gboolean 
 seahorse_object_predicate_match (SeahorseObjectPredicate *self, SeahorseObject* obj) 
 {
@@ -729,6 +871,8 @@
 	g_return_val_if_fail (SEAHORSE_IS_OBJECT (obj), FALSE);
 	pv = obj->pv;
 	
+	seahorse_object_realize (obj);
+	
 	/* Check all the fields */
 	if (self->tag != 0 && self->tag != pv->tag)
 		return FALSE;

Modified: trunk/libseahorse/seahorse-object.h
==============================================================================
--- trunk/libseahorse/seahorse-object.h	(original)
+++ trunk/libseahorse/seahorse-object.h	Sat Nov 29 23:46:10 2008
@@ -67,12 +67,22 @@
 
 struct _SeahorseObjectClass {
 	GObjectClass parent_class;
+	
+	/* virtual methods ------------------------------------------------- */
+
+	void (*realize) (SeahorseObject *self);
+	
+	void (*flush) (SeahorseObject *self);
 };
 
 GType               seahorse_object_get_type               (void);
 
 SeahorseObject*     seahorse_object_new                    (void);
 
+void                seahorse_object_realize                (SeahorseObject *self);
+
+void                seahorse_object_refresh                (SeahorseObject *self);
+
 GQuark              seahorse_object_get_id                 (SeahorseObject *self);
 
 GQuark              seahorse_object_get_tag                (SeahorseObject *self);

Modified: trunk/libseahorse/seahorse-operation.c
==============================================================================
--- trunk/libseahorse/seahorse-operation.c	(original)
+++ trunk/libseahorse/seahorse-operation.c	Sat Nov 29 23:46:10 2008
@@ -226,15 +226,18 @@
 void
 seahorse_operation_copy_error  (SeahorseOperation *op, GError **err)
 {
-    g_return_if_fail (err == NULL || *err == NULL);
-    if (err) 
-        *err = op->error ? g_error_copy (op->error) : NULL;
+	g_return_if_fail (SEAHORSE_IS_OPERATION (op));
+	g_return_if_fail (err == NULL || *err == NULL);
+    
+	if (err) 
+		*err = op->error ? g_error_copy (op->error) : NULL;
 }
 
 const GError*       
 seahorse_operation_get_error (SeahorseOperation *op)
 {
-    return op->error;
+	g_return_val_if_fail (SEAHORSE_IS_OPERATION (op), NULL);
+	return op->error;
 }
 
 void
@@ -249,19 +252,26 @@
 gpointer
 seahorse_operation_get_result (SeahorseOperation *op)
 {
-    return op->result;
+	g_return_val_if_fail (SEAHORSE_IS_OPERATION (op), NULL);
+	return op->result;
 }
 
 void                
 seahorse_operation_wait (SeahorseOperation *op)
 {
-    seahorse_util_wait_until (!seahorse_operation_is_running (op));
+	g_return_if_fail (SEAHORSE_IS_OPERATION (op));
+
+	g_object_ref (op);
+	seahorse_util_wait_until (!seahorse_operation_is_running (op));
+	g_object_unref (op);
 }
 
 void
 seahorse_operation_watch (SeahorseOperation *operation, SeahorseDoneFunc done_callback,
                           gpointer donedata, SeahorseProgressFunc progress_callback, gpointer progdata)
 {
+    g_return_if_fail (SEAHORSE_IS_OPERATION (operation));
+
     if (!seahorse_operation_is_running (operation)) {
         if (done_callback)
             (done_callback) (operation, donedata);

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	(original)
+++ trunk/src/main.c	Sat Nov 29 23:46:10 2008
@@ -92,12 +92,10 @@
 #ifdef WITH_PKCS11
     seahorse_pkcs11_module_init ();
 #endif
+    seahorse_gkr_module_init ();
 
     op = seahorse_context_refresh_local (SCTX_APP ());
 
-    /* Load these components after loading local keys */
-    seahorse_gkr_module_init ();
-
     seahorse_key_manager_show (op);
     g_signal_connect_after (SCTX_APP (), "destroy", gtk_main_quit, NULL);
     

Modified: trunk/src/seahorse-key-manager.c
==============================================================================
--- trunk/src/seahorse-key-manager.c	(original)
+++ trunk/src/seahorse-key-manager.c	Sat Nov 29 23:46:10 2008
@@ -38,7 +38,6 @@
 #include <seahorse-preferences.h>
 #include <gconf/gconf-client.h>
 #include <gconf/gconf.h>
-#include <common/seahorse-registry.h>
 #include <config.h>
 #include "seahorse-generate-select.h"
 
@@ -78,7 +77,6 @@
 	GtkEntry* _filter_entry;
 	GQuark _track_selected_id;
 	guint _track_selected_tab;
-	gboolean _loaded_gnome_keyring;
 	SeahorseKeyManagerTabInfo* _tabs;
 	gint _tabs_length1;
 };
@@ -134,9 +132,6 @@
 static void seahorse_key_manager_on_gconf_notify (SeahorseKeyManager* self, GConfClient* client, guint cnxn_id, GConfEntry* entry);
 static gboolean seahorse_key_manager_fire_selection_changed (SeahorseKeyManager* self);
 static void seahorse_key_manager_on_tab_changed (SeahorseKeyManager* self, GtkNotebook* notebook, void* unused, guint page_num);
-static void __lambda0 (SeahorseOperation* op, SeahorseKeyManager* self);
-static void ___lambda0_seahorse_done_func (SeahorseOperation* op, gpointer self);
-static void seahorse_key_manager_load_gnome_keyring_items (SeahorseKeyManager* self);
 static void seahorse_key_manager_on_help_show (SeahorseKeyManager* self, GtkButton* button);
 static void _seahorse_key_manager_on_app_quit_gtk_action_activate (GtkAction* _sender, gpointer self);
 static void _seahorse_key_manager_on_key_generate_gtk_action_activate (GtkAction* _sender, gpointer self);
@@ -963,47 +958,6 @@
 	/* Don't track the selected key when tab is changed on purpose */
 	self->priv->_track_selected_id = ((GQuark) (0));
 	seahorse_key_manager_fire_selection_changed (self);
-	/* 
-	 * Because gnome-keyring can throw prompts etc... we delay loading 
-	 * of the gnome key ring items until we first access them. 
-	 */
-	if (seahorse_key_manager_get_tab_id (self, seahorse_key_manager_get_tab_info (self, ((gint) (page_num)))) == SEAHORSE_KEY_MANAGER_TABS_PASSWORD) {
-		seahorse_key_manager_load_gnome_keyring_items (self);
-	}
-}
-
-
-static void __lambda0 (SeahorseOperation* op, SeahorseKeyManager* self) {
-	g_return_if_fail (SEAHORSE_IS_OPERATION (op));
-	if (seahorse_operation_is_successful (op)) {
-		self->priv->_loaded_gnome_keyring = TRUE;
-	}
-}
-
-
-static void ___lambda0_seahorse_done_func (SeahorseOperation* op, gpointer self) {
-	__lambda0 (op, self);
-}
-
-
-static void seahorse_key_manager_load_gnome_keyring_items (SeahorseKeyManager* self) {
-	GType type;
-	SeahorseSource* sksrc;
-	SeahorseOperation* op;
-	g_return_if_fail (SEAHORSE_IS_KEY_MANAGER (self));
-	if (self->priv->_loaded_gnome_keyring) {
-		return;
-	}
-	type = seahorse_registry_find_type (seahorse_registry_get (), "gnome-keyring", "local", "source", NULL, NULL);
-	g_return_if_fail (type != 0);
-	sksrc = SEAHORSE_SOURCE (g_object_new (type, NULL, NULL));
-	seahorse_context_add_source (seahorse_context_for_app (), sksrc);
-	op = seahorse_source_load (sksrc, ((GQuark) (0)));
-	/* Monitor loading progress */
-	seahorse_progress_status_set_operation (SEAHORSE_WIDGET (self), op);
-	seahorse_operation_watch (op, ___lambda0_seahorse_done_func, self, NULL, NULL);
-	(sksrc == NULL ? NULL : (sksrc = (g_object_unref (sksrc), NULL)));
-	(op == NULL ? NULL : (op = (g_object_unref (op), NULL)));
 }
 
 
@@ -1167,7 +1121,6 @@
 		GtkTargetEntry* _tmp20;
 		GtkTargetEntry* entries;
 		GtkTargetList* targets;
-		self->priv->_loaded_gnome_keyring = FALSE;
 		_tmp1 = NULL;
 		self->priv->_tabs = (_tmp1 = g_new0 (SeahorseKeyManagerTabInfo, (_tmp0 = ((gint) (SEAHORSE_KEY_MANAGER_TABS_NUM_TABS)))), (self->priv->_tabs = (g_free (self->priv->_tabs), NULL)), self->priv->_tabs_length1 = _tmp0, _tmp1);
 		_tmp3 = NULL;

Modified: trunk/src/seahorse-key-manager.vala
==============================================================================
--- trunk/src/seahorse-key-manager.vala	(original)
+++ trunk/src/seahorse-key-manager.vala	Sat Nov 29 23:46:10 2008
@@ -31,7 +31,6 @@
 		private Gtk.Entry _filter_entry;
 		private Quark _track_selected_id;
 		private uint _track_selected_tab;
-		private bool _loaded_gnome_keyring;
 		
 		private enum Targets {
 			PLAIN,
@@ -134,7 +133,6 @@
 		}
 		
 		construct {
-			_loaded_gnome_keyring = false;
 			_tabs = new TabInfo[(int)Tabs.NUM_TABS];
 			
 			_notebook = (Gtk.Notebook)get_widget ("notebook");
@@ -704,38 +702,8 @@
 			/* Don't track the selected key when tab is changed on purpose */
 			_track_selected_id = 0;
 			fire_selection_changed ();
-    
-			/* 
-			 * Because gnome-keyring can throw prompts etc... we delay loading 
-			 * of the gnome key ring items until we first access them. 
-			 */
-    
-    			if (get_tab_id (get_tab_info ((int)page_num)) == Tabs.PASSWORD)
-        			load_gnome_keyring_items ();
 		}
 
-		private void load_gnome_keyring_items () {
-			
-			if (_loaded_gnome_keyring)
-				return;
-			
-			GLib.Type type = Registry.get().find_type ("gnome-keyring", "local", "source", null);
-			return_if_fail (type != 0);
-
-			var sksrc = (Source)GLib.Object.new (type, null);
-			Context.for_app().add_source (sksrc);
-			Operation op = sksrc.load (0);
-			
-			/* Monitor loading progress */
-			Progress.status_set_operation (this, op);
-			
-			/* After load completes set loaded to TRUE */
-			op.watch ((op) => {if (op.is_successful ())
-                                _loaded_gnome_keyring = true;
-                            },  
-                      null);
-		}
-		
 		private void on_help_show (Gtk.Button button) {
 			show_help ();
 		}

Modified: trunk/src/vala-build.stamp
==============================================================================
--- trunk/src/vala-build.stamp	(original)
+++ trunk/src/vala-build.stamp	Sat Nov 29 23:46:10 2008
@@ -1 +1 @@
-1227980124
+1227995668



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