[gnome-software/gnome-3-14] Show installation progress when installing applications



commit 707aea5c5ea0571875871ec7052f0d29a36d8188
Author: Kalev Lember <klember redhat com>
Date:   Mon Aug 3 13:32:25 2015 +0200

    Show installation progress when installing applications
    
    This backports the following commits from master:
    
    da59a0c Show installation progress when installing applications
    8c5db4f Add a separate button style class for install progress
    fdc5ecb app row: Hide the spinner during install
    706bb64 Break out the progress button as a separate class
    f9435c4 packagekit: Propagate 0 percent of progress as well
    d420dec packagekit: Make sure progress gets correctly associated with an app
    abab83d Show app install progress on the details page as well
    0d4cbda Simplify progress marshalling code

 src/Makefile.am                    |    2 +
 src/gs-app-row.c                   |   18 ++++++-
 src/gs-app-row.ui                  |    2 +-
 src/gs-app.c                       |   44 ++++++++++++++++
 src/gs-app.h                       |    3 +
 src/gs-plugin.c                    |   33 ++++++++++++
 src/gs-plugin.h                    |    3 +
 src/gs-progress-button.c           |   98 +++++++++++++++++++++++++++++++++++
 src/gs-progress-button.h           |   61 ++++++++++++++++++++++
 src/gs-shell-details.c             |   37 +++++++++++++-
 src/gs-shell-details.ui            |    2 +-
 src/plugins/gs-plugin-packagekit.c |  100 +++++++++++++++++++++++++----------
 12 files changed, 369 insertions(+), 34 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index aaf2350..c6bd080 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -125,6 +125,8 @@ gnome_software_SOURCES =                            \
        gs-plugin.h                                     \
        gs-profile.c                                    \
        gs-profile.h                                    \
+       gs-progress-button.c                            \
+       gs-progress-button.h                            \
        gs-screenshot-image.c                           \
        gs-screenshot-image.h                           \
        gs-shell.c                                      \
diff --git a/src/gs-app-row.c b/src/gs-app-row.c
index e306731..2ddc4d5 100644
--- a/src/gs-app-row.c
+++ b/src/gs-app-row.c
@@ -28,6 +28,7 @@
 #include "gs-app-row.h"
 #include "gs-star-widget.h"
 #include "gs-markdown.h"
+#include "gs-progress-button.h"
 #include "gs-utils.h"
 #include "gs-folders.h"
 
@@ -129,6 +130,18 @@ gs_app_row_refresh (GsAppRow *app_row)
        if (app_row->priv->app == NULL)
                return;
 
+       /* do a fill bar for the current progress */
+       switch (gs_app_get_state (priv->app)) {
+       case AS_APP_STATE_INSTALLING:
+               gs_progress_button_set_progress (GS_PROGRESS_BUTTON (priv->button),
+                                                gs_app_get_progress (priv->app));
+               gs_progress_button_set_show_progress (GS_PROGRESS_BUTTON (priv->button), TRUE);
+               break;
+       default:
+               gs_progress_button_set_show_progress (GS_PROGRESS_BUTTON (priv->button), FALSE);
+               break;
+       }
+
        /* join the lines*/
        str = gs_app_row_get_description (app_row);
        gs_string_replace (str, "\n", " ");
@@ -219,8 +232,6 @@ gs_app_row_refresh (GsAppRow *app_row)
                        gtk_style_context_add_class (context, "destructive-action");
                break;
        case AS_APP_STATE_INSTALLING:
