[gnome-packagekit/glib2: 57/79] moo



commit 20f7af54346b65e20e079342f7a3fc463d6e69e2
Author: Richard Hughes <richard hughsie com>
Date:   Sat Oct 3 12:46:23 2009 +0100

    moo

 src/gpk-application.c   | 1574 ++++++++++++++++++++++++++---------------------
 src/gpk-check-update.c  |    2 +-
 src/gpk-service-pack.c  |    3 +-
 src/gpk-update-viewer.c |   10 +-
 4 files changed, 886 insertions(+), 703 deletions(-)
---
diff --git a/src/gpk-application.c b/src/gpk-application.c
index 6e444da..293ea74 100644
--- a/src/gpk-application.c
+++ b/src/gpk-application.c
@@ -96,11 +96,12 @@ struct GpkApplicationPrivate
 	PkSearchType		 search_type;
 	PkSearchMode		 search_mode;
 	PkActionMode		 action;
-	GPtrArray		*package_array;
+	PkPackageSack		*package_sack;
 	GtkWidget		*image_status;
 	GpkHelperRun		*helper_run;
 	guint			 status_id;
 	PkStatusEnum		 status_last;
+	GCancellable		*cancellable;
 };
 
 enum {
@@ -146,8 +147,7 @@ static guint	     signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (GpkApplication, gpk_application, G_TYPE_OBJECT)
 
-static void gpk_application_categories_finished (GpkApplication *application);
-static gboolean gpk_application_perform_search (GpkApplication *application);
+static void gpk_application_perform_search (GpkApplication *application);
 
 /**
  * gpk_application_class_init:
@@ -353,7 +353,7 @@ gpk_application_set_buttons_apply_clear (GpkApplication *application)
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
 	/* okay to apply? */
-	len = application->priv->package_array->len;
+	len = pk_package_sack_get_size (application->priv->package_sack);
 	if (len == 0) {
 		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
 		gtk_widget_set_sensitive (widget, FALSE);
@@ -441,6 +441,7 @@ gpk_application_install (GpkApplication *application)
 	gboolean ret;
 	gchar *package_id_selected = NULL;
 	gchar *summary_selected = NULL;
+	PkPackage *package;
 
 	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
 
@@ -453,10 +454,9 @@ gpk_application_install (GpkApplication *application)
 
 	/* changed mind, or wrong mode */
 	if (application->priv->action == PK_ACTION_REMOVE) {
-		ret = pk_package_array_contains (application->priv->package_array, package_id_selected);
+		ret = pk_package_sack_remove_package_by_id (application->priv->package_sack, package_id_selected);
 		if (ret) {
 			egg_debug ("removed %s from package array", package_id_selected);
-			g_ptr_array_remove (application->priv->package_array, package_id_selected);
 
 			/* correct buttons */
 			gpk_application_allow_install (application, FALSE);
@@ -470,8 +470,8 @@ gpk_application_install (GpkApplication *application)
 	}
 
 	/* already added */
-	ret = !pk_package_array_contains (application->priv->package_array, package_id_selected);
-	if (!ret) {
+	package = pk_package_sack_find_by_id (application->priv->package_sack, package_id_selected);
+	if (package != NULL) {
 		egg_warning ("already added");
 		goto out;
 	}
@@ -480,7 +480,14 @@ gpk_application_install (GpkApplication *application)
 	application->priv->action = PK_ACTION_INSTALL;
 
 	/* add to array */
-	g_ptr_array_add_xxxwithrecount (application->priv->package_array, PK_INFO_ENUM_AVAILABLE, package_id_selected, summary_selected);
+	package = pk_package_new ();
+	g_object_set (package,
+		      "info", PK_INFO_ENUM_AVAILABLE,
+		      "id", package_id_selected,
+		      "summary", summary_selected,
+		      NULL);
+	pk_package_sack_add_package (application->priv->package_sack, package);
+	g_object_unref (package);
 
 	/* correct buttons */
 	gpk_application_allow_install (application, FALSE);
@@ -513,13 +520,206 @@ gpk_application_strcmp_indirect (gchar **a, gchar **b)
 }
 
 /**
+ * gpk_application_get_files_cb:
+ **/
+static void
+gpk_application_get_files_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	PkItemFiles *item;
+	GPtrArray *array_sort;
+	gchar **files;
+	gchar *title;
+	GtkWindow *window;
+	GtkWidget *dialog;
+	gchar *package_id_selected = NULL;
+	gboolean ret;
+	gchar **split;
+
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get files: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get files: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_files_array (results);
+	if (array->len != 1)
+		goto out;
+
+	/* assume only one option */
+	item = g_ptr_array_index (array, 0);
+
+	/* get selection */
+	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
+	if (!ret) {
+		egg_warning ("no package selected");
+		goto out;
+	}
+
+	/* convert to pointer array */
+	array_sort = pk_strv_to_ptr_array (item->files);
+	g_ptr_array_sort (array_sort, (GCompareFunc) gpk_application_strcmp_indirect);
+
+	/* title */
+	split = pk_package_id_split (package_id_selected);
+	/* TRANSLATORS: title: how many files are installed by the application */
+	title = g_strdup_printf (ngettext ("%i file installed by %s",
+					   "%i files installed by %s",
+					   array_sort->len), array_sort->len, split[PK_PACKAGE_ID_NAME]);
+
+	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
+	gpk_dialog_embed_file_list_widget (GTK_DIALOG (dialog), array_sort);
+	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+	gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 250);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+out:
+	g_free (title);
+	g_ptr_array_unref (array_sort);
+	g_strfreev (files);
+	g_strfreev (split);
+	g_free (package_id_selected);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+
+/**
+ * gpk_application_status_changed_timeout_cb:
+ **/
+static gboolean
+gpk_application_status_changed_timeout_cb (GpkApplication *application)
+{
+	const gchar *text;
+	GtkWidget *widget;
+
+	/* set the text and show */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "label_status"));
+	text = gpk_status_enum_to_localised_text (application->priv->status_last);
+	gtk_label_set_label (GTK_LABEL (widget), text);
+
+	/* set icon */
+	gpk_set_animated_icon_from_status (GPK_ANIMATED_ICON (application->priv->image_status),
+					   application->priv->status_last, GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+	/* show containing box */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
+	gtk_widget_show (widget);
+
+	/* never repeat */
+	application->priv->status_id = 0;
+	return FALSE;
+}
+
+#if 0
+	if (application->priv->action == PK_ACTION_INSTALL ||
+	    application->priv->action == PK_ACTION_REMOVE) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_clear"));
+		gtk_widget_set_sensitive (widget, FALSE);
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_find"));
+		gtk_widget_set_sensitive (widget, FALSE);
+	}
+#endif
+
+/**
+ * gpk_application_progress_cb:
+ **/
+static void
+gpk_application_progress_cb (PkProgress *progress, PkProgressType type, GpkApplication *application)
+{
+	PkStatusEnum status;
+	gint percentage;
+	gboolean allow_cancel;
+	GtkWidget *widget;
+
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+
+	g_object_get (progress,
+		      "status", &status,
+		      "percentage", &percentage,
+		      "allow-cancel", &allow_cancel,
+		      NULL);
+
+	if (type == PK_PROGRESS_TYPE_STATUS) {
+		egg_debug ("now %s", pk_status_enum_to_text (status));
+
+		if (status == PK_STATUS_ENUM_FINISHED) {
+
+			/* re-enable UI */
+			widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
+			gtk_widget_set_sensitive (widget, TRUE);
+
+			/* we've not yet shown, so don't bother */
+			if (application->priv->status_id > 0) {
+				g_source_remove (application->priv->status_id);
+				application->priv->status_id = 0;
+			}
+
+			widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
+			gtk_widget_hide (widget);
+			gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (application->priv->image_status), FALSE);
+			goto out;
+		}
+
+		/* already pending show */
+		if (application->priv->status_id > 0)
+			goto out;
+
+		/* only show after some time in the transaction */
+		application->priv->status_id = g_timeout_add (GPK_UI_STATUS_SHOW_DELAY, (GSourceFunc) gpk_application_status_changed_timeout_cb, application);
+
+		/* save for the callback */
+		application->priv->status_last = status;
+
+	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+		egg_debug ("now %i", percentage);
+	} else if (type == PK_PROGRESS_TYPE_ALLOW_CANCEL) {
+		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_cancel"));
+		gtk_widget_set_sensitive (widget, allow_cancel);
+	}
+out:
+	return;
+}
+
+/**
  * gpk_application_menu_files_cb:
  **/
 static void
 gpk_application_menu_files_cb (GtkAction *action, GpkApplication *application)
 {
 	gboolean ret;
-	GError *error = NULL;
 	gchar **package_ids = NULL;
 	gchar *package_id_selected = NULL;
 
@@ -534,12 +734,9 @@ gpk_application_menu_files_cb (GtkAction *action, GpkApplication *application)
 
 	/* set correct view */
 	package_ids = pk_package_ids_from_id (package_id_selected);
-	ret = pk_client_get_files (application->priv->client, package_ids, &error);
-	if (!ret) {
-		egg_warning ("cannot get file lists for %s: %s", package_id_selected, error->message);
-		g_error_free (error);
-		goto out;
-	}
+	pk_client_get_files_async (application->priv->client, package_ids, application->priv->cancellable,
+				   (PkProgressCallback) gpk_application_progress_cb, application,
+				   (GAsyncReadyCallback) gpk_application_get_files_cb, application);
 out:
 	g_free (package_id_selected);
 	g_strfreev (package_ids);
@@ -552,9 +749,9 @@ static gboolean
 gpk_application_remove (GpkApplication *application)
 {
 	gboolean ret;
-	gchar *id;
 	gchar *package_id_selected = NULL;
 	gchar *summary_selected = NULL;
+	PkPackage *package;
 
 	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
 
@@ -567,10 +764,9 @@ gpk_application_remove (GpkApplication *application)
 
 	/* changed mind, or wrong mode */
 	if (application->priv->action == PK_ACTION_INSTALL) {
-		ret = pk_package_array_contains (application->priv->package_array, package_id_selected);
+		ret = pk_package_sack_remove_package_by_id (application->priv->package_sack, package_id_selected);
 		if (ret) {
 			egg_debug ("removed %s from package array", package_id_selected);
-			g_ptr_array_remove (application->priv->package_array, package_id_selected);
 
 			/* correct buttons */
 			gpk_application_allow_install (application, TRUE);
@@ -584,14 +780,21 @@ gpk_application_remove (GpkApplication *application)
 	}
 
 	/* already added */
-	ret = !pk_package_array_contains (application->priv->package_array, package_id_selected);
+	ret = (pk_package_sack_find_by_id (application->priv->package_sack, package_id_selected) != NULL);
 	if (!ret) {
 		egg_warning ("already added");
 		goto out;
 	}
 
 	application->priv->action = PK_ACTION_REMOVE;
-	g_ptr_array_add_xxxwithrecount (application->priv->package_array, PK_INFO_ENUM_AVAILABLE, package_id_selected, summary_selected);
+	package = pk_package_new ();
+	g_object_set (package,
+		      "info", PK_INFO_ENUM_AVAILABLE,
+		      "id", package_id_selected,
+		      "summary", summary_selected,
+		      NULL);
+	pk_package_sack_add_package (application->priv->package_sack, package);
+	g_object_unref (package);
 
 	/* correct buttons */
 	gpk_application_allow_install (application, TRUE);
@@ -662,12 +865,99 @@ gpk_application_menu_run_cb (GtkAction *action, GpkApplication *application)
 }
 
 /**
+ * gpk_application_get_requires_cb:
+ **/
+static void
+gpk_application_get_requires_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	GtkWindow *window;
+	gchar *name = NULL;
+	gchar *title = NULL;
+	gchar *message = NULL;
+	gchar **package_ids = NULL;
+	GtkWidget *dialog;
+	gchar *package_id_selected = NULL;
+	gboolean ret;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get requires: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get requires: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* get selection */
+	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
+	if (!ret) {
+		egg_warning ("no package selected");
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_package_array (results);
+
+	/* empty array */
+	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+	if (array->len == 0) {
+		gpk_error_dialog_modal (window,
+					/* TRANSLATORS: no packages returned */
+					_("No packages"),
+					/* TRANSLATORS: this package is not required by any others */
+					_("No other packages require this package"), NULL);
+		goto out;
+	}
+
+	package_ids = pk_package_ids_from_id (package_id_selected);
+	name = gpk_dialog_package_id_name_join_locale (package_ids);
+	/* TRANSLATORS: title: how many packages require this package */
+	title = g_strdup_printf (ngettext ("%i package requires %s",
+					   "%i packages require %s",
+					   array->len), array->len, name);
+
+	/* TRANSLATORS: show a array of packages for the package */
+	message = g_strdup_printf (ngettext ("Packages listed below require %s to function correctly.",
+					     "Packages listed below require %s to function correctly.",
+					     array->len), name);
+
+	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
+	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+	gpk_dialog_embed_package_list_widget (GTK_DIALOG (dialog), array);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+out:
+	g_free (package_id_selected);
+	g_strfreev (package_ids);
+	g_free (name);
+	g_free (title);
+	g_free (message);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
  * gpk_application_menu_requires_cb:
  **/
 static void
 gpk_application_menu_requires_cb (GtkAction *action, GpkApplication *application)
 {
-	GError *error = NULL;
 	gboolean ret;
 	gchar **package_ids = NULL;
 	gchar *package_id_selected = NULL;
@@ -681,16 +971,101 @@ gpk_application_menu_requires_cb (GtkAction *action, GpkApplication *application
 
 	/* get the requires */
 	package_ids = pk_package_ids_from_id (package_id_selected);
-	ret = pk_client_get_requires (application->priv->client, PK_FILTER_ENUM_NONE,
-				      package_ids, TRUE, &error);
-	if (!ret) {
-		egg_warning ("failed to get requires: %s", error->message);
+	pk_client_get_requires_async (application->priv->client, PK_FILTER_ENUM_NONE,
+				      package_ids, TRUE, application->priv->cancellable,
+				      (PkProgressCallback) gpk_application_progress_cb, application,
+				      (GAsyncReadyCallback) gpk_application_get_requires_cb, application);
+out:
+	g_free (package_id_selected);
+	g_strfreev (package_ids);
+}
+
+/**
+ * gpk_application_get_depends_cb:
+ **/
+static void
+gpk_application_get_depends_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	GtkWindow *window;
+	gchar *name = NULL;
+	gchar *title = NULL;
+	gchar *message = NULL;
+	gchar **package_ids = NULL;
+	GtkWidget *dialog;
+	gchar *package_id_selected = NULL;
+	gboolean ret;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get depends: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get depends: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_package_array (results);
+
+	/* get selection */
+	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
+	if (!ret) {
+		egg_warning ("no package selected");
+		goto out;
+	}
+
+	/* empty array */
+	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
+	if (array->len == 0) {
+		gpk_error_dialog_modal (window,
+					/* TRANSLATORS: no packages returned */
+					_("No packages"),
+					/* TRANSLATORS: this package does not depend on any others */
+					_("This package does not depends on any others"), NULL);
+		goto out;
+	}
+
+	package_ids = pk_package_ids_from_id (package_id_selected);
+	name = gpk_dialog_package_id_name_join_locale (package_ids);
+	/* TRANSLATORS: title: show the number of other packages we depend on */
+	title = g_strdup_printf (ngettext ("%i additional package is required for %s",
+					   "%i additional packages are required for %s",
+					   array->len), array->len, name);
+
+	/* TRANSLATORS: message: show the array of dependant packages for this package */
+	message = g_strdup_printf (ngettext ("Packages listed below are required for %s to function correctly.",
+					     "Packages listed below are required for %s to function correctly.",
+					     array->len), name);
+
+	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
+	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+	gpk_dialog_embed_package_list_widget (GTK_DIALOG (dialog), array);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (GTK_WIDGET (dialog));
 out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 	g_free (package_id_selected);
 	g_strfreev (package_ids);
+	g_free (name);
+	g_free (title);
+	g_free (message);
 }
 
 /**
@@ -699,7 +1074,6 @@ out:
 static void
 gpk_application_menu_depends_cb (GtkAction *action, GpkApplication *application)
 {
-	GError *error = NULL;
 	gboolean ret;
 	gchar **package_ids = NULL;
 	gchar *package_id_selected = NULL;
@@ -713,13 +1087,10 @@ gpk_application_menu_depends_cb (GtkAction *action, GpkApplication *application)
 
 	/* get the depends */
 	package_ids = pk_package_ids_from_id (package_id_selected);
-	ret = pk_client_get_depends (application->priv->client, PK_FILTER_ENUM_NONE,
-				     package_ids, TRUE, &error);
-	if (!ret) {
-		egg_warning ("failed to get depends: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
+	pk_client_get_depends_async (application->priv->client, PK_FILTER_ENUM_NONE,
+				     package_ids, TRUE, application->priv->cancellable,
+				     (PkProgressCallback) gpk_application_progress_cb, application,
+				     (GAsyncReadyCallback) gpk_application_get_depends_cb, application);
 out:
 	g_free (package_id_selected);
 	g_strfreev (package_ids);
@@ -844,114 +1215,6 @@ gpk_application_text_format_display (GpkApplication *application, const gchar *a
 }
 
 /**
- * gpk_application_details_cb:
- **/
-static void
-gpk_application_details_cb (PkClient *client, PkItemDetails *item, GpkApplication *application)
-{
-	GtkWidget *widget;
-	gchar *text;
-	gchar *value;
-	const gchar *repo_name;
-	const gchar *group;
-	gboolean installed;
-	gchar **split = NULL;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	split = pk_package_id_split (item->package_id);
-	installed = g_strcmp0 (split[PK_PACKAGE_ID_DATA], "installed") == 0;
-
-	/* hide to start */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow_detail"));
-	gtk_widget_show (widget);
-
-	gtk_list_store_clear (application->priv->details_store);
-
-	/* if a collection, mark as such */
-	if (g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") == 0)
-		/* TRANSLATORS: the type of package is a collection (metagroup) */
-		gpk_application_add_detail_item (application, _("Type"), _("Collection"), NULL);
-
-	/* homepage */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_homepage"));
-	if (egg_strzero (item->url) == FALSE) {
-		gtk_widget_set_sensitive (widget, TRUE);
-
-		/* TRANSLATORS: tooltip: go to the web address */
-		text = g_strdup_printf (_("Visit %s"), item->url);
-		gtk_widget_set_tooltip_text (widget, text);
-		g_free (text);
-
-		/* TRANSLATORS: add an entry to go to the project home page */
-		gpk_application_add_detail_item (application, _("Project"), _("Homepage"), item->url);
-
-		/* save the url for the button */
-		g_free (application->priv->url);
-		application->priv->url = g_strdup (item->url);
-
-	} else {
-		gtk_widget_set_sensitive (widget, FALSE);
-	}
-
-	/* group */
-	if (item->group != PK_GROUP_ENUM_UNKNOWN) {
-		group = gpk_group_enum_to_localised_text (item->group);
-		/* TRANSLATORS: the group the package belongs in */
-		gpk_application_add_detail_item (application, _("Group"), group, NULL);
-	}
-
-	/* group */
-	if (!egg_strzero (item->license)) {
-		/* TRANSLATORS: the licence string for the package */
-		gpk_application_add_detail_item (application, _("License"), item->license, NULL);
-	}
-
-	/* menu path */
-	value = gpk_desktop_guess_best_file (application->priv->desktop, split[PK_PACKAGE_ID_NAME]);
-	if (value != NULL) {
-		text = gpk_desktop_get_menu_path (value);
-		if (text != NULL) {
-			/* TRANSLATORS: the path in the menu, e.g. Applications -> Games */
-			gpk_application_add_detail_item (application, _("Menu"), text, NULL);
-		}
-		g_free (text);
-	}
-	g_free (value);
-
-	/* set the description */
-	text = gpk_application_text_format_display (application, item->description);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
-	gpk_application_set_text_buffer (widget, text);
-	g_free (text);
-
-	/* if non-zero, set the size */
-	if (item->size > 0) {
-		/* set the size */
-		value = g_format_size_for_display (item->size);
-		if (g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") == 0)
-			/* TRANSLATORS: the size of the meta package */
-			gpk_application_add_detail_item (application, _("Size"), value, NULL);
-		else if (installed)
-			/* TRANSLATORS: the installed size in bytes of the package */
-			gpk_application_add_detail_item (application, _("Installed size"), value, NULL);
-		else
-			/* TRANSLATORS: the download size of the package */
-			gpk_application_add_detail_item (application, _("Download size"), value, NULL);
-		g_free (value);
-	}
-
-	/* set the repo text, or hide if installed */
-	if (!installed && g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") != 0) {
-		/* get the full name of the repo from the repo_id */
-		repo_name = gpk_application_get_full_repo_name (application, split[PK_PACKAGE_ID_DATA]);
-		/* TRANSLATORS: where the package came from, the software source name */
-		gpk_application_add_detail_item (application, _("Source"), repo_name, NULL);
-	}
-	g_strfreev (split);
-}
-
-/**
  * gpk_application_add_item_to_results:
  **/
 static void
@@ -977,7 +1240,7 @@ gpk_application_add_item_to_results (GpkApplication *application, const PkItemPa
 	application->priv->has_package = TRUE;
 
 	/* are we in the package array? */
-	in_queue = pk_package_array_contains (application->priv->package_array, item->package_id);
+	in_queue = (pk_package_sack_find_by_id (application->priv->package_sack, item->package_id) != NULL);
 	installed = (item->info == PK_INFO_ENUM_INSTALLED) || (item->info == PK_INFO_ENUM_COLLECTION_INSTALLED);
 
 	if (installed)
@@ -1025,33 +1288,7 @@ gpk_application_add_item_to_results (GpkApplication *application, const PkItemPa
 	g_free (text);
 }
 
-/**
- * gpk_application_package_cb:
- **/
-static void
-gpk_application_package_cb (PkClient *client, const PkItemPackage *item, GpkApplication *application)
-{
-	PkRoleEnum role;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	/* ignore not search data */
-	g_object_get (client,
-		      "role", &role,
-		      NULL);
-	if (role == PK_ROLE_ENUM_GET_DEPENDS ||
-	    role == PK_ROLE_ENUM_GET_REQUIRES)
-		return;
-
-	/* ignore progress */
-	if (item->info != PK_INFO_ENUM_INSTALLED && item->info != PK_INFO_ENUM_AVAILABLE &&
-	    item->info != PK_INFO_ENUM_COLLECTION_INSTALLED && item->info != PK_INFO_ENUM_COLLECTION_AVAILABLE)
-		return;
-
-	/* add to array */
-	gpk_application_add_item_to_results (application, item);
-}
-
+#if 0
 /**
  * gpk_application_error_code_cb:
  **/
@@ -1069,6 +1306,7 @@ gpk_application_error_code_cb (PkClient *client, PkErrorCodeEnum code, const gch
 	gpk_error_dialog_modal (window, gpk_error_enum_to_localised_text (code),
 				gpk_error_enum_to_localised_message (code), details);
 }
+#endif
 
 /**
  * gpk_application_suggest_better_search:
@@ -1114,126 +1352,6 @@ gpk_application_suggest_better_search (GpkApplication *application)
 }
 
 /**
- * gpk_application_finished_get_depends:
- **/
-static void
-gpk_application_finished_get_depends (GpkApplication *application, GPtrArray *array)
-{
-	GtkWindow *window;
-	gchar *name = NULL;
-	gchar *title = NULL;
-	gchar *message = NULL;
-	gchar **package_ids = NULL;
-	GtkWidget *dialog;
-	gchar *package_id_selected = NULL;
-	gboolean ret;
-
-	/* get selection */
-	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
-	if (!ret) {
-		egg_warning ("no package selected");
-		goto out;
-	}
-
-	/* empty array */
-	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-	if (array->len == 0) {
-		gpk_error_dialog_modal (window,
-					/* TRANSLATORS: no packages returned */
-					_("No packages"),
-					/* TRANSLATORS: this package does not depend on any others */
-					_("This package does not depends on any others"), NULL);
-		goto out;
-	}
-
-	package_ids = pk_package_ids_from_id (package_id_selected);
-	name = gpk_dialog_package_id_name_join_locale (package_ids);
-	/* TRANSLATORS: title: show the number of other packages we depend on */
-	title = g_strdup_printf (ngettext ("%i additional package is required for %s",
-					   "%i additional packages are required for %s",
-					   array->len), array->len, name);
-
-	/* TRANSLATORS: message: show the array of dependant packages for this package */
-	message = g_strdup_printf (ngettext ("Packages listed below are required for %s to function correctly.",
-					     "Packages listed below are required for %s to function correctly.",
-					     array->len), name);
-
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
-	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
-	gpk_dialog_embed_package_array_widget (GTK_DIALOG (dialog), array);
-
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-out:
-	g_free (package_id_selected);
-	g_strfreev (package_ids);
-	g_free (name);
-	g_free (title);
-	g_free (message);
-}
-
-/**
- * gpk_application_finished_get_requires:
- **/
-static void
-gpk_application_finished_get_requires (GpkApplication *application, GPtrArray *array)
-{
-	GtkWindow *window;
-	gchar *name = NULL;
-	gchar *title = NULL;
-	gchar *message = NULL;
-	gchar **package_ids = NULL;
-	GtkWidget *dialog;
-	gchar *package_id_selected = NULL;
-	gboolean ret;
-
-	/* get selection */
-	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
-	if (!ret) {
-		egg_warning ("no package selected");
-		goto out;
-	}
-
-	/* empty array */
-	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-	if (array->len == 0) {
-		gpk_error_dialog_modal (window,
-					/* TRANSLATORS: no packages returned */
-					_("No packages"),
-					/* TRANSLATORS: this package is not required by any others */
-					_("No other packages require this package"), NULL);
-		goto out;
-	}
-
-	package_ids = pk_package_ids_from_id (package_id_selected);
-	name = gpk_dialog_package_id_name_join_locale (package_ids);
-	/* TRANSLATORS: title: how many packages require this package */
-	title = g_strdup_printf (ngettext ("%i package requires %s",
-					   "%i packages require %s",
-					   array->len), length, name);
-
-	/* TRANSLATORS: show a array of packages for the package */
-	message = g_strdup_printf (ngettext ("Packages listed below require %s to function correctly.",
-					     "Packages listed below require %s to function correctly.",
-					     array->len), name);
-
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
-	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
-	gpk_dialog_embed_package_array_widget (GTK_DIALOG (dialog), array);
-
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-out:
-	g_free (package_id_selected);
-	g_strfreev (package_ids);
-	g_free (name);
-	g_free (title);
-	g_free (message);
-}
-
-/**
  * gpk_application_perform_search_idle_cb:
  **/
 static gboolean
@@ -1259,7 +1377,7 @@ gpk_application_select_exact_match (GpkApplication *application, const gchar *te
 	GtkTreeModel *model;
 	GtkTreeSelection *selection = NULL;
 	gchar *package_id;
-	gchar *split;
+	gchar **split;
 
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
@@ -1298,146 +1416,53 @@ gpk_application_select_exact_match (GpkApplication *application, const gchar *te
  * gpk_application_run_installed:
  **/
 static void
-gpk_application_run_installed (GpkApplication *application)
+gpk_application_run_installed (GpkApplication *application, PkResults *results)
 {
 	guint i;
-	guint len;
 	GPtrArray *array;
 	const PkItemPackage *item;
-	GPtrArray *array;
+	GPtrArray *package_ids_array;
 	gchar **package_ids = NULL;
 
 	/* get the package array and filter on INSTALLED */
-	array = g_ptr_array_new_with_free_func (g_free);
-	array = pk_results_get_package_array (application->priv->client);
-	len = array->len;
-	for (i=0; i<len; i++) {
+	package_ids_array = g_ptr_array_new_with_free_func (g_free);
+	array = pk_results_get_package_array (results);
+	for (i=0; i<array->len; i++) {
 		item = g_ptr_array_index (array, i);
 		if (item->info == PK_INFO_ENUM_INSTALLING)
-			g_ptr_array_add (array, g_strdup (item->package_id));
+			g_ptr_array_add (package_ids_array, g_strdup (item->package_id));
 	}
 
 	/* nothing to show */
-	if (array->len == 0) {
+	if (package_ids_array->len == 0) {
 		egg_debug ("nothing to do");
 		goto out;
 	}
 
 	/* this is async */
-	package_ids = pk_ptr_array_to_strv (array);
+	package_ids = pk_ptr_array_to_strv (package_ids_array);
 	gpk_helper_run_show (application->priv->helper_run, package_ids);
 
 out:
 	g_strfreev (package_ids);
-	g_object_unref (array);
+	g_ptr_array_unref (package_ids_array);
 	g_ptr_array_unref (array);
 }
 
+#if 0
 /**
  * gpk_application_finished_cb:
  **/
 static void
 gpk_application_finished_cb (PkClient *client, PkExitEnum exit_enum, guint runtime, GpkApplication *application)
 {
-	GtkWidget *widget;
-	PkRoleEnum role;
-	GPtrArray *array;
-
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	/* get role */
-	g_object_get (client,
-		      "role", &role,
-		      NULL);
-	egg_debug ("role: %s, exit: %s", pk_role_enum_to_text (role), pk_exit_enum_to_text (exit_enum));
-
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "progressbar_progress"));
-	gtk_widget_hide (widget);
-
-	/* reset UI */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
-	gtk_widget_set_sensitive (widget, TRUE);
-	gpk_application_set_buttons_apply_clear (application);
-
-	if (role == PK_ROLE_ENUM_GET_CATEGORIES) {
-		/* get complex group array */
-		gpk_application_categories_finished (application);
-	}
-
-	/* get deps */
-	if (role == PK_ROLE_ENUM_GET_DEPENDS &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		array = pk_results_get_package_array (application->priv->client);
-		gpk_application_finished_get_depends (application, array);
-		g_object_unref (array);
-	}
-
-	/* get reqs */
-	if (role == PK_ROLE_ENUM_GET_REQUIRES &&
-	    exit_enum == PK_EXIT_ENUM_SUCCESS) {
-		array = pk_results_get_package_array (application->priv->client);
-		gpk_application_finished_get_requires (application, array);
-		g_object_unref (array);
-	}
-
-	/* we've just agreed to auth or a EULA */
-	if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE ||
-	    role == PK_ROLE_ENUM_ACCEPT_EULA) {
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS)
-			gpk_application_primary_requeue (application);
-	}
-
-	/* do we need to update the search? */
-	if (role == PK_ROLE_ENUM_INSTALL_PACKAGES ||
-	    role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
-		/* refresh the search as the items may have changed and the filter has not changed */
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS) {
-			/* idle add in the background */
-			g_idle_add ((GSourceFunc) gpk_application_perform_search_idle_cb, application);
-
-			/* find applications that were installed, and offer to run them */
-			gpk_application_run_installed (application);
-
-			/* clear if success */
-			g_ptr_array_set_size (application->priv->package_array, 0);
-			application->priv->action = PK_ACTION_NONE;
-			gpk_application_set_buttons_apply_clear (application);
-		}
-	}
-
-	/* we've just agreed to auth or a EULA */
-	if (role == PK_ROLE_ENUM_INSTALL_SIGNATURE ||
-	    role == PK_ROLE_ENUM_ACCEPT_EULA) {
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS)
-			gpk_application_primary_requeue (application);
-	}
-
-	if (role == PK_ROLE_ENUM_SEARCH_NAME ||
-	    role == PK_ROLE_ENUM_SEARCH_DETAILS ||
-	    role == PK_ROLE_ENUM_SEARCH_GROUP ||
-	    role == PK_ROLE_ENUM_GET_PACKAGES) {
+//	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "progressbar_progress"));
+//	gtk_widget_hide (widget);
 
-		/* were there no entries found? */
-		if (exit_enum == PK_EXIT_ENUM_SUCCESS && !application->priv->has_package) {
-			gpk_application_suggest_better_search (application);
-		}
-
-		/* if there is an exact match, select it */
-		gpk_application_select_exact_match (application, application->priv->search_text);
-
-		/* focus back to the text extry */
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
-		gtk_widget_grab_focus (widget);
-	}
 }
+#endif
 
 /**
  * gpk_application_cancel_cb:
@@ -1449,25 +1474,92 @@ gpk_application_cancel_cb (GtkWidget *button_widget, GpkApplication *application
 
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	ret = g_cancellable_cancel (application->priv->client, NULL);
-	egg_debug ("canceled? %i", ret);
+	g_cancellable_cancel (application->priv->cancellable);
 
 	/* switch buttons around */
-	if (ret) {
+	if (ret)
 		application->priv->search_mode = PK_MODE_UNKNOWN;
+}
+
+/**
+ * gpk_application_search_cb:
+ **/
+static void
+gpk_application_search_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	PkItemPackage *item;
+	guint i;
+	GtkWidget *widget;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to search: %s", error->message);
+		g_error_free (error);
+		goto out;
 	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to search: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_package_array (results);
+	for (i=0; i<array->len; i++) {
+		item = g_ptr_array_index (array, i);
+		gpk_application_add_item_to_results (application, item);
+	}
+
+	/* were there no entries found? */
+	if (!application->priv->has_package)
+		gpk_application_suggest_better_search (application);
+
+	/* if there is an exact match, select it */
+	gpk_application_select_exact_match (application, application->priv->search_text);
+
+	/* focus back to the text extry */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
+	gtk_widget_grab_focus (widget);
+
+	/* reset UI */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
+	gtk_widget_set_sensitive (widget, TRUE);
+	gpk_application_set_buttons_apply_clear (application);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
  * gpk_application_perform_search_name_details_file:
  **/
-static gboolean
+static void
 gpk_application_perform_search_name_details_file (GpkApplication *application)
 {
 	GtkEntry *entry;
 	GtkWindow *window;
 	GError *error = NULL;
 	gboolean ret;
+	gchar **searches = NULL;
 
 	entry = GTK_ENTRY (gtk_builder_get_object (application->priv->builder, "entry_text"));
 	g_free (application->priv->search_text);
@@ -1476,10 +1568,10 @@ gpk_application_perform_search_name_details_file (GpkApplication *application)
 	/* have we got input? */
 	if (egg_strzero (application->priv->search_text)) {
 		egg_debug ("no input");
-		return FALSE;
+		goto out;
 	}
 
-	ret = pk_strvalidate (application->priv->search_text);
+	ret = !egg_strzero (application->priv->search_text);
 	if (!ret) {
 		egg_debug ("invalid input text, will fail");
 		/* TODO - make the dialog turn red... */
@@ -1489,26 +1581,33 @@ gpk_application_perform_search_name_details_file (GpkApplication *application)
 					_("Invalid search text"),
 					/* TRANSLATORS: message: tell the user that's not allowed */
 					_("The search text contains invalid characters"), NULL);
-		return FALSE;
+		goto out;
 	}
 	egg_debug ("find %s", application->priv->search_text);
 
 	/* do the search */
+	searches = g_strsplit (application->priv->search_text, " ", -1);
 	if (application->priv->search_type == PK_SEARCH_NAME) {
-		ret = pk_client_search_name (application->priv->client,
+		pk_client_search_name_async (application->priv->client,
 					     application->priv->filters_current,
-					     application->priv->search_text, &error);
+					     searches, application->priv->cancellable,
+					     (PkProgressCallback) gpk_application_progress_cb, application,
+					     (GAsyncReadyCallback) gpk_application_search_cb, application);
 	} else if (application->priv->search_type == PK_SEARCH_DETAILS) {
-		ret = pk_client_search_details (application->priv->client,
+		pk_client_search_details_async (application->priv->client,
 					     application->priv->filters_current,
-					     application->priv->search_text, &error);
+					     searches, application->priv->cancellable,
+					     (PkProgressCallback) gpk_application_progress_cb, application,
+					     (GAsyncReadyCallback) gpk_application_search_cb, application);
 	} else if (application->priv->search_type == PK_SEARCH_FILE) {
-		ret = pk_client_search_file (application->priv->client,
+		pk_client_search_file_async (application->priv->client,
 					     application->priv->filters_current,
-					     application->priv->search_text, &error);
+					     searches, application->priv->cancellable,
+					     (PkProgressCallback) gpk_application_progress_cb, application,
+					     (GAsyncReadyCallback) gpk_application_search_cb, application);
 	} else {
 		egg_warning ("invalid search type");
-		return FALSE;
+		goto out;
 	}
 
 	if (!ret) {
@@ -1519,46 +1618,36 @@ gpk_application_perform_search_name_details_file (GpkApplication *application)
 					/* TRANSLATORS: low level failure, details to follow */
 					_("Running the transaction failed"), error->message);
 		g_error_free (error);
-		return FALSE;
+		goto out;
 	}
-
-	return TRUE;
+out:
+	g_strfreev (searches);
 }
 
 /**
  * gpk_application_perform_search_others:
  **/
-static gboolean
+static void
 gpk_application_perform_search_others (GpkApplication *application)
 {
-	gboolean ret;
-	GtkWindow *window;
-	GError *error = NULL;
+	gchar **groups;
 
-	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
-	g_return_val_if_fail (application->priv->group != NULL, FALSE);
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+	g_return_if_fail (application->priv->group != NULL);
 
 	if (application->priv->search_mode == PK_MODE_GROUP) {
-		ret = pk_client_search_group (application->priv->client,
-					      application->priv->filters_current,
-					      application->priv->group, &error);
+		groups = g_strsplit (application->priv->group, " ", -1);
+		pk_client_search_group_async (application->priv->client,
+					      application->priv->filters_current, groups, application->priv->cancellable,
+					      (PkProgressCallback) gpk_application_progress_cb, application,
+					      (GAsyncReadyCallback) gpk_application_search_cb, application);
+		g_strfreev (groups);
 	} else {
-		ret = pk_client_get_packages (application->priv->client,
-					      application->priv->filters_current, &error);
-	}
-
-	if (!ret) {
-		window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-		gpk_error_dialog_modal (window,
-					/* TRANSLATORS: title: could not get group data */
-					_("The group could not be queried"),
-					/* TRANSLATORS: low level failure */
-					_("Running the transaction failed"), error->message);
-		g_error_free (error);
-		return FALSE;
+		pk_client_get_packages_async (application->priv->client,
+					      application->priv->filters_current, application->priv->cancellable,
+					      (PkProgressCallback) gpk_application_progress_cb, application,
+					      (GAsyncReadyCallback) gpk_application_search_cb, application);
 	}
-
-	return TRUE;
 }
 
 /**
@@ -1569,12 +1658,15 @@ gpk_application_populate_selected (GpkApplication *application)
 {
 	guint i;
 	guint len;
-	GPtrArray *array;
-	const PkItemPackage *item;
-
-	array = application->priv->package_array;
-	len = array->len;
+	PkItemPackage *item;
+	PkPackage *package;
+	PkInfoEnum info;
+	const gchar *package_id;
+	gchar *summary;
 
+	/* get size */
+	len = pk_package_sack_get_size (application->priv->package_sack);
+	
 	/* nothing in queue */
 	if (len == 0) {
 		gpk_application_suggest_better_search (application);
@@ -1583,8 +1675,16 @@ gpk_application_populate_selected (GpkApplication *application)
 
 	/* dump queue to package window */
 	for (i=0; i<len; i++) {
-		item = g_ptr_array_index (array, i);
+		package = pk_package_sack_get_index (application->priv->package_sack, i);
+		package_id = pk_package_get_id (package);
+		g_object_get (package,
+			      "info", &info,
+			      "summary", &summary,
+			      NULL);
+		item = pk_item_package_new (info, package_id, summary);
 		gpk_application_add_item_to_results (application, item);
+		pk_item_package_unref (item);
+		g_free (summary);
 	}
 out:
 	return TRUE;
@@ -1593,27 +1693,24 @@ out:
 /**
  * gpk_application_perform_search:
  **/
-static gboolean
+static void
 gpk_application_perform_search (GpkApplication *application)
 {
-	gboolean ret = FALSE;
-
-	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
+	g_return_if_fail (GPK_IS_APPLICATION (application));
 
 	gpk_application_clear_details (application);
 	gpk_application_clear_packages (application);
 
 	if (application->priv->search_mode == PK_MODE_NAME_DETAILS_FILE) {
-		ret = gpk_application_perform_search_name_details_file (application);
+		gpk_application_perform_search_name_details_file (application);
 	} else if (application->priv->search_mode == PK_MODE_GROUP ||
 		   application->priv->search_mode == PK_MODE_ALL_PACKAGES) {
-		ret = gpk_application_perform_search_others (application);
+		gpk_application_perform_search_others (application);
 	} else if (application->priv->search_mode == PK_MODE_SELECTED) {
-		ret = gpk_application_populate_selected (application);
+		gpk_application_populate_selected (application);
 	} else {
 		egg_debug ("doing nothing");
 	}
-	return ret;
 }
 
 /**
@@ -1636,16 +1733,14 @@ static gboolean
 gpk_application_quit (GpkApplication *application)
 {
 	gint len;
-	gboolean ret;
 	GtkResponseType result;
-	GError *error = NULL;
 	GtkWindow *window;
 	GtkWidget *dialog;
 
 	g_return_val_if_fail (GPK_IS_APPLICATION (application), FALSE);
 
 	/* do we have any items queued for removal or installation? */
-	len = application->priv->package_array->len;
+	len = pk_package_sack_get_size (application->priv->package_sack);
 	if (len != 0) {
 		window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
 		dialog = gtk_message_dialog_new (window, GTK_DIALOG_MODAL,
@@ -1668,12 +1763,7 @@ gpk_application_quit (GpkApplication *application)
 	}
 
 	/* we might have visual stuff running, close them down */
-	ret = g_cancellable_cancel (application->priv->client, &error);
-	if (!ret) {
-		egg_warning ("failed to cancel client: %s", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
+	g_cancellable_cancel (application->priv->cancellable);
 
 	egg_debug ("emitting action-close");
 	g_signal_emit (application, signals [ACTION_CLOSE], 0);
@@ -1727,7 +1817,7 @@ gpk_application_text_changed_cb (GtkEntry *entry, GdkEventKey *event, GpkApplica
 	}
 
 	/* check for invalid chars */
-	valid = pk_strvalidate (package);
+	valid = !egg_strzero (package);
 
 	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_find"));
 	if (valid == FALSE || egg_strzero (package))
@@ -1830,7 +1920,7 @@ gpk_application_button_clear_cb (GtkWidget *widget_button, GpkApplication *appli
 	}
 
 	/* clear queue */
-	g_ptr_array_set_size (application->priv->package_array, 0);
+	pk_package_sack_clear (application->priv->package_sack);
 
 	/* force a button refresh */
 	selection = gtk_tree_view_get_selection (treeview);
@@ -1840,47 +1930,119 @@ gpk_application_button_clear_cb (GtkWidget *widget_button, GpkApplication *appli
 }
 
 /**
+ * gpk_application_install_packages_cb:
+ **/
+static void
+gpk_application_install_packages_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to install packages: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to install packages: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* idle add in the background */
+	g_idle_add ((GSourceFunc) gpk_application_perform_search_idle_cb, application);
+
+	/* find applications that were installed, and offer to run them */
+	gpk_application_run_installed (application, results);
+
+	/* clear if success */
+	pk_package_sack_clear (application->priv->package_sack);
+	application->priv->action = PK_ACTION_NONE;
+	gpk_application_set_buttons_apply_clear (application);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_application_remove_packages_cb:
+ **/
+static void
+gpk_application_remove_packages_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to remove packages: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to remove packages: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* idle add in the background */
+	g_idle_add ((GSourceFunc) gpk_application_perform_search_idle_cb, application);
+
+	/* clear if success */
+	pk_package_sack_clear (application->priv->package_sack);
+	application->priv->action = PK_ACTION_NONE;
+	gpk_application_set_buttons_apply_clear (application);
+out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
  * gpk_application_button_apply_cb:
  **/
 static void
 gpk_application_button_apply_cb (GtkWidget *widget, GpkApplication *application)
 {
-	gboolean ret = FALSE;
-	GError *error = NULL;
 	gchar **package_ids = NULL;
 
 	g_return_if_fail (GPK_IS_APPLICATION (application));
 
-	package_ids = pk_package_array_to_strv (application->priv->package_array);
+	package_ids = pk_package_sack_get_ids (application->priv->package_sack);
 	if (application->priv->action == PK_ACTION_INSTALL) {
 
 		/* install */
-		ret = pk_client_install_packages (application->priv->client, package_ids, &error);
-		if (!ret) {
-			egg_warning ("failed to get depends: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
+		pk_client_install_packages_async (application->priv->client, TRUE, package_ids, application->priv->cancellable,
+						  (PkProgressCallback) gpk_application_progress_cb, application,
+						  (GAsyncReadyCallback) gpk_application_install_packages_cb, application);
 
 		/* make package array insensitive */
 		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
 		gtk_widget_set_sensitive (widget, FALSE);
-	}
-	if (application->priv->action == PK_ACTION_REMOVE) {
+
+	} else if (application->priv->action == PK_ACTION_REMOVE) {
 
 		/* install */
-		ret = pk_client_remove_packages (application->priv->client, pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package_ids, TRUE, &error);
-		if (!ret) {
-			egg_warning ("failed to get requires: %s", error->message);
-			g_error_free (error);
-			goto out;
-		}
+		pk_client_remove_packages_async (application->priv->client, package_ids, TRUE, FALSE, application->priv->cancellable,
+						 (PkProgressCallback) gpk_application_progress_cb, application,
+						 (GAsyncReadyCallback) gpk_application_remove_packages_cb, application);
 
 		/* make package array insensitive */
 		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
 		gtk_widget_set_sensitive (widget, FALSE);
 	}
-out:
 	g_strfreev (package_ids);
 	return;
 }
@@ -1999,6 +2161,151 @@ gpk_application_groups_treeview_changed_cb (GtkTreeSelection *selection, GpkAppl
 }
 
 /**
+ * gpk_application_get_details_cb:
+ **/
+static void
+gpk_application_get_details_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
+{
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
+	PkItemDetails *item;
+	GtkWidget *widget;
+	gchar *text;
+	gchar *value;
+	const gchar *repo_name;
+	const gchar *group;
+	gboolean installed;
+	gchar **split = NULL;
+
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get list of categories: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get cats: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
+	/* get data */
+	array = pk_results_get_details_array (results);
+	if (array->len != 1) {
+		egg_warning ("not one entry %i", array->len);
+		goto out;
+	}
+
+	/* only choose the first item */
+	item = g_ptr_array_index (array, 0);
+
+	/* hide to start */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "scrolledwindow_detail"));
+	gtk_widget_show (widget);
+
+	gtk_list_store_clear (application->priv->details_store);
+
+	split = pk_package_id_split (item->package_id);
+	installed = g_strcmp0 (split[PK_PACKAGE_ID_DATA], "installed") == 0;
+
+	/* if a collection, mark as such */
+	if (g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") == 0)
+		/* TRANSLATORS: the type of package is a collection (metagroup) */
+		gpk_application_add_detail_item (application, _("Type"), _("Collection"), NULL);
+
+	/* homepage */
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "menuitem_homepage"));
+	if (egg_strzero (item->url) == FALSE) {
+		gtk_widget_set_sensitive (widget, TRUE);
+
+		/* TRANSLATORS: tooltip: go to the web address */
+		text = g_strdup_printf (_("Visit %s"), item->url);
+		gtk_widget_set_tooltip_text (widget, text);
+		g_free (text);
+
+		/* TRANSLATORS: add an entry to go to the project home page */
+		gpk_application_add_detail_item (application, _("Project"), _("Homepage"), item->url);
+
+		/* save the url for the button */
+		g_free (application->priv->url);
+		application->priv->url = g_strdup (item->url);
+
+	} else {
+		gtk_widget_set_sensitive (widget, FALSE);
+	}
+
+	/* group */
+	if (item->group != PK_GROUP_ENUM_UNKNOWN) {
+		group = gpk_group_enum_to_localised_text (item->group);
+		/* TRANSLATORS: the group the package belongs in */
+		gpk_application_add_detail_item (application, _("Group"), group, NULL);
+	}
+
+	/* group */
+	if (!egg_strzero (item->license)) {
+		/* TRANSLATORS: the licence string for the package */
+		gpk_application_add_detail_item (application, _("License"), item->license, NULL);
+	}
+
+	/* menu path */
+	value = gpk_desktop_guess_best_file (application->priv->desktop, split[PK_PACKAGE_ID_NAME]);
+	if (value != NULL) {
+		text = gpk_desktop_get_menu_path (value);
+		if (text != NULL) {
+			/* TRANSLATORS: the path in the menu, e.g. Applications -> Games */
+			gpk_application_add_detail_item (application, _("Menu"), text, NULL);
+		}
+		g_free (text);
+	}
+	g_free (value);
+
+	/* set the description */
+	text = gpk_application_text_format_display (application, item->description);
+	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
+	gpk_application_set_text_buffer (widget, text);
+	g_free (text);
+
+	/* if non-zero, set the size */
+	if (item->size > 0) {
+		/* set the size */
+		value = g_format_size_for_display (item->size);
+		if (g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") == 0)
+			/* TRANSLATORS: the size of the meta package */
+			gpk_application_add_detail_item (application, _("Size"), value, NULL);
+		else if (installed)
+			/* TRANSLATORS: the installed size in bytes of the package */
+			gpk_application_add_detail_item (application, _("Installed size"), value, NULL);
+		else
+			/* TRANSLATORS: the download size of the package */
+			gpk_application_add_detail_item (application, _("Download size"), value, NULL);
+		g_free (value);
+	}
+
+	/* set the repo text, or hide if installed */
+	if (!installed && g_strcmp0 (split[PK_PACKAGE_ID_DATA], "meta") != 0) {
+		/* get the full name of the repo from the repo_id */
+		repo_name = gpk_application_get_full_repo_name (application, split[PK_PACKAGE_ID_DATA]);
+		/* TRANSLATORS: where the package came from, the software source name */
+		gpk_application_add_detail_item (application, _("Source"), repo_name, NULL);
+	}
+out:
+	g_strfreev (split);
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
  * gpk_application_packages_treeview_clicked_cb:
  **/
 static void
@@ -2008,7 +2315,6 @@ gpk_application_packages_treeview_clicked_cb (GtkTreeSelection *selection, GpkAp
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	gboolean ret;
-	GError *error = NULL;
 	gboolean show_install = TRUE;
 	gboolean show_remove = TRUE;
 	PkBitfield state;
@@ -2070,11 +2376,9 @@ gpk_application_packages_treeview_clicked_cb (GtkTreeSelection *selection, GpkAp
 
 	/* get the details */
 	package_ids = pk_package_ids_from_id (package_id);
-	ret = pk_client_get_details (application->priv->client, package_ids, &error);
-	if (!ret) {
-		egg_warning ("failed to get details: %s", error->message);
-		g_error_free (error);
-	}
+	pk_client_get_details_async (application->priv->client, package_ids, application->priv->cancellable,
+				     (PkProgressCallback) gpk_application_progress_cb, application,
+				     (GAsyncReadyCallback) gpk_application_get_details_cb, application);
 out:
 	g_free (package_id);
 	g_strfreev (package_ids);
@@ -2455,25 +2759,46 @@ gpk_application_menu_log_cb (GtkAction *action, GpkApplication *application)
 }
 
 /**
- * gpk_application_menu_refresh_cb:
+ * gpk_application_refresh_cache_cb:
  **/
 static void
-gpk_application_menu_refresh_cb (GtkAction *action, GpkApplication *application)
+gpk_application_refresh_cache_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
 {
-	gboolean ret;
+	PkResults *results;
 	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
 
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	/* set correct view */
-	ret = pk_client_refresh_cache (application->priv->client, TRUE, &error);
-	if (!ret) {
-		egg_warning ("cannot get refresh cache: %s", error->message);
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to refresh: %s", error->message);
 		g_error_free (error);
 		goto out;
 	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to refresh: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
 out:
-	return;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (results != NULL)
+		g_object_unref (results);
+}
+
+/**
+ * gpk_application_menu_refresh_cb:
+ **/
+static void
+gpk_application_menu_refresh_cb (GtkAction *action, GpkApplication *application)
+{
+	g_return_if_fail (GPK_IS_APPLICATION (application));
+	pk_client_refresh_cache_async (application->priv->client, TRUE, application->priv->cancellable,
+				       (PkProgressCallback) gpk_application_progress_cb, application,
+				       (GAsyncReadyCallback) gpk_application_refresh_cache_cb, application);
 }
 
 /**
@@ -2720,105 +3045,6 @@ gpk_application_menu_filter_arch_cb (GtkWidget *widget, GpkApplication *applicat
 }
 
 /**
- * gpk_application_status_changed_timeout_cb:
- **/
-static gboolean
-gpk_application_status_changed_timeout_cb (GpkApplication *application)
-{
-	const gchar *text;
-	GtkWidget *widget;
-
-	/* set the text and show */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "label_status"));
-	text = gpk_status_enum_to_localised_text (application->priv->status_last);
-	gtk_label_set_label (GTK_LABEL (widget), text);
-
-	/* set icon */
-	gpk_set_animated_icon_from_status (GPK_ANIMATED_ICON (application->priv->image_status),
-					   application->priv->status_last, GTK_ICON_SIZE_LARGE_TOOLBAR);
-
-	/* show containing box */
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
-	gtk_widget_show (widget);
-
-	/* never repeat */
-	application->priv->status_id = 0;
-	return FALSE;
-}
-
-/**
- * gpk_application_status_changed_cb:
- **/
-static void
-gpk_application_status_changed_cb (PkClient *client, PkStatusEnum status, GpkApplication *application)
-{
-	GtkWidget *widget;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	if (application->priv->action == PK_ACTION_INSTALL ||
-	    application->priv->action == PK_ACTION_REMOVE) {
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "textview_description"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_detail"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "entry_text"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_apply"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_clear"));
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_find"));
-		gtk_widget_set_sensitive (widget, FALSE);
-	}
-
-	if (status == PK_STATUS_ENUM_FINISHED) {
-
-		/* re-enable UI */
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "treeview_packages"));
-		gtk_widget_set_sensitive (widget, TRUE);
-
-		/* we've not yet shown, so don't bother */
-		if (application->priv->status_id > 0) {
-			g_source_remove (application->priv->status_id);
-			application->priv->status_id = 0;
-		}
-
-		widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "hbox_status"));
-		gtk_widget_hide (widget);
-		gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (application->priv->image_status), FALSE);
-		goto out;
-	}
-
-	/* already pending show */
-	if (application->priv->status_id > 0)
-		goto out;
-
-	/* only show after some time in the transaction */
-	application->priv->status_id = g_timeout_add (GPK_UI_STATUS_SHOW_DELAY, (GSourceFunc) gpk_application_status_changed_timeout_cb, application);
-
-out:
-	/* save for the callback */
-	application->priv->status_last = status;
-}
-
-/**
- * gpk_application_allow_cancel_cb:
- **/
-static void
-gpk_application_allow_cancel_cb (PkClient *client, gboolean allow_cancel, GpkApplication *application)
-{
-	GtkWidget *widget;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	widget = GTK_WIDGET (gtk_builder_get_object (application->priv->builder, "button_cancel"));
-	gtk_widget_set_sensitive (widget, allow_cancel);
-}
-
-/**
  * gpk_application_package_row_activated_cb:
  **/
 static void
@@ -3001,7 +3227,7 @@ gpk_application_create_group_array_enum (GpkApplication *application)
 	/* create group tree view if we can search by group */
 	if (pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_SEARCH_GROUP)) {
 		/* add all the groups supported (except collections, which we handled above */
-		for (i=0; i<PK_GROUP_ENUM_UNKNOWN; i++) {
+		for (i=0; i<PK_GROUP_ENUM_LAST; i++) {
 			if (pk_bitfield_contain (application->priv->groups, i) &&
 			    i != PK_GROUP_ENUM_COLLECTIONS && i != PK_GROUP_ENUM_NEWEST)
 				gpk_application_group_add_data (application, i);
@@ -3013,19 +3239,37 @@ gpk_application_create_group_array_enum (GpkApplication *application)
 }
 
 /**
- * gpk_application_categories_finished:
+ * gpk_application_get_categories_cb:
  **/
 static void
-gpk_application_categories_finished (GpkApplication *application)
+gpk_application_get_categories_cb (PkClient *client, GAsyncResult *res, GpkApplication *application)
 {
-	GPtrArray *array;
-	const PkCategoryObj *item;
-	const PkCategoryObj *item2;
+	PkResults *results;
+	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
+	GPtrArray *array = NULL;
 	GtkTreeIter iter;
 	GtkTreeIter iter2;
 	guint i, j;
 	GtkTreeView *treeview;
 	const gchar *icon_name;
+	PkItemCategory *item;
+	PkItemCategory *item2;
+
+	/* get the results */
+	results = pk_client_generic_finish (client, res, &error);
+	if (results == NULL) {
+		egg_warning ("failed to get list of categories: %s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to get cats: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
 
 	/* set to expanders with indent */
 	treeview = GTK_TREE_VIEW (gtk_builder_get_object (application->priv->builder, "treeview_groups"));
@@ -3062,14 +3306,9 @@ gpk_application_categories_finished (GpkApplication *application)
 	gtk_tree_view_set_row_separator_func (treeview,
 					      gpk_application_group_row_separator_func, NULL, NULL);
 
-	/* get return values */
-	array = pk_client_get_category_array (application->priv->client);
-	if (array->len == 0) {
-		egg_warning ("no results from GetCategories");
-		goto out;
-	}
-
-	for (i=0; i < array->len; i++) {
+	/* add repos wih descriptions */
+	array = pk_results_get_category_array (results);
+	for (i=0; i<array->len; i++) {
 		item = g_ptr_array_index (array, i);
 
 		gtk_tree_store_append (application->priv->groups_store, &iter, NULL);
@@ -3093,7 +3332,7 @@ gpk_application_categories_finished (GpkApplication *application)
 						    GROUPS_COLUMN_ICON, item2->icon,
 						    GROUPS_COLUMN_ACTIVE, TRUE,
 						    -1);
-				pk_item_array_remove (array, item2);
+				g_ptr_array_remove (array, item2);
 			} else
 				j++;
 		} while (j < array->len);
@@ -3101,35 +3340,25 @@ gpk_application_categories_finished (GpkApplication *application)
 
 	/* open all expanders */
 	gtk_tree_view_collapse_all (treeview);
-	g_object_unref (array);
 out:
-	return;
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
+	if (array != NULL)
+		g_ptr_array_unref (array);
+	if (results != NULL)
+		g_object_unref (results);
 }
 
 /**
  * gpk_application_create_group_array_categories:
  **/
-static gboolean
+static void
 gpk_application_create_group_array_categories (GpkApplication *application)
 {
-	GError *error = NULL;
-	gboolean ret = FALSE;
-
-	/* check we can do this */
-	if (!pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_CATEGORIES)) {
-		egg_warning ("backend does not support complex groups");
-		goto out;
-	}
-
 	/* get categories supported */
-	ret = pk_client_get_categories (application->priv->client, &error);
-	if (!ret) {
-		egg_warning ("failed to get categories: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-out:
-	return ret;
+	pk_client_get_categories_async (application->priv->client, application->priv->cancellable,
+				        (PkProgressCallback) gpk_application_progress_cb, application,
+				        (GAsyncReadyCallback) gpk_application_get_categories_cb, application);
 }
 
 /**
@@ -3170,62 +3399,6 @@ gpk_application_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfE
 }
 
 /**
- * gpk_application_files_cb:
- **/
-static void
-gpk_application_files_cb (PkClient *client, const gchar *package_id,
-			  const gchar *filelist, GpkApplication *application)
-{
-	GPtrArray *array;
-	gchar **files;
-	gchar *title;
-	GtkWindow *window;
-	GtkWidget *dialog;
-	gchar *package_id_selected = NULL;
-	gboolean ret;
-	gchar **split;
-
-	g_return_if_fail (GPK_IS_APPLICATION (application));
-
-	/* get selection */
-	ret = gpk_application_get_selected_package (application, &package_id_selected, NULL);
-	if (!ret) {
-		egg_warning ("no package selected");
-		goto out;
-	}
-
-	files = g_strsplit (filelist, ";", -1);
-
-	/* convert to pointer array */
-	array = pk_strv_to_ptr_array (files);
-	g_ptr_array_sort (array, (GCompareFunc) gpk_application_strcmp_indirect);
-
-	/* title */
-	split = pk_package_id_split (package_id_selected);
-	/* TRANSLATORS: title: how many files are installed by the application */
-	title = g_strdup_printf (ngettext ("%i file installed by %s",
-					   "%i files installed by %s",
-					   array->len), array->len, split[PK_PACKAGE_ID_NAME]);
-
-	window = GTK_WINDOW (gtk_builder_get_object (application->priv->builder, "window_manager"));
-	dialog = gtk_message_dialog_new (window, GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", title);
-	gpk_dialog_embed_file_list_widget (GTK_DIALOG (dialog), array);
-	gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
-	gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 250);
-
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-
-	g_free (title);
-	g_ptr_array_unref (array);
-	g_strfreev (files);
-	g_strfreev (split);
-out:
-	g_free (package_id_selected);
-}
-
-/**
  * pk_backend_status_get_properties_cb:
  **/
 static void
@@ -3357,11 +3530,9 @@ pk_backend_status_get_properties_cb (GObject *object, GAsyncResult *res, GpkAppl
 
 	/* simple array or category tree? */
 	ret = gconf_client_get_bool (application->priv->gconf_client, GPK_CONF_APPLICATION_CATEGORY_GROUPS, NULL);
-	if (ret)
-		ret = gpk_application_create_group_array_categories (application);
-
-	/* fallback to creating a simple array if we can't do category array */
-	if (!ret)
+	if (ret && pk_bitfield_contain (application->priv->roles, PK_ROLE_ENUM_GET_CATEGORIES))
+		gpk_application_create_group_array_categories (application);
+	else
 		gpk_application_create_group_array_enum (application);
 out:
 	return;
@@ -3375,6 +3546,7 @@ gpk_application_get_repo_list_cb (PkClient *client, GAsyncResult *res, GpkApplic
 {
 	PkResults *results;
 	GError *error = NULL;
+	PkItemErrorCode *error_item = NULL;
 	GPtrArray *array = NULL;
 	PkItemRepoDetail *item;
 	guint i;
@@ -3387,6 +3559,13 @@ gpk_application_get_repo_list_cb (PkClient *client, GAsyncResult *res, GpkApplic
 		goto out;
 	}
 
+	/* check error code */
+	error_item = pk_results_get_error_code (results);
+	if (error_item != NULL) {
+		egg_warning ("failed to repo list: %s, %s", pk_error_enum_to_text (error_item->code), error_item->details);
+		goto out;
+	}
+
 	/* add repos wih descriptions */
 	array = pk_results_get_repo_detail_array (results);
 	for (i=0; i<array->len; i++) {
@@ -3399,6 +3578,8 @@ gpk_application_get_repo_list_cb (PkClient *client, GAsyncResult *res, GpkApplic
 	}
 
 out:
+	if (error_item != NULL)
+		pk_item_error_code_unref (error_item);
 	if (array != NULL)
 		g_ptr_array_unref (array);
 	if (results != NULL)
@@ -3431,9 +3612,10 @@ gpk_application_init (GpkApplication *application)
 	application->priv->details_event_id = 0;
 	application->priv->status_id = 0;
 	application->priv->status_last = PK_STATUS_ENUM_UNKNOWN;
-	application->priv->package_array = g_ptr_array_new_with_free_func ((GDestroyNotify) pk_item_package_unref);
+	application->priv->package_sack = pk_package_sack_new ();
 
 	application->priv->gconf_client = gconf_client_get_default ();
+	application->priv->cancellable = g_cancellable_new ();
 	application->priv->repos = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 
 	application->priv->search_type = PK_SEARCH_UNKNOWN;
@@ -3787,8 +3969,8 @@ gpk_application_init (GpkApplication *application)
 			  G_CALLBACK (gpk_application_groups_treeview_changed_cb), application);
 
 	/* get repos, so we can show the full name in the software source box */
-	pk_client_get_repo_list_async (application->priv->client, PK_FILTER_ENUM_NONE, NULL,
-				       NULL, NULL,
+	pk_client_get_repo_list_async (application->priv->client, PK_FILTER_ENUM_NONE, application->priv->cancellable,
+				       (PkProgressCallback) gpk_application_progress_cb, application,
 				       (GAsyncReadyCallback) gpk_application_get_repo_list_cb, application);
 
 	/* set current action */
@@ -3866,6 +4048,8 @@ gpk_application_finalize (GObject *object)
 	g_object_unref (application->priv->markdown);
 	g_object_unref (application->priv->builder);
 	g_object_unref (application->priv->helper_run);
+	g_object_unref (application->priv->cancellable);
+	g_object_unref (application->priv->package_sack);
 
 	if (application->priv->status_id > 0)
 		g_source_remove (application->priv->status_id);
diff --git a/src/gpk-check-update.c b/src/gpk-check-update.c
index 8325acd..8f851b6 100644
--- a/src/gpk-check-update.c
+++ b/src/gpk-check-update.c
@@ -1305,7 +1305,7 @@ gpk_check_update_auto_get_upgrades_cb (GpkAutoRefresh *arefresh, GpkCheckUpdate
 static void
 gpk_check_update_notify_network_status_cb (PkControl *control, GParamSpec *pspec, GpkCheckUpdate *cupdate)
 {
-	PkNetworkEnum *status;
+	PkNetworkEnum status;
 
 	g_object_get (control, "network-state", &status, NULL);
 
diff --git a/src/gpk-service-pack.c b/src/gpk-service-pack.c
index 45a40aa..8d34a56 100644
--- a/src/gpk-service-pack.c
+++ b/src/gpk-service-pack.c
@@ -401,10 +401,9 @@ gpk_pack_progress_cb (PkProgress *progress, PkProgressType type, gpointer userda
 
 	if (type == PK_PROGRESS_TYPE_STATUS) {
 		egg_debug ("now %s", pk_status_enum_to_text (status));
-	} else (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
 		gpk_pack_set_percentage (percentage);
 	}
-
 }
 
 /**
diff --git a/src/gpk-update-viewer.c b/src/gpk-update-viewer.c
index 5d3d8e1..a5102df 100644
--- a/src/gpk-update-viewer.c
+++ b/src/gpk-update-viewer.c
@@ -1418,7 +1418,7 @@ gpk_update_viewer_finished_get_details_cb (GPtrArray *array)
 	gboolean ret;
 	gchar **package_ids;
 	GError *error = NULL;
-	package_ids = pk_package_array_to_strv (array);
+	package_ids = pk_package_sack_get_ids (array);
 
 	/* get the details of all the packages */
 	ret = pk_client_get_details (client, package_ids, &error);
@@ -1429,7 +1429,7 @@ gpk_update_viewer_finished_get_details_cb (GPtrArray *array)
 	}
 out:
 	g_strfreev (package_ids);
-	g_object_unref (array);
+	g_ptr_array_unref (array);
 	return FALSE;
 }
 
@@ -1442,7 +1442,7 @@ gpk_update_viewer_finished_get_update_details_cb (GPtrArray *array)
 	gboolean ret;
 	gchar **package_ids;
 	GError *error = NULL;
-	package_ids = pk_package_array_to_strv (array);
+	package_ids = pk_package_sack_get_ids (array);
 
 	/* get the details of all the packages */
 	ret = pk_client_get_update_detail (client, package_ids, &error);
@@ -1453,7 +1453,7 @@ gpk_update_viewer_finished_get_update_details_cb (GPtrArray *array)
 	}
 out:
 	g_strfreev (package_ids);
-	g_object_unref (array);
+	g_ptr_array_unref (array);
 	return FALSE;
 }
 
@@ -1783,7 +1783,7 @@ gpk_update_viewer_finished_cb (PkClient *client, PkExitEnum exit, guint runtime,
 		/* check blocked */
 		array = pk_results_get_package_array (results);
 		gpk_update_viewer_check_blocked_packages (array);
-		g_object_unref (array);
+		g_ptr_array_unref (array);
 
 		/* check restart */
 		if (restart_update == PK_RESTART_ENUM_SYSTEM ||



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