[gnome-software] Allow application removal from the installed shell page



commit b30cefb6ed0c4ad02c0cf59677f747fecc26aea7
Author: Richard Hughes <richard hughsie com>
Date:   Thu Aug 22 17:33:56 2013 +0100

    Allow application removal from the installed shell page

 src/gs-main.c            |   82 ---------------------------------------
 src/gs-plugin-loader.c   |   95 ++++++++++++++++++++++++++++++++++++++--------
 src/gs-plugin-loader.h   |   10 ++---
 src/gs-shell-installed.c |   77 +++++++++++++++++++++++++++++++++++--
 4 files changed, 156 insertions(+), 108 deletions(-)
---
diff --git a/src/gs-main.c b/src/gs-main.c
index d975ab8..cb6fecd 100644
--- a/src/gs-main.c
+++ b/src/gs-main.c
@@ -251,28 +251,6 @@ gs_main_plugin_loader_status_changed_cb (GsPluginLoader *plugin_loader,
 #endif
 
 #if 0
-static void
-update_pending_apps (GsMainPrivate *priv, gint delta)
-{
-       GtkWidget *widget;
-       gchar *label;
-
-       priv->pending_apps += delta;
-       g_assert (priv->pending_apps >= 0);
-
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_button_installed"));
-
-       if (priv->pending_apps == 0)
-               label = g_strdup (_("Installed"));
-       else
-               label = g_strdup_printf (_("Installed (%d)"), priv->pending_apps);
-
-       gtk_label_set_label (GTK_LABEL (widget), label);
-       g_free (label);
-}
-#endif
-
-#if 0
 typedef struct {
        GsAppWidget     *app_widget;
        GsMainPrivate   *priv;
@@ -296,8 +274,6 @@ gs_main_remove_packages_cb (PkClient *client,
        PkResults *results;
        GsAppWidget *app_widget;
 
-       update_pending_apps (data->priv, -1);
-
        /* get the results */
        results = pk_client_generic_finish (client, res, &error);
        if (results == NULL) {
@@ -361,7 +337,6 @@ gs_main_app_widget_button_clicked_cb (GsAppWidget *app_widget, GsMainPrivate *pr
        const gchar *to_array[] = { NULL, NULL };
        GsMainMethodData *data;
 
-       kind = gs_app_widget_get_kind (app_widget);
        app = gs_app_widget_get_app (app_widget);
        package_id = gs_app_get_id (app);
 
@@ -373,20 +348,7 @@ gs_main_app_widget_button_clicked_cb (GsAppWidget *app_widget, GsMainPrivate *pr
        data->priv = priv;
 
        if (kind == GS_APP_WIDGET_KIND_UPDATE) {
-               update_pending_apps (data->priv, 1);
-               g_debug ("update %s", package_id);
-               to_array[0] = package_id;
-               gs_app_widget_set_kind (app_widget, GS_APP_WIDGET_KIND_BUSY);
-               gs_app_widget_set_status (app_widget, "Updating");
-               pk_task_update_packages_async (priv->task,
-                                              (gchar**)to_array,
-                                              priv->cancellable,
-                                              (PkProgressCallback) gs_main_progress_cb,
-                                              priv,
-                                              (GAsyncReadyCallback) gs_main_remove_packages_cb,
-                                              data);
        } else if (kind == GS_APP_WIDGET_KIND_INSTALL) {
-               update_pending_apps (data->priv, 1);
                g_debug ("install %s", package_id);
                to_array[0] = package_id;
                gs_app_widget_set_kind (app_widget, GS_APP_WIDGET_KIND_BUSY);
@@ -398,50 +360,6 @@ gs_main_app_widget_button_clicked_cb (GsAppWidget *app_widget, GsMainPrivate *pr
                                                priv,
                                                (GAsyncReadyCallback) gs_main_remove_packages_cb,
                                                data);
-       } else if (kind == GS_APP_WIDGET_KIND_REMOVE) {
-
-               GtkWidget *dialog;
-               GtkWindow *window;
-               GtkResponseType response;
-               GString *markup;
-
-               window = GTK_WINDOW (gtk_builder_get_object (priv->builder, "window_software"));
-               markup = g_string_new ("");
-               g_string_append_printf (markup,
-                                       _("Are you sure you want to remove %s?"),
-                                       gs_app_get_name (app));
-               g_string_prepend (markup, "<b>");
-               g_string_append (markup, "</b>");
-               dialog = gtk_message_dialog_new (window,
-                                                GTK_DIALOG_MODAL,
-                                                GTK_MESSAGE_QUESTION,
-                                                GTK_BUTTONS_CANCEL,
-                                                NULL);
-               gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), markup->str);
-               gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
-                                                           _("%s will be removed, and you will have to 
install it to use it again."),
-                                                           gs_app_get_name (app));
-               gtk_dialog_add_button (GTK_DIALOG (dialog), _("Remove"), GTK_RESPONSE_OK);
-               response = gtk_dialog_run (GTK_DIALOG (dialog));
-               if (response == GTK_RESPONSE_OK) {
-                       update_pending_apps (data->priv, 1);
-                       g_debug ("remove %s", package_id);
-                       to_array[0] = package_id;
-                       gs_app_widget_set_kind (app_widget, GS_APP_WIDGET_KIND_BUSY);
-                       gs_app_widget_set_status (app_widget, "Removing");
-
-                       pk_task_remove_packages_async (priv->task,
-                                                      (gchar**)to_array,
-                                                      TRUE, /* allow deps */
-                                                      FALSE, /* autoremove */
-                                                      priv->cancellable,
-                                                      (PkProgressCallback) gs_main_progress_cb,
-                                                      priv,
-                                                      (GAsyncReadyCallback) gs_main_remove_packages_cb,
-                                                      data);
-               }
-               g_string_free (markup, TRUE);
-               gtk_widget_destroy (dialog);
        }
 }
 #endif
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 8a321ec..9faae16 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -914,36 +914,99 @@ gs_plugin_loader_get_pending (GsPluginLoader *plugin_loader)
        return g_ptr_array_ref (plugin_loader->priv->pending_apps);
 }
 
+typedef struct {
+       GsPluginLoader  *plugin_loader;
+       GsApp           *app;
+       GCancellable    *cancellable;
+       GThread         *thread;
+       const gchar     *function_name;
+       GsAppState       state_progress;
+       GsAppState       state_success;
+       GsAppState       state_failure;
+} GsPluginLoaderThreadHelper;
+
+/**
+ * gs_plugin_loader_thread_func:
+ **/
+static gpointer
+gs_plugin_loader_thread_func (gpointer user_data)
+{
+       GsPluginLoaderThreadHelper *helper = (GsPluginLoaderThreadHelper *) user_data;
+       gboolean ret;
+       GError *error = NULL;
+
+       /* add to list */
+       gs_app_set_state (helper->app, helper->state_progress);
+       g_ptr_array_add (helper->plugin_loader->priv->pending_apps, helper->app);
+       g_signal_emit (helper->plugin_loader, signals[SIGNAL_PENDING_APPS_CHANGED], 0);
+
+       /* run action */
+       ret = gs_plugin_loader_run_action (helper->plugin_loader,
+                                          helper->app,
+                                          helper->function_name,
+                                          helper->cancellable,
+                                          &error);
+       if (!ret) {
+               gs_app_set_state (helper->app, helper->state_failure);
+               g_warning ("failed to install: %s", error->message);
+               g_error_free (error);
+       } else {
+               gs_app_set_state (helper->app, helper->state_success);
+       }
+
+       /* remove from list */
+       g_ptr_array_remove (helper->plugin_loader->priv->pending_apps, helper->app);
+       g_signal_emit (helper->plugin_loader, signals[SIGNAL_PENDING_APPS_CHANGED], 0);
+
+       g_object_unref (helper->plugin_loader);
+       g_object_unref (helper->app);
+       g_object_unref (helper->cancellable);
+       g_free (helper);
+       return NULL;
+}
+
 /**
  * gs_plugin_loader_app_install:
  **/
-gboolean
+void
 gs_plugin_loader_app_install (GsPluginLoader *plugin_loader,
                              GsApp *app,
-                             GCancellable *cancellable,
-                             GError **error)
+                             GCancellable *cancellable)
 {
-       return gs_plugin_loader_run_action (plugin_loader,
-                                           app,
-                                           "gs_plugin_app_install",
-                                           cancellable,
-                                           error);
+       GsPluginLoaderThreadHelper *helper;
+       helper = g_new0 (GsPluginLoaderThreadHelper, 1);
+       helper->plugin_loader = g_object_ref (plugin_loader);
+       helper->app = g_object_ref (app);
+       helper->cancellable = g_object_ref (cancellable);
+       helper->function_name = "gs_plugin_app_install";
+       helper->state_progress = GS_APP_STATE_INSTALLING;
+       helper->state_success = GS_APP_STATE_INSTALLED;
+       helper->state_failure = GS_APP_STATE_AVAILABLE;
+       helper->thread = g_thread_new ("GsPluginLoader::install",
+                                      gs_plugin_loader_thread_func,
+                                      helper);
 }
 
 /**
  * gs_plugin_loader_app_remove:
  **/
-gboolean
+void
 gs_plugin_loader_app_remove (GsPluginLoader *plugin_loader,
                             GsApp *app,
-                            GCancellable *cancellable,
-                            GError **error)
+                            GCancellable *cancellable)
 {
-       return gs_plugin_loader_run_action (plugin_loader,
-                                           app,
-                                           "gs_plugin_app_remove",
-                                           cancellable,
-                                           error);
+       GsPluginLoaderThreadHelper *helper;
+       helper = g_new0 (GsPluginLoaderThreadHelper, 1);
+       helper->plugin_loader = g_object_ref (plugin_loader);
+       helper->app = g_object_ref (app);
+       helper->cancellable = g_object_ref (cancellable);
+       helper->function_name = "gs_plugin_app_remove";
+       helper->state_progress = GS_APP_STATE_REMOVING;
+       helper->state_success = GS_APP_STATE_AVAILABLE;
+       helper->state_failure = GS_APP_STATE_INSTALLED;
+       helper->thread = g_thread_new ("GsPluginLoader::remove",
+                                      gs_plugin_loader_thread_func,
+                                      helper);
 }
 
 /**
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 09ce3e5..3528f99 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -107,14 +107,12 @@ gboolean   gs_plugin_loader_app_refine            (GsPluginLoader *plugin_loader,
                                                         GsApp          *app,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
-gboolean        gs_plugin_loader_app_install           (GsPluginLoader *plugin_loader,
+void            gs_plugin_loader_app_install           (GsPluginLoader *plugin_loader,
                                                         GsApp          *app,
-                                                        GCancellable   *cancellable,
-                                                        GError         **error);
-gboolean        gs_plugin_loader_app_remove            (GsPluginLoader *plugin_loader,
+                                                        GCancellable   *cancellable);
+void            gs_plugin_loader_app_remove            (GsPluginLoader *plugin_loader,
                                                         GsApp          *app,
-                                                        GCancellable   *cancellable,
-                                                        GError         **error);
+                                                        GCancellable   *cancellable);
 gboolean        gs_plugin_loader_app_set_rating        (GsPluginLoader *plugin_loader,
                                                         GsApp          *app,
                                                         GCancellable   *cancellable,
diff --git a/src/gs-shell-installed.c b/src/gs-shell-installed.c
index 238170c..4a9ae3c 100644
--- a/src/gs-shell-installed.c
+++ b/src/gs-shell-installed.c
@@ -149,6 +149,49 @@ gs_shell_installed_app_widget_read_more_clicked_cb (GsAppWidget *app_widget,
 
        gtk_window_present (GTK_WINDOW (details));
 }
+/**
+ * gs_shell_installed_app_remove_cb:
+ **/
+static void
+gs_shell_installed_app_remove_cb (GsAppWidget *app_widget,
+                                 GsShellInstalled *shell_installed)
+{
+       GsApp *app;
+       GsShellInstalledPrivate *priv = shell_installed->priv;
+       GString *markup;
+       GtkResponseType response;
+       GtkWidget *dialog;
+       GtkWindow *window;
+
+       window = GTK_WINDOW (gtk_builder_get_object (priv->builder, "window_software"));
+       markup = g_string_new ("");
+       app = gs_app_widget_get_app (app_widget);
+       g_string_append_printf (markup,
+                               _("Are you sure you want to remove %s?"),
+                               gs_app_get_name (app));
+       g_string_prepend (markup, "<b>");
+       g_string_append (markup, "</b>");
+       dialog = gtk_message_dialog_new (window,
+                                        GTK_DIALOG_MODAL,
+                                        GTK_MESSAGE_QUESTION,
+                                        GTK_BUTTONS_CANCEL,
+                                        NULL);
+       gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), markup->str);
+       gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
+                                                   _("%s will be removed, and you will have to install it to 
use it again."),
+                                                   gs_app_get_name (app));
+       gtk_dialog_add_button (GTK_DIALOG (dialog), _("Remove"), GTK_RESPONSE_OK);
+       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       if (response == GTK_RESPONSE_OK) {
+               g_debug ("remove %s", gs_app_get_id (app));
+               gs_app_widget_set_status (app_widget, "Removing");
+               gs_plugin_loader_app_remove (priv->plugin_loader,
+                                            app,
+                                            NULL); /* cancellable */
+       }
+       g_string_free (markup, TRUE);
+       gtk_widget_destroy (dialog);
+}
 
 /**
  * gs_shell_installed_get_installed_cb:
@@ -179,10 +222,9 @@ gs_shell_installed_get_installed_cb (GObject *source_object,
                app = GS_APP (l->data);
                g_debug ("adding installed %s", gs_app_get_id (app));
                widget = gs_app_widget_new ();
-//FIXME: We need to connect this to allow removal in the list
-//             g_signal_connect (widget, "button-clicked",
-//                               G_CALLBACK (gs_shell_installed_app_widget_button_clicked_cb),
-//                               shell_installed);
+               g_signal_connect (widget, "button-clicked",
+                                 G_CALLBACK (gs_shell_installed_app_remove_cb),
+                                 shell_installed);
                g_signal_connect (widget, "read-more-clicked",
                                  G_CALLBACK (gs_shell_installed_app_widget_read_more_clicked_cb),
                                  shell_installed);
@@ -341,6 +383,29 @@ gs_shell_installed_list_header_func (GtkListBoxRow *row,
 }
 
 /**
+ * gs_shell_installed_pending_apps_changed_cb:
+ */
+static void
+gs_shell_installed_pending_apps_changed_cb (GsPluginLoader *plugin_loader,
+                                           GsShellInstalled *shell_installed)
+{
+       gchar *label;
+       GPtrArray *pending;
+       GtkWidget *widget;
+
+       widget = GTK_WIDGET (gtk_builder_get_object (shell_installed->priv->builder,
+                                                    "label_button_installed"));
+       pending = gs_plugin_loader_get_pending (plugin_loader);
+       if (pending->len == 0)
+               label = g_strdup (_("Installed"));
+       else
+               label = g_strdup_printf (_("Installed (%d)"), pending->len);
+       gtk_label_set_label (GTK_LABEL (widget), label);
+       g_free (label);
+       g_ptr_array_unref (pending);
+}
+
+/**
  * gs_shell_installed_setup:
  */
 void
@@ -354,6 +419,10 @@ gs_shell_installed_setup (GsShellInstalled *shell_installed,
        g_return_if_fail (GS_IS_SHELL_INSTALLED (shell_installed));
 
        priv->plugin_loader = g_object_ref (plugin_loader);
+       g_signal_connect (priv->plugin_loader, "pending-apps-changed",
+                         G_CALLBACK (gs_shell_installed_pending_apps_changed_cb),
+                         shell_installed);
+
        priv->builder = g_object_ref (builder);
 
        /* refilter on search box changing */


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