-               gtk_spinner_start (GTK_SPINNER (priv->spinner));
-               gtk_widget_set_visible (priv->spinner, TRUE);
                gtk_widget_set_visible (priv->button, TRUE);
                gtk_widget_set_sensitive (priv->button, FALSE);
                /* TRANSLATORS: this is a button next to the search results that
@@ -338,6 +349,9 @@ gs_app_row_set_app (GsAppRow *app_row, GsApp *app)
        g_signal_connect_object (app_row->priv->app, "notify::rating",
                                 G_CALLBACK (gs_app_row_notify_props_changed_cb),
                                 app_row, 0);
+       g_signal_connect_object (app_row->priv->app, "notify::progress",
+                                G_CALLBACK (gs_app_row_notify_props_changed_cb),
+                                app_row, 0);
        gs_app_row_refresh (app_row);
 }
 
diff --git a/src/gs-app-row.ui b/src/gs-app-row.ui
index bf65033..b4f0645 100644
--- a/src/gs-app-row.ui
+++ b/src/gs-app-row.ui
@@ -122,7 +122,7 @@
             <property name="halign">end</property>
             <property name="valign">center</property>
             <child>
-              <object class="GtkButton" id="button">
+              <object class="GsProgressButton" id="button">
                 <property name="margin_end">24</property>
                 <property name="width_request">100</property>
                 <property name="halign">end</property>
diff --git a/src/gs-app.c b/src/gs-app.c
index e3a5d5d..4eb22b3 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -86,6 +86,7 @@ struct GsAppPrivate
        GsAppKind                kind;
        AsIdKind                 id_kind;
        AsAppState               state;
+       guint                    progress;
        GHashTable              *metadata;
        GdkPixbuf               *pixbuf;
        GdkPixbuf               *featured_pixbuf;
@@ -109,6 +110,7 @@ enum {
        PROP_RATING,
        PROP_KIND,
        PROP_STATE,
+       PROP_PROGRESS,
        PROP_INSTALL_DATE,
        PROP_LAST
 };
@@ -179,6 +181,8 @@ gs_app_to_string (GsApp *app)
        }
        g_string_append_printf (str, "\tstate:\t%s\n",
                                as_app_state_to_string (priv->state));
+       if (priv->progress > 0)
+               g_string_append_printf (str, "\tprogress:\t%i%%\n", priv->progress);
        if (priv->id != NULL)
                g_string_append_printf (str, "\tid:\t%s\n", priv->id);
        if ((priv->kudos & GS_APP_KUDO_MY_LANGUAGE) > 0)
@@ -365,6 +369,16 @@ gs_app_get_state (GsApp *app)
 }
 
 /**
+ * gs_app_get_progress:
+ */
+guint
+gs_app_get_progress (GsApp *app)
+{
+       g_return_val_if_fail (GS_IS_APP (app), 0);
+       return app->priv->progress;
+}
+
+/**
  * gs_app_set_state_internal:
  */
 static gboolean
