[seahorse] pgp: Fix key server and syncing bugs



commit 5a81d2302488fb8553638b6284dcb621b3d30c83
Author: Stef Walter <stefw collabora co uk>
Date:   Mon Dec 12 10:40:59 2011 +0100

    pgp: Fix key server and syncing bugs

 pgp/seahorse-hkp-source.c         |   20 +++----
 pgp/seahorse-keyserver-sync.c     |   17 +++++-
 pgp/seahorse-ldap-source.c        |    8 ++--
 pgp/seahorse-pgp-backend.c        |   38 ++++++++------
 pgp/seahorse-pgp-backend.h        |    4 +-
 pgp/seahorse-pgp-key-properties.c |   64 +++++++++++++-----------
 pgp/seahorse-server-source.c      |    2 +-
 pgp/seahorse-server-source.h      |    4 +-
 pgp/seahorse-transfer.c           |   81 ++++++++++++++++++++++++-------
 pgp/seahorse-transfer.h           |    9 +++-
 pgp/seahorse-unknown-source.c     |   98 ++++++++++++++++++++++++++++++++++--
 11 files changed, 251 insertions(+), 94 deletions(-)
---
diff --git a/pgp/seahorse-hkp-source.c b/pgp/seahorse-hkp-source.c
index 2004ad3..d821c1a 100644
--- a/pgp/seahorse-hkp-source.c
+++ b/pgp/seahorse-hkp-source.c
@@ -788,7 +788,9 @@ on_import_message_complete (SoupSession *session,
 	GError *error = NULL;
 	gchar *errmsg;
 
-	seahorse_progress_end (closure->cancellable, message);
+	g_assert (closure->requests > 0);
+	seahorse_progress_end (closure->cancellable, GUINT_TO_POINTER (closure->requests));
+	closure->requests--;
 
 	if (hkp_message_propagate_error (closure->source, message, &error)) {
 		g_simple_async_result_take_error (res, error);
@@ -802,9 +804,6 @@ on_import_message_complete (SoupSession *session,
 
 	/* A successful status from the server is all we want in this case */
 	} else {
-		g_assert (closure->requests > 0);
-		closure->requests--;
-
 		if (closure->requests == 0)
 			g_simple_async_result_complete_in_idle (res);
 	}
@@ -890,7 +889,7 @@ seahorse_hkp_source_import_async (SeahorsePlace *place,
 		                            on_import_message_complete, g_object_ref (res));
 
 		closure->requests++;
-		seahorse_progress_prep_and_begin (cancellable, message, NULL);
+		seahorse_progress_prep_and_begin (cancellable, GUINT_TO_POINTER (closure->requests), NULL);
 	}
 	g_hash_table_destroy (form);
 
@@ -1001,7 +1000,7 @@ on_export_message_complete (SoupSession *session,
 **/
 static void
 seahorse_hkp_source_export_async (SeahorseServerSource *source,
-                                  GList *keyids,
+                                  const gchar **keyids,
                                   GCancellable *cancellable,
                                   GAsyncReadyCallback callback,
                                   gpointer user_data)
@@ -1015,7 +1014,7 @@ seahorse_hkp_source_export_async (SeahorseServerSource *source,
 	gchar hexfpr[11];
 	GHashTable *form;
 	guint len;
-	GList *l;
+	gint i;
 
 	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
 	                                 seahorse_hkp_source_export_async);
@@ -1026,7 +1025,7 @@ seahorse_hkp_source_export_async (SeahorseServerSource *source,
 	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 	g_simple_async_result_set_op_res_gpointer (res, closure, export_closure_free);
 
-	if (g_list_length (keyids) == 0) {
+	if (!keyids || !keyids[0]) {
 		g_simple_async_result_complete_in_idle (res);
 		g_object_unref (res);
 		return;
@@ -1039,12 +1038,11 @@ seahorse_hkp_source_export_async (SeahorseServerSource *source,
 	strncpy (hexfpr, "0x", 3);
 
 	form = g_hash_table_new (g_str_hash, g_str_equal);
-	for (l = keyids; l; l = g_list_next (l)) {
-
+	for (i = 0; keyids[i] != NULL; i++) {
 		g_hash_table_remove_all (form);
 
 		/* Get the key id and limit it to 8 characters */
-		fpr = l->data;
+		fpr = keyids[i];
 		len = strlen (fpr);
 		if (len > 8)
 			fpr += (len - 8);
diff --git a/pgp/seahorse-keyserver-sync.c b/pgp/seahorse-keyserver-sync.c
index 6ec4827..1019b94 100644
--- a/pgp/seahorse-keyserver-sync.c
+++ b/pgp/seahorse-keyserver-sync.c
@@ -186,6 +186,8 @@ seahorse_keyserver_sync (GList *keys)
 	gchar *keyserver;
 	GCancellable *cancellable;
 	gchar **keyservers;
+	GPtrArray *keyids;
+	GList *l;
 	guint i;
 
 	if (!keys)
@@ -193,6 +195,11 @@ seahorse_keyserver_sync (GList *keys)
 
 	cancellable = g_cancellable_new ();
 
+	keyids = g_ptr_array_new ();
+	for (l = keys; l != NULL; l = g_list_next (l))
+		g_ptr_array_add (keyids, (gchar *)seahorse_pgp_key_get_keyid (l->data));
+	g_ptr_array_add (keyids, NULL);
+
 	/* And now synchronizing keys from the servers */
 	keyservers = seahorse_servers_get_uris ();
 	for (i = 0; keyservers[i] != NULL; i++) {
@@ -203,11 +210,15 @@ seahorse_keyserver_sync (GList *keys)
 			continue;
 
 		keyring = seahorse_pgp_backend_get_default_keyring (NULL);
-		seahorse_transfer_async (SEAHORSE_PLACE (source), SEAHORSE_PLACE (keyring),
-		                         keys, cancellable, on_transfer_download_complete,
-		                         g_object_ref (source));
+		seahorse_transfer_keyids_async (SEAHORSE_SERVER_SOURCE (source),
+		                                SEAHORSE_PLACE (keyring),
+		                                (const gchar **)keyids->pdata,
+		                                cancellable,
+		                                on_transfer_download_complete,
+		                                g_object_ref (source));
 	}
 
+	g_ptr_array_free (keyids, TRUE);
 	g_strfreev (keyservers);
 
 	/* Publishing keys online */
diff --git a/pgp/seahorse-ldap-source.c b/pgp/seahorse-ldap-source.c
index 38d3d0c..5d2e8a7 100644
--- a/pgp/seahorse-ldap-source.c
+++ b/pgp/seahorse-ldap-source.c
@@ -1370,7 +1370,7 @@ on_export_connect_completed (GObject *source,
 
 static void
 seahorse_ldap_source_export_async (SeahorseServerSource *source,
-                                   GList *keyids,
+                                   const gchar **keyids,
                                    GCancellable *cancellable,
                                    GAsyncReadyCallback callback,
                                    gpointer user_data)
@@ -1379,7 +1379,7 @@ seahorse_ldap_source_export_async (SeahorseServerSource *source,
 	ExportClosure *closure;
 	GSimpleAsyncResult *res;
 	gchar *fingerprint;
-	GList *l;
+	gint i;
 
 	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
 	                                 seahorse_ldap_source_export_async);
@@ -1387,8 +1387,8 @@ seahorse_ldap_source_export_async (SeahorseServerSource *source,
 	closure->data = g_string_sized_new (1024);
 	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 	closure->fingerprints = g_ptr_array_new_with_free_func (g_free);
-	for (l = keyids; l; l = g_list_next (l)) {
-		fingerprint = g_strdup (l->data);
+	for (i = 0; keyids[i] != NULL; i++) {
+		fingerprint = g_strdup (keyids[i]);
 		g_ptr_array_add (closure->fingerprints, fingerprint);
 		seahorse_progress_prep (closure->cancellable, fingerprint, NULL);
 	}
diff --git a/pgp/seahorse-pgp-backend.c b/pgp/seahorse-pgp-backend.c
index 29d06ee..6e373e6 100644
--- a/pgp/seahorse-pgp-backend.c
+++ b/pgp/seahorse-pgp-backend.c
@@ -554,13 +554,13 @@ seahorse_pgp_backend_transfer_async (SeahorsePgpBackend *self,
 
 		/* Export from this key place */
 		from = seahorse_object_get_place (object);
-		g_return_if_fail (from != NULL);
+		g_return_if_fail (SEAHORSE_IS_GPGME_KEYRING (from));
 
 		if (from != to) {
 			/* Start a new transfer operation between the two places */
 			seahorse_progress_prep_and_begin (cancellable, GINT_TO_POINTER (closure->num_transfers), NULL);
-			seahorse_transfer_async (from, to, keys, cancellable,
-			                         on_source_transfer_ready, g_object_ref (res));
+			seahorse_transfer_keys_async (SEAHORSE_GPGME_KEYRING (from), to, keys, cancellable,
+			                              on_source_transfer_ready, g_object_ref (res));
 			closure->num_transfers++;
 		}
 
@@ -596,7 +596,7 @@ seahorse_pgp_backend_transfer_finish (SeahorsePgpBackend *self,
 
 void
 seahorse_pgp_backend_retrieve_async (SeahorsePgpBackend *self,
-                                     GList *keyids,
+                                     const gchar **keyids,
                                      SeahorsePlace *to,
                                      GCancellable *cancellable,
                                      GAsyncReadyCallback callback,
@@ -623,8 +623,8 @@ seahorse_pgp_backend_retrieve_async (SeahorsePgpBackend *self,
 	while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&place)) {
 		/* Start a new transfer operation between the two places */
 		seahorse_progress_prep_and_begin (cancellable, GINT_TO_POINTER (closure->num_transfers), NULL);
-		seahorse_transfer_async (place, to, keyids, cancellable,
-		                         on_source_transfer_ready, g_object_ref (res));
+		seahorse_transfer_keyids_async (SEAHORSE_SERVER_SOURCE (place), to, keyids, cancellable,
+		                                on_source_transfer_ready, g_object_ref (res));
 		closure->num_transfers++;
 	}
 
@@ -656,29 +656,31 @@ seahorse_pgp_backend_retrieve_finish (SeahorsePgpBackend *self,
 
 GList *
 seahorse_pgp_backend_discover_keys (SeahorsePgpBackend *self,
-                                    GList *keyids,
+                                    const gchar **keyids,
                                     GCancellable *cancellable)
 {
 	GList *robjects = NULL;
 	const gchar *keyid;
-	GList *todiscover = NULL;
 	SeahorseGpgmeKey *key;
 	SeahorseObject *object;
-	GList *l;
+	GPtrArray *todiscover;
+	gint i;
 
 	self = self ? self : seahorse_pgp_backend_get ();
 	g_return_val_if_fail (SEAHORSE_IS_PGP_BACKEND (self), NULL);
 
+	todiscover = g_ptr_array_new ();
+
 	/* Check all the ids */
-	for (l = keyids; l != NULL; l = g_list_next (l)) {
-		keyid = l->data;
+	for (i = 0; keyids[i] != NULL; i++) {
+		keyid = keyids[i];
 
 		/* Do we know about this object? */
 		key = seahorse_gpgme_keyring_lookup (self->keyring, keyid);
 
 		/* No such object anywhere, discover it */
 		if (key == NULL) {
-			todiscover = g_list_prepend (todiscover, (gpointer)keyid);
+			g_ptr_array_add (todiscover, (gchar *)keyid);
 			continue;
 		}
 
@@ -686,20 +688,22 @@ seahorse_pgp_backend_discover_keys (SeahorsePgpBackend *self,
 		robjects = g_list_prepend (robjects, key);
 	}
 
+	g_ptr_array_add (todiscover, NULL);
+
 	/* Start a discover process on all todiscover */
 	if (todiscover != NULL &&
 	    g_settings_get_boolean (seahorse_context_settings (NULL), "server-auto-retrieve")) {
-		seahorse_pgp_backend_retrieve_async (self, todiscover, SEAHORSE_PLACE (self->keyring),
+		seahorse_pgp_backend_retrieve_async (self, (const gchar **)todiscover->pdata,
+		                                     SEAHORSE_PLACE (self->keyring),
 		                                     cancellable, NULL, NULL);
 	}
 
 	/* Add unknown objects for all these */
-	for (l = todiscover; l != NULL; l = g_list_next (l)) {
-		object = seahorse_unknown_source_add_object (self->unknown, keyid, cancellable);
+	for (i = 0; keyids[i] != NULL; i++) {
+		object = seahorse_unknown_source_add_object (self->unknown, keyids[i], cancellable);
 		robjects = g_list_prepend (robjects, object);
 	}
 
-	g_list_free (todiscover);
-
+	g_ptr_array_free (todiscover, TRUE);
 	return robjects;
 }
diff --git a/pgp/seahorse-pgp-backend.h b/pgp/seahorse-pgp-backend.h
index 51afc81..8fc3aab 100644
--- a/pgp/seahorse-pgp-backend.h
+++ b/pgp/seahorse-pgp-backend.h
@@ -90,7 +90,7 @@ gboolean               seahorse_pgp_backend_transfer_finish      (SeahorsePgpBac
                                                                   GError **error);
 
 void                   seahorse_pgp_backend_retrieve_async       (SeahorsePgpBackend *self,
-                                                                  GList *keyids,
+                                                                  const gchar **keyids,
                                                                   SeahorsePlace *to,
                                                                   GCancellable *cancellable,
                                                                   GAsyncReadyCallback callback,
@@ -101,7 +101,7 @@ gboolean               seahorse_pgp_backend_retrieve_finish      (SeahorsePgpBac
                                                                   GError **error);
 
 GList*                 seahorse_pgp_backend_discover_keys        (SeahorsePgpBackend *self,
-                                                                  GList *keyids,
+                                                                  const gchar **keyids,
                                                                   GCancellable *cancellable);
 
 G_END_DECLS
diff --git a/pgp/seahorse-pgp-key-properties.c b/pgp/seahorse-pgp-key-properties.c
index 8ee8cae..0082a75 100644
--- a/pgp/seahorse-pgp-key-properties.c
+++ b/pgp/seahorse-pgp-key-properties.c
@@ -259,19 +259,18 @@ on_pgp_signature_row_activated (GtkTreeView *treeview,
 	}
 }
 
-static GList*
-unique_slist_strings (GList *keyids)
+static void
+unique_strings (GPtrArray *keyids)
 {
-    GList *l;
-    
-    keyids = g_list_sort (keyids, (GCompareFunc)g_ascii_strcasecmp);
-    for (l = keyids; l; l = g_list_next (l)) {
-        while (l->next && l->data && l->next->data && 
-               g_ascii_strcasecmp (l->data, l->next->data) == 0)
-            keyids = g_list_delete_link (keyids, l->next);
-    }    
-    
-    return keyids;
+	gint i;
+
+	g_ptr_array_sort (keyids, (GCompareFunc)g_ascii_strcasecmp);
+	for (i = 0; i + 1 < keyids->len; ) {
+		if (g_ascii_strcasecmp (keyids->pdata[i], keyids->pdata[i + 1]) == 0)
+			g_ptr_array_remove_index (keyids, i);
+		else
+			i++;
+	}
 }
 
 /* -----------------------------------------------------------------------------
@@ -436,7 +435,7 @@ names_populate (SeahorseWidget *swidget, GtkTreeStore *store, SeahorsePgpKey *pk
 {
 	GObject *object;
 	GtkTreeIter uiditer, sigiter;
-	GList *keyids = NULL;
+	GPtrArray *keyids;
 	SeahorsePgpUid *uid;
 	GList *keys, *l;
 	GList *uids, *u;
@@ -459,25 +458,29 @@ names_populate (SeahorseWidget *swidget, GtkTreeStore *store, SeahorsePgpKey *pk
 		                    -1);
 		g_object_unref (icon);
 
+		keyids = g_ptr_array_new ();
+
 		/* Build a list of all the keyids */
 		sigs = seahorse_pgp_uid_get_signatures (uid);
 		for (s = sigs; s; s = g_list_next (s)) {
 			/* Never show self signatures, they're implied */
 			if (seahorse_pgp_key_has_keyid (pkey, seahorse_pgp_signature_get_keyid (s->data)))
 				continue;
-			keyids = g_list_prepend (keyids, (gpointer)seahorse_pgp_signature_get_keyid (s->data));
+			g_ptr_array_add (keyids, (gpointer)seahorse_pgp_signature_get_keyid (s->data));
 		}
 
+		g_ptr_array_add (keyids, NULL);
+
 		/*
 		 * Pass it to 'DiscoverKeys' for resolution/download, cancellable
 		 * ties search scope together
 		 */
 		cancellable = g_cancellable_new ();
-		keys = seahorse_pgp_backend_discover_keys (NULL, keyids, cancellable);
+		keys = seahorse_pgp_backend_discover_keys (NULL, (const gchar **)keyids->pdata, cancellable);
 		g_object_unref (cancellable);
-		g_list_free (keyids);
+		g_ptr_array_free (keyids, TRUE);
 		keyids = NULL;
-        
+
 		/* Add the keys to the store */
 		for (l = keys; l; l = g_list_next (l)) {
 			object = G_OBJECT (l->data);
@@ -1573,7 +1576,7 @@ signatures_populate_model (SeahorseWidget *swidget, SeahorseObjectModel *skmodel
 	GtkTreeIter iter;
 	GtkWidget *widget;
 	gboolean have_sigs = FALSE;
-	GList *rawids = NULL;
+	GPtrArray *rawids;
 	GList *keys, *l, *uids;
 	GList *sigs, *s;
 	GCancellable *cancellable;
@@ -1582,7 +1585,8 @@ signatures_populate_model (SeahorseWidget *swidget, SeahorseObjectModel *skmodel
 	widget = GTK_WIDGET (seahorse_widget_get_widget (swidget, "signatures-tree"));
 	if (!widget)
 		return;
-    
+
+	rawids = g_ptr_array_new ();
 	uids = seahorse_pgp_key_get_uids (pkey);
 
 	/* Build a list of all the keyids */        
@@ -1593,37 +1597,39 @@ signatures_populate_model (SeahorseWidget *swidget, SeahorseObjectModel *skmodel
 			if (seahorse_pgp_key_has_keyid (pkey, seahorse_pgp_signature_get_keyid (s->data)))
 				continue;
 			have_sigs = TRUE;
-			rawids = g_list_prepend (rawids, (gpointer)seahorse_pgp_signature_get_keyid (s->data));
+			g_ptr_array_add (rawids, (gchar *)seahorse_pgp_signature_get_keyid (s->data));
 		}
 	}
-    
+
+	/* Strip out duplicates */
+	unique_strings (rawids);
+	g_ptr_array_add (rawids, NULL);
+
 	/* Only show signatures area when there are signatures */
 	seahorse_widget_set_visible (swidget, "signatures-area", have_sigs);
 
 	if (skmodel) {
-    
-		/* String out duplicates */
-		rawids = unique_slist_strings (rawids);
 
 		/*
 		 * Pass it to 'DiscoverKeys' for resolution/download. cancellable ties
 		 * search scope together
 		 */
 		cancellable = g_cancellable_new ();
-		keys = seahorse_pgp_backend_discover_keys (NULL, rawids, cancellable);
+		keys = seahorse_pgp_backend_discover_keys (NULL, (const gchar **)rawids->pdata, cancellable);
 		g_object_unref (cancellable);
-		g_list_free (rawids);
-		rawids = NULL;
-        
+
 		/* Add the keys to the store */
 		for (l = keys; l; l = g_list_next (l)) {
 			object = G_OBJECT (l->data);
 			gtk_tree_store_append (GTK_TREE_STORE (skmodel), &iter, NULL);
-            
+
 			/* This calls the 'update-row' callback, to set the values for the key */
 			seahorse_object_model_set_row_object (SEAHORSE_OBJECT_MODEL (skmodel), &iter, object);
 		}
 	}
+
+	g_ptr_array_free (rawids, TRUE);
+	rawids = NULL;
 }
 
 /* Refilter when the user toggles the 'only show trusted' checkbox */
diff --git a/pgp/seahorse-server-source.c b/pgp/seahorse-server-source.c
index d146cab..2a7a5d0 100644
--- a/pgp/seahorse-server-source.c
+++ b/pgp/seahorse-server-source.c
@@ -398,7 +398,7 @@ seahorse_server_source_search_finish (SeahorseServerSource *self,
 
 void
 seahorse_server_source_export_async (SeahorseServerSource *self,
-                                     GList *keyids,
+                                     const gchar **keyids,
                                      GCancellable *cancellable,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
diff --git a/pgp/seahorse-server-source.h b/pgp/seahorse-server-source.h
index 3aab05d..c9ceafe 100644
--- a/pgp/seahorse-server-source.h
+++ b/pgp/seahorse-server-source.h
@@ -65,7 +65,7 @@ struct _SeahorseServerSourceClass {
 	GObjectClass parent_class;
 
 	void            (*export_async)          (SeahorseServerSource *source,
-	                                          GList *ids,
+	                                          const gchar **keyids,
 	                                          GCancellable *cancellable,
 	                                          GAsyncReadyCallback callback,
 	                                          gpointer user_data);
@@ -103,7 +103,7 @@ gboolean               seahorse_server_source_search_finish    (SeahorseServerSo
                                                                 GError **error);
 
 void                   seahorse_server_source_export_async     (SeahorseServerSource *self,
-                                                                GList *ids,
+                                                                const gchar **keyids,
                                                                 GCancellable *cancellable,
                                                                 GAsyncReadyCallback callback,
                                                                 gpointer user_data);
diff --git a/pgp/seahorse-transfer.c b/pgp/seahorse-transfer.c
index 31494e8..5b6c8fd 100644
--- a/pgp/seahorse-transfer.c
+++ b/pgp/seahorse-transfer.c
@@ -42,6 +42,7 @@ typedef struct {
 	GCancellable *cancellable;
 	SeahorsePlace *from;
 	SeahorsePlace *to;
+	gchar **keyids;
 	GList *keys;
 } TransferClosure;
 
@@ -52,6 +53,7 @@ transfer_closure_free (gpointer user_data)
 	g_clear_object (&closure->from);
 	g_clear_object (&closure->to);
 	g_clear_object (&closure->cancellable);
+	g_strfreev (closure->keyids);
 	seahorse_object_list_free (closure->keys);
 	g_free (closure);
 }
@@ -143,23 +145,19 @@ on_timeout_start_transfer (gpointer user_data)
 	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
 	TransferClosure *closure = g_simple_async_result_get_op_res_gpointer (res);
 	SeahorseExporter *exporter;
-	GList *keyids, *l;
 
 	g_assert (SEAHORSE_IS_PLACE (closure->from));
-	g_assert (closure->keys);
 
 	seahorse_progress_begin (closure->cancellable, &closure->from);
 	if (SEAHORSE_IS_SERVER_SOURCE (closure->from)) {
-		keyids = NULL;
-		for (l = closure->keys; l != NULL; l = g_list_next (l))
-			keyids = g_list_prepend (keyids, (gpointer)seahorse_pgp_key_get_keyid (l->data));
-		keyids = g_list_reverse (keyids);
+		g_assert (closure->keyids != NULL);
 		seahorse_server_source_export_async (SEAHORSE_SERVER_SOURCE (closure->from),
-		                                     keyids, closure->cancellable,
-		                                     on_source_export_ready, g_object_ref (res));
-		g_list_free (keyids);
+		                                     (const gchar **)closure->keyids,
+		                                     closure->cancellable, on_source_export_ready,
+		                                     g_object_ref (res));
 
 	} else if (SEAHORSE_IS_GPGME_KEYRING (closure->from)) {
+		g_assert (closure->keys != NULL);
 		exporter = seahorse_gpgme_exporter_new_multiple (closure->keys, TRUE);
 		seahorse_exporter_export_async (exporter, closure->cancellable,
 		                                on_source_export_ready, g_object_ref (res));
@@ -173,21 +171,21 @@ on_timeout_start_transfer (gpointer user_data)
 }
 
 void
-seahorse_transfer_async (SeahorsePlace *from,
-                         SeahorsePlace *to,
-                         GList *keys,
-                         GCancellable *cancellable,
-                         GAsyncReadyCallback callback,
-                         gpointer user_data)
+seahorse_transfer_keys_async (SeahorseGpgmeKeyring *from,
+                              SeahorsePlace *to,
+                              GList *keys,
+                              GCancellable *cancellable,
+                              GAsyncReadyCallback callback,
+                              gpointer user_data)
 {
 	GSimpleAsyncResult *res;
 	TransferClosure *closure;
 
-	g_return_if_fail (SEAHORSE_PLACE (from));
+	g_return_if_fail (SEAHORSE_IS_GPGME_KEYRING (from));
 	g_return_if_fail (SEAHORSE_PLACE (to));
 
 	res = g_simple_async_result_new (NULL, callback, user_data,
-	                                 seahorse_transfer_async);
+	                                 seahorse_transfer_finish);
 
 	if (!keys) {
 		g_simple_async_result_complete_in_idle (res);
@@ -219,12 +217,59 @@ seahorse_transfer_async (SeahorsePlace *from,
 	g_object_unref (res);
 }
 
+void
+seahorse_transfer_keyids_async (SeahorseServerSource *from,
+                                SeahorsePlace *to,
+                                const gchar **keyids,
+                                GCancellable *cancellable,
+                                GAsyncReadyCallback callback,
+                                gpointer user_data)
+{
+	GSimpleAsyncResult *res;
+	TransferClosure *closure;
+
+	g_return_if_fail (SEAHORSE_IS_SERVER_SOURCE (from));
+	g_return_if_fail (SEAHORSE_PLACE (to));
+
+	res = g_simple_async_result_new (NULL, callback, user_data,
+	                                 seahorse_transfer_finish);
+
+	if (!keyids || !keyids[0]) {
+		g_simple_async_result_complete_in_idle (res);
+		g_object_unref (res);
+		return;
+	}
+
+	closure = g_new0 (TransferClosure, 1);
+	closure->cancellable = cancellable ? g_object_ref (cancellable) : cancellable;
+	closure->from = g_object_ref (from);
+	closure->to = g_object_ref (to);
+	closure->keyids = g_strdupv ((gchar **)keyids);
+	g_simple_async_result_set_op_res_gpointer (res, closure, transfer_closure_free);
+
+	seahorse_progress_prep (cancellable, &closure->from,
+	                        SEAHORSE_IS_GPGME_KEYRING (closure->from) ?
+	                        _("Exporting data") : _("Retrieving data"));
+	seahorse_progress_prep (cancellable, &closure->to,
+	                        SEAHORSE_IS_GPGME_KEYRING (closure->to) ?
+	                        _("Importing data") : _("Sending data"));
+
+	seahorse_debug ("starting export");
+
+	/* We delay and continue from a callback */
+	g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 0,
+	                            on_timeout_start_transfer,
+	                            g_object_ref (res), g_object_unref);
+
+	g_object_unref (res);
+}
+
 gboolean
 seahorse_transfer_finish (GAsyncResult *result,
                           GError **error)
 {
 	g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
-	                      seahorse_transfer_async), FALSE);
+	                      seahorse_transfer_finish), FALSE);
 
 	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
 		return FALSE;
diff --git a/pgp/seahorse-transfer.h b/pgp/seahorse-transfer.h
index 671e415..9e9ff63 100644
--- a/pgp/seahorse-transfer.h
+++ b/pgp/seahorse-transfer.h
@@ -27,7 +27,14 @@
 
 #include "seahorse-server-source.h"
 
-void            seahorse_transfer_async         (SeahorsePlace *from,
+void            seahorse_transfer_keyids_async  (SeahorseServerSource *from,
+                                                 SeahorsePlace *to,
+                                                 const gchar **keyids,
+                                                 GCancellable *cancellable,
+                                                 GAsyncReadyCallback callback,
+                                                 gpointer user_data);
+
+void            seahorse_transfer_keys_async    (SeahorseGpgmeKeyring *from,
                                                  SeahorsePlace *to,
                                                  GList *keys,
                                                  GCancellable *cancellable,
diff --git a/pgp/seahorse-unknown-source.c b/pgp/seahorse-unknown-source.c
index 27f1d8f..1c428cd 100644
--- a/pgp/seahorse-unknown-source.c
+++ b/pgp/seahorse-unknown-source.c
@@ -22,14 +22,26 @@
 
 #include "config.h"
 
-#include <glib/gi18n.h>
-
 #include "seahorse-pgp-key.h"
 #include "seahorse-unknown-source.h"
 
+#include "seahorse-place.h"
 #include "seahorse-registry.h"
 #include "seahorse-unknown.h"
 
+#include <gcr/gcr-base.h>
+
+#include <glib/gi18n.h>
+
+enum {
+	PROP_0,
+	PROP_LABEL,
+	PROP_DESCRIPTION,
+	PROP_ICON,
+	PROP_URI,
+	PROP_ACTIONS
+};
+
 struct _SeahorseUnknownSource {
 	GObject parent;
 	GHashTable *keys;
@@ -39,11 +51,14 @@ struct _SeahorseUnknownSourceClass {
 	GObjectClass parent_class;
 };
 
-G_DEFINE_TYPE (SeahorseUnknownSource, seahorse_unknown_source, G_TYPE_OBJECT);
+static void      seahorse_unknown_source_collection_iface      (GcrCollectionIface *iface);
 
-/* -----------------------------------------------------------------------------
- * OBJECT
- */
+static void      seahorse_unknown_source_place_iface           (SeahorsePlaceIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (SeahorseUnknownSource, seahorse_unknown_source, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GCR_TYPE_COLLECTION, seahorse_unknown_source_collection_iface);
+                         G_IMPLEMENT_INTERFACE (SEAHORSE_TYPE_PLACE, seahorse_unknown_source_place_iface);
+);
 
 static void
 seahorse_unknown_source_init (SeahorseUnknownSource *self)
@@ -54,6 +69,32 @@ seahorse_unknown_source_init (SeahorseUnknownSource *self)
 }
 
 static void
+seahorse_unknown_source_get_property (GObject *obj,
+                                      guint prop_id,
+                                      GValue *value,
+                                      GParamSpec *pspec)
+{
+	switch (prop_id) {
+	case PROP_LABEL:
+		g_value_set_string (value, "");
+		break;
+	case PROP_DESCRIPTION:
+	case PROP_URI:
+		g_value_set_string (value, NULL);
+		break;
+	case PROP_ICON:
+		g_value_set_object (value, NULL);
+		break;
+	case PROP_ACTIONS:
+		g_value_set_object (value, NULL);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
 seahorse_unknown_source_finalize (GObject *obj)
 {
 	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (obj);
@@ -67,7 +108,52 @@ static void
 seahorse_unknown_source_class_init (SeahorseUnknownSourceClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	gobject_class->get_property = seahorse_unknown_source_get_property;
 	gobject_class->finalize = seahorse_unknown_source_finalize;
+
+	g_object_class_override_property (gobject_class, PROP_LABEL, "label");
+	g_object_class_override_property (gobject_class, PROP_DESCRIPTION, "description");
+	g_object_class_override_property (gobject_class, PROP_ICON, "icon");
+	g_object_class_override_property (gobject_class, PROP_ACTIONS, "actions");
+	g_object_class_override_property (gobject_class, PROP_URI, "uri");
+}
+
+static guint
+seahorse_unknown_source_get_length (GcrCollection *collection)
+{
+	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
+	return g_hash_table_size (self->keys);
+}
+
+static GList *
+seahorse_unknown_source_get_objects (GcrCollection *collection)
+{
+	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
+	return g_hash_table_get_values (self->keys);
+}
+
+static gboolean
+seahorse_unknown_source_contains (GcrCollection *collection,
+                                  GObject *object)
+{
+	SeahorseUnknownSource *self = SEAHORSE_UNKNOWN_SOURCE (collection);
+	const gchar *identifier = seahorse_object_get_identifier (SEAHORSE_OBJECT (object));
+	return g_hash_table_lookup (self->keys, identifier) == object;
+}
+
+static void
+seahorse_unknown_source_collection_iface (GcrCollectionIface *iface)
+{
+	iface->contains = seahorse_unknown_source_contains;
+	iface->get_length = seahorse_unknown_source_get_length;
+	iface->get_objects = seahorse_unknown_source_get_objects;
+}
+
+static void
+seahorse_unknown_source_place_iface (SeahorsePlaceIface *iface)
+{
+	/* no implementation */
 }
 
 SeahorseUnknownSource*



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