@@ -465,6 +479,22 @@ gs_app_set_state_internal (GsApp *app, AsAppState state)
 }
 
 /**
+ * gs_app_set_progress:
+ *
+ * This sets the progress completion of the application.
+ */
+void
+gs_app_set_progress (GsApp *app, guint percentage)
+{
+       GsAppPrivate *priv = app->priv;
+       g_return_if_fail (GS_IS_APP (app));
+       if (priv->progress == percentage)
+               return;
+       priv->progress = percentage;
+       gs_app_queue_notify (app, "progress");
+}
+
+/**
  * gs_app_set_state:
  *
  * This sets the state of the application. The following state diagram explains
@@ -1859,6 +1889,9 @@ gs_app_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *
        case PROP_STATE:
                g_value_set_uint (value, priv->state);
                break;
+       case PROP_PROGRESS:
+               g_value_set_uint (value, priv->progress);
+               break;
        case PROP_INSTALL_DATE:
                g_value_set_uint64 (value, priv->install_date);
                break;
@@ -1875,6 +1908,7 @@ static void
 gs_app_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
        GsApp *app = GS_APP (object);
+       GsAppPrivate *priv = app->priv;
 
        switch (prop_id) {
        case PROP_ID:
@@ -1907,6 +1941,9 @@ gs_app_set_property (GObject *object, guint prop_id, const GValue *value, GParam
        case PROP_STATE:
                gs_app_set_state_internal (app, g_value_get_uint (value));
                break;
+       case PROP_PROGRESS:
+               priv->progress = g_value_get_uint (value);
+               break;
        case PROP_INSTALL_DATE:
                gs_app_set_install_date (app, g_value_get_uint64 (value));
                break;
@@ -1994,6 +2031,13 @@ gs_app_class_init (GsAppClass *klass)
                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
        g_object_class_install_property (object_class, PROP_STATE, pspec);
 
+       /**
+        * GsApp:progress:
+        */
+       pspec = g_param_spec_uint ("progress", NULL, NULL, 0, 100, 0,
+                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+       g_object_class_install_property (object_class, PROP_PROGRESS, pspec);
+
        pspec = g_param_spec_uint64 ("install-date", NULL, NULL,
                                     0, G_MAXUINT64, 0,
                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
diff --git a/src/gs-app.h b/src/gs-app.h
index 4fddcbe..699bc6d 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -129,6 +129,9 @@ void                 gs_app_set_id_kind             (GsApp          *app,
 AsAppState      gs_app_get_state               (GsApp          *app);
 void            gs_app_set_state               (GsApp          *app,
                                                 AsAppState      state);
+guint           gs_app_get_progress            (GsApp          *app);
+void            gs_app_set_progress            (GsApp          *app,
+                                                guint           percentage);
 const gchar    *gs_app_get_name                (GsApp          *app);
 void            gs_app_set_name                (GsApp          *app,
                                                 GsAppQuality    quality,
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index d7411e5..78fc6d6 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -244,6 +244,7 @@ typedef struct {
        GsPlugin        *plugin;
        GsApp           *app;
        GsPluginStatus   status;
+       guint            percentage;
 } GsPluginStatusHelper;
 
 /**
@@ -282,6 +283,38 @@ gs_plugin_status_update (GsPlugin *plugin, GsApp *app, GsPluginStatus status)
 }
 
 /**
+ * gs_plugin_progress_update_cb:
+ **/
+static gboolean
+gs_plugin_progress_update_cb (gpointer user_data)
+{
+       GsPluginStatusHelper *helper = (GsPluginStatusHelper *) user_data;
+
+       gs_app_set_progress (helper->app, helper->percentage);
+       g_object_unref (helper->app);
+       g_slice_free (GsPluginStatusHelper, helper);
+       return FALSE;
+}
+
+/**
+ * gs_plugin_progress_update:
+ **/
+void
+gs_plugin_progress_update (GsPlugin *plugin, GsApp *app, guint percentage)
+{
+       GsPluginStatusHelper *helper;
+
+       if (app == NULL)
+               return;
+
+       helper = g_slice_new0 (GsPluginStatusHelper);
+       helper->plugin = plugin;
+       helper->percentage = percentage;
+       helper->app = g_object_ref (app);
+       g_idle_add (gs_plugin_progress_update_cb, helper);
+}
+
+/**
  * gs_plugin_updates_changed_cb:
  **/
 static gboolean
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 5c9399e..ced46bd 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -173,6 +173,9 @@ void                 gs_plugin_list_randomize               (GList          **list);
 void            gs_plugin_status_update                (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         GsPluginStatus  status);
+void            gs_plugin_progress_update              (GsPlugin       *plugin,
+                                                        GsApp          *app,
+                                                        guint           percentage);
 void            gs_plugin_updates_changed              (GsPlugin       *plugin);
 const gchar    *gs_plugin_status_to_string             (GsPluginStatus  status);
 gboolean        gs_plugin_add_search                   (GsPlugin       *plugin,
diff --git a/src/gs-progress-button.c b/src/gs-progress-button.c
new file mode 100644
index 0000000..aea60aa
--- /dev/null
+++ b/src/gs-progress-button.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013-2014 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "gs-progress-button.h"
+
+struct _GsProgressButtonPrivate
+{
+       GtkCssProvider  *css_provider;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GsProgressButton, gs_progress_button, GTK_TYPE_BUTTON)
+
+void
+gs_progress_button_set_progress (GsProgressButton *button, guint percentage)
+{
+       GsProgressButtonPrivate *priv = gs_progress_button_get_instance_private (button);
+       gchar *css;
+
+       if (percentage == 0)
+               css = g_strdup (".button.install-progress { background: @theme_bg_color; }");
+       else if (percentage == 100)
+               css = g_strdup (".button.install-progress { background: @theme_selected_bg_color; }");
+       else
+               css = g_strdup_printf (".button.install-progress { background: linear-gradient(to right, 
@theme_selected_bg_color %d%%, @theme_bg_color %d%%); }", percentage, percentage + 1);
+
+       gtk_css_provider_load_from_data (priv->css_provider, css, -1, NULL);
+       g_free (css);
+}
+
+void
+gs_progress_button_set_show_progress (GsProgressButton *button, gboolean show_progress)
+{
+       GtkStyleContext *context;
+
+       context = gtk_widget_get_style_context (GTK_WIDGET (button));
+       if (show_progress)
+               gtk_style_context_add_class (context, "install-progress");
+       else
+               gtk_style_context_remove_class (context, "install-progress");
+}
+
+static void
+gs_progress_button_dispose (GObject *object)
+{
+       GsProgressButton *button = GS_PROGRESS_BUTTON (object);
+       GsProgressButtonPrivate *priv = gs_progress_button_get_instance_private (button);
+
+       g_clear_object (&priv->css_provider);
+
+       G_OBJECT_CLASS (gs_progress_button_parent_class)->dispose (object);
+}
+
+static void
+gs_progress_button_init (GsProgressButton *button)
+{
+       GsProgressButtonPrivate *priv = gs_progress_button_get_instance_private (button);
+
+       priv->css_provider = gtk_css_provider_new ();
+       gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (button)),
+                                       GTK_STYLE_PROVIDER (priv->css_provider),
+                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
+static void
+gs_progress_button_class_init (GsProgressButtonClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = gs_progress_button_dispose;
+}
+
+GtkWidget *
+gs_progress_button_new (void)
+{
+       return g_object_new (GS_TYPE_PROGRESS_BUTTON, NULL);
+}
+
+/* vim: set noexpandtab: */
diff --git a/src/gs-progress-button.h b/src/gs-progress-button.h
new file mode 100644
index 0000000..ba10d21
--- /dev/null
+++ b/src/gs-progress-button.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013-2014 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef GS_PROGRESS_BUTTON_H
+#define GS_PROGRESS_BUTTON_H
+
+#include <gtk/gtk.h>
+
+#define GS_TYPE_PROGRESS_BUTTON                        (gs_progress_button_get_type())
+#define GS_PROGRESS_BUTTON(obj)                        (G_TYPE_CHECK_INSTANCE_CAST((obj), 
GS_TYPE_PROGRESS_BUTTON, GsProgressButton))
+#define GS_PROGRESS_BUTTON_CLASS(cls)          (G_TYPE_CHECK_CLASS_CAST((cls), GS_TYPE_PROGRESS_BUTTON, 
GsProgressButtonClass))
+#define GS_IS_PROGRESS_BUTTON(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj), GS_TYPE_PROGRESS_BUTTON))
+#define GS_IS_PROGRESS_BUTTON_CLASS(cls)       (G_TYPE_CHECK_CLASS_TYPE((cls), GS_TYPE_PROGRESS_BUTTON))
+#define GS_PROGRESS_BUTTON_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), GS_TYPE_PROGRESS_BUTTON, 
GsProgressButtonClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GsProgressButton               GsProgressButton;
+typedef struct _GsProgressButtonClass          GsProgressButtonClass;
+typedef struct _GsProgressButtonPrivate                GsProgressButtonPrivate;
+
+struct _GsProgressButton
+{
+       GtkButton        parent;
+};
+
+struct _GsProgressButtonClass
+{
+       GtkButtonClass   parent_class;
+};
+
+GType           gs_progress_button_get_type            (void);
+GtkWidget      *gs_progress_button_new                 (void);
+void            gs_progress_button_set_progress        (GsProgressButton       *button,
+                                                        guint                   percentage);
+void            gs_progress_button_set_show_progress   (GsProgressButton       *button,
+                                                        gboolean                show_progress);
+
+G_END_DECLS
+
+#endif /* GS_PROGRESS_BUTTON_H */
+
+/* vim: set noexpandtab: */
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index 0d2ed48..129e4cf 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -33,6 +33,7 @@
 #include "gs-app-addon-row.h"
 #include "gs-history-dialog.h"
 #include "gs-screenshot-image.h"
+#include "gs-progress-button.h"
 #include "gs-star-widget.h"
 
 static void    gs_shell_details_finalize       (GObject        *object);
@@ -238,6 +239,16 @@ gs_shell_details_switch_to (GsShellDetails *shell_details)
                }
        }
 
+       /* do a fill bar for the current progress */
+       switch (gs_app_get_state (priv->app)) {
+       case AS_APP_STATE_INSTALLING:
+               gs_progress_button_set_show_progress (GS_PROGRESS_BUTTON (priv->button_install), TRUE);
+               break;
+       default:
+               gs_progress_button_set_show_progress (GS_PROGRESS_BUTTON (priv->button_install), FALSE);
+               break;
+       }
+
        /* spinner */
        if (kind == GS_APP_KIND_SYSTEM) {
                gtk_widget_set_visible (priv->spinner_install_remove, FALSE);
@@ -251,10 +262,10 @@ gs_shell_details_switch_to (GsShellDetails *shell_details)
                case AS_APP_STATE_UPDATABLE:
                case AS_APP_STATE_UNAVAILABLE:
                case AS_APP_STATE_AVAILABLE_LOCAL:
+               case AS_APP_STATE_INSTALLING:
                        gtk_widget_set_visible (priv->spinner_install_remove, FALSE);
                        gtk_spinner_stop (GTK_SPINNER (priv->spinner_install_remove));
                        break;
-               case AS_APP_STATE_INSTALLING:
                case AS_APP_STATE_REMOVING:
                        gtk_spinner_start (GTK_SPINNER (priv->spinner_install_remove));
                        gtk_widget_set_visible (priv->spinner_install_remove, TRUE);
@@ -273,6 +284,27 @@ gs_shell_details_switch_to (GsShellDetails *shell_details)
 }
 
 static gboolean
+gs_shell_details_refresh_progress_idle (gpointer user_data)
+{
+       GsShellDetails *shell_details = GS_SHELL_DETAILS (user_data);
+       GsShellDetailsPrivate *priv = shell_details->priv;
+
+       gs_progress_button_set_progress (GS_PROGRESS_BUTTON (priv->button_install),
+                                        gs_app_get_progress (priv->app));
+
+       g_object_unref (shell_details);
+       return G_SOURCE_REMOVE;
+}
+
+static void
+gs_shell_details_progress_changed_cb (GsApp *app,
+                                      GParamSpec *pspec,
+                                      GsShellDetails *shell_details)
+{
+       g_idle_add (gs_shell_details_refresh_progress_idle, g_object_ref (shell_details));
+}
+
+static gboolean
 gs_shell_details_switch_to_idle (gpointer user_data)
 {
        GsShellDetails *shell_details = GS_SHELL_DETAILS (user_data);
@@ -1033,6 +1065,9 @@ gs_shell_details_set_app (GsShellDetails *shell_details, GsApp *app)
        g_signal_connect_object (priv->app, "notify::licence",
                                 G_CALLBACK (gs_shell_details_notify_state_changed_cb),
                                 shell_details, 0);
+       g_signal_connect_object (priv->app, "notify::progress",
+                                G_CALLBACK (gs_shell_details_progress_changed_cb),
+                                shell_details, 0);
        gs_shell_details_load (shell_details);
 
        /* change widgets */
diff --git a/src/gs-shell-details.ui b/src/gs-shell-details.ui
index 786185c..70c0e5b 100644
--- a/src/gs-shell-details.ui
+++ b/src/gs-shell-details.ui
@@ -139,7 +139,7 @@
                                 <property name="can_focus">False</property>
                                 <property name="spacing">6</property>
                                 <child>
-                                  <object class="GtkButton" id="button_install">
+                                  <object class="GsProgressButton" id="button_install">
                                     <property name="use_underline">True</property>
                                     <property name="label" translatable="yes">_Install</property>
                                     <property name="width_request">105</property>
diff --git a/src/plugins/gs-plugin-packagekit.c b/src/plugins/gs-plugin-packagekit.c
index a859352..44e7d6a 100644
--- a/src/plugins/gs-plugin-packagekit.c
+++ b/src/plugins/gs-plugin-packagekit.c
@@ -65,6 +65,11 @@ gs_plugin_destroy (GsPlugin *plugin)
        g_object_unref (plugin->priv->task);
 }
 
+typedef struct {
+       GsApp           *app;
+       GsPlugin        *plugin;
+} ProgressData;
+
 /**
  * gs_plugin_packagekit_progress_cb:
  **/
@@ -73,28 +78,37 @@ gs_plugin_packagekit_progress_cb (PkProgress *progress,
                                  PkProgressType type,
                                  gpointer user_data)
 {
-       GsPluginStatus plugin_status;
-       PkStatusEnum status;
-       GsPlugin *plugin = GS_PLUGIN (user_data);
-
-       if (type != PK_PROGRESS_TYPE_STATUS)
-               return;
-       g_object_get (progress,
-                     "status", &status,
-                     NULL);
-
-       /* profile */
-       if (status == PK_STATUS_ENUM_SETUP) {
-               gs_profile_start (plugin->profile,
-                                 "packagekit-refine::transaction");
-       } else if (status == PK_STATUS_ENUM_FINISHED) {
-               gs_profile_stop (plugin->profile,
-                                "packagekit-refine::transaction");
-       }
+       ProgressData *data = (ProgressData *) user_data;
+       GsPlugin *plugin = data->plugin;
+
+       if (type == PK_PROGRESS_TYPE_STATUS) {
+               GsPluginStatus plugin_status;
+               PkStatusEnum status;
+               g_object_get (progress,
+                             "status", &status,
+                             NULL);
+
+               /* profile */
+               if (status == PK_STATUS_ENUM_SETUP) {
+                       gs_profile_start (plugin->profile,
+                                         "packagekit-refine::transaction");
+               } else if (status == PK_STATUS_ENUM_FINISHED) {
+                       gs_profile_stop (plugin->profile,
+                                        "packagekit-refine::transaction");
+               }
 
-       plugin_status = packagekit_status_enum_to_plugin_status (status);
-       if (plugin_status != GS_PLUGIN_STATUS_UNKNOWN)
-               gs_plugin_status_update (plugin, NULL, plugin_status);
+               plugin_status = packagekit_status_enum_to_plugin_status (status);
+               if (plugin_status != GS_PLUGIN_STATUS_UNKNOWN)
+                       gs_plugin_status_update (plugin, NULL, plugin_status);
+
+       } else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+               gint percentage;
+               g_object_get (progress,
+                             "percentage", &percentage,
+                             NULL);
+               if (percentage >= 0 && percentage <= 100)
+                       gs_plugin_progress_update (plugin, data->app, percentage);
+       }
 }
 
 /**
@@ -108,8 +122,12 @@ gs_plugin_add_installed (GsPlugin *plugin,
 {
        gboolean ret = TRUE;
        PkBitfield filter;
+       ProgressData data;
        PkResults *results;
 
+       data.app = NULL;
+       data.plugin = plugin;
+
        /* update UI as this might take some time */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
 
@@ -123,7 +141,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
        results = pk_client_get_packages (PK_CLIENT(plugin->priv->task),
                                          filter,
                                          cancellable,
-                                         gs_plugin_packagekit_progress_cb, plugin,
+                                         gs_plugin_packagekit_progress_cb, &data,
                                          error);
        if (results == NULL) {
                ret = FALSE;
@@ -155,10 +173,14 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
        GsApp *app_tmp;
        PkBitfield filter;
        PkResults *results = NULL;
+       ProgressData data;
        const gchar *id;
        gboolean ret = TRUE;
        gchar **split;
 
+       data.app = NULL;
+       data.plugin = plugin;
+
        gs_profile_start (plugin->profile, "packagekit::add-sources-related");
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED,
                                         PK_FILTER_ENUM_NEWEST,
@@ -168,7 +190,7 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
        results = pk_client_get_packages (PK_CLIENT(plugin->priv->task),
                                           filter,
                                           cancellable,
-                                          gs_plugin_packagekit_progress_cb, plugin,
+                                          gs_plugin_packagekit_progress_cb, &data,
                                           error);
        if (results == NULL) {
                ret = FALSE;
@@ -216,11 +238,15 @@ gs_plugin_add_sources (GsPlugin *plugin,
        PkBitfield filter;
        PkRepoDetail *rd;
        PkResults *results;
+       ProgressData data;
        const gchar *id;
        gboolean ret = TRUE;
        guint i;
        GHashTable *hash = NULL;
 
+       data.app = NULL;
+       data.plugin = plugin;
+
        /* ask PK for the repo details */
        filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_SOURCE,
                                         PK_FILTER_ENUM_NOT_SUPPORTED,
@@ -229,7 +255,7 @@ gs_plugin_add_sources (GsPlugin *plugin,
        results = pk_client_get_repo_list (PK_CLIENT(plugin->priv->task),
                                           filter,
                                           cancellable,
-                                          gs_plugin_packagekit_progress_cb, plugin,
+                                          gs_plugin_packagekit_progress_cb, &data,
                                           error);
        if (results == NULL) {
                ret = FALSE;
@@ -288,11 +314,15 @@ gs_plugin_app_install (GsPlugin *plugin,
        GPtrArray *source_ids;
        PkError *error_code = NULL;
        PkResults *results = NULL;
+       ProgressData data;
        const gchar *package_id;
        gboolean ret = TRUE;
        gchar **package_ids = NULL;
        guint i, j;
 
+       data.app = app;
+       data.plugin = plugin;
+
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "PackageKit") != 0)
                goto out;
@@ -353,7 +383,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                results = pk_task_install_packages_sync (plugin->priv->task,
                                                         (gchar **) array_package_ids->pdata,
                                                         cancellable,
-                                                        gs_plugin_packagekit_progress_cb, plugin,
+                                                        gs_plugin_packagekit_progress_cb, &data,
                                                         error);
                if (results == NULL) {
                        ret = FALSE;
@@ -375,7 +405,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                results = pk_task_install_files_sync (plugin->priv->task,
                                                      package_ids,
                                                      cancellable,
-                                                     gs_plugin_packagekit_progress_cb, plugin,
+                                                     gs_plugin_packagekit_progress_cb, &data,
                                                      error);
                if (results == NULL) {
                        ret = FALSE;
@@ -429,6 +459,10 @@ gs_plugin_app_source_disable (GsPlugin *plugin,
 {
        gboolean ret = TRUE;
        PkResults *results;
+       ProgressData data;
+
+       data.app = NULL;
+       data.plugin = plugin;
 
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
@@ -436,7 +470,7 @@ gs_plugin_app_source_disable (GsPlugin *plugin,
                                         gs_app_get_id (app),
                                         FALSE,
                                         cancellable,
-                                        gs_plugin_packagekit_progress_cb, plugin,
+                                        gs_plugin_packagekit_progress_cb, &data,
                                         error);
        if (results == NULL) {
                ret = FALSE;
@@ -460,8 +494,12 @@ gs_plugin_app_source_remove (GsPlugin *plugin,
        gboolean ret = TRUE;
 #if PK_CHECK_VERSION(0,9,1)
        PkResults *results;
+       ProgressData data;
        GError *error_local = NULL;
 
+       data.app = NULL;
+       data.plugin = plugin;
+
        /* do sync call */
        gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING);
        results = pk_client_repo_remove (PK_CLIENT (plugin->priv->task),
@@ -469,7 +507,7 @@ gs_plugin_app_source_remove (GsPlugin *plugin,
                                         gs_app_get_id (app),
                                         TRUE,
                                         cancellable,
-                                        gs_plugin_packagekit_progress_cb, plugin,
+                                        gs_plugin_packagekit_progress_cb, &data,
                                         &error_local);
        if (results == NULL) {
                /* fall back to disabling it */
@@ -506,10 +544,14 @@ gs_plugin_app_remove (GsPlugin *plugin,
        GPtrArray *array = NULL;
        PkError *error_code = NULL;
        PkResults *results = NULL;
+       ProgressData data;
        GPtrArray *source_ids;
        guint i;
        guint cnt = 0;
 
+       data.app = NULL;
+       data.plugin = plugin;
+
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "PackageKit") != 0)
                goto out;
@@ -555,7 +597,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
                                                package_ids,
                                                TRUE, FALSE,
                                                cancellable,
-                                               gs_plugin_packagekit_progress_cb, plugin,
+                                               gs_plugin_packagekit_progress_cb, &data,
                                                error);
        if (results == NULL) {
                ret = FALSE;



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