[gnome-software/wip/rancell/permissions] Connect permission changes through to plugins



commit 68cb44db030fac6d469dda22100c1fb4c7b5a897
Author: Robert Ancell <robert ancell canonical com>
Date:   Tue Aug 15 15:52:48 2017 +1200

    Connect permission changes through to plugins

 lib/gs-plugin-job-private.h   |    2 +
 lib/gs-plugin-job.c           |   58 ++++++++++++++++++++++++
 lib/gs-plugin-job.h           |    5 ++
 lib/gs-plugin-loader.c        |   15 ++++++
 lib/gs-plugin-types.h         |    2 +
 lib/gs-plugin-vfuncs.h        |   21 +++++++++
 lib/gs-plugin.c               |    6 +++
 plugins/snap/gs-plugin-snap.c |   15 ++++++
 src/gs-details-page.c         |   10 ++++
 src/gs-page.c                 |   30 +++++++++++++
 src/gs-page.h                 |    5 ++
 src/gs-permission-dialog.c    |   41 +++++++++++++----
 src/gs-permission-switch.c    |   97 +++++++++++++++++++++++++++++++++++++++++
 src/gs-permission-switch.h    |   41 +++++++++++++++++
 src/meson.build               |    1 +
 15 files changed, 339 insertions(+), 10 deletions(-)
---
diff --git a/lib/gs-plugin-job-private.h b/lib/gs-plugin-job-private.h
index 447e21d..f9f2cfd 100644
--- a/lib/gs-plugin-job-private.h
+++ b/lib/gs-plugin-job-private.h
@@ -52,6 +52,8 @@ GsPlugin              *gs_plugin_job_get_plugin               (GsPluginJob    *self);
 GsCategory             *gs_plugin_job_get_category             (GsPluginJob    *self);
 AsReview               *gs_plugin_job_get_review               (GsPluginJob    *self);
 GsPrice                        *gs_plugin_job_get_price                (GsPluginJob    *self);
+GsPermission           *gs_plugin_job_get_permission           (GsPluginJob    *self);
+gboolean                gs_plugin_job_get_permission_value     (GsPluginJob    *self);
 gchar                  *gs_plugin_job_to_string                (GsPluginJob    *self);
 void                    gs_plugin_job_set_action               (GsPluginJob    *self,
                                                                 GsPluginAction  action);
diff --git a/lib/gs-plugin-job.c b/lib/gs-plugin-job.c
index b862412..0973674 100644
--- a/lib/gs-plugin-job.c
+++ b/lib/gs-plugin-job.c
@@ -47,6 +47,8 @@ struct _GsPluginJob
        GsCategory              *category;
        AsReview                *review;
        GsPrice                 *price;
+       GsPermission            *permission;
+       gboolean                 permission_value;
        gint64                   time_created;
 };
 
@@ -67,6 +69,8 @@ enum {
        PROP_MAX_RESULTS,
        PROP_PRICE,
        PROP_TIMEOUT,
+       PROP_PERMISSION,
+       PROP_PERMISSION_VALUE,
        PROP_LAST
 };
 
@@ -128,6 +132,9 @@ gs_plugin_job_to_string (GsPluginJob *self)
                g_autofree gchar *path = g_file_get_path (self->file);
                g_string_append_printf (str, " with file=%s", path);
        }
+       if (self->permission != NULL) {
+               g_string_append_printf (str, " with permission=%s:%s", gs_permission_get_label 
(self->permission), self->permission_value ? "true" : "false");
+       }
        if (self->plugin != NULL) {
                g_string_append_printf (str, " on plugin=%s",
                                        gs_plugin_get_name (self->plugin));
@@ -430,6 +437,34 @@ gs_plugin_job_get_price (GsPluginJob *self)
        return self->price;
 }
 
+void
+gs_plugin_job_set_permission (GsPluginJob *self, GsPermission *permission)
+{
+       g_return_if_fail (GS_IS_PLUGIN_JOB (self));
+       g_set_object (&self->permission, permission);
+}
+
+GsPermission *
+gs_plugin_job_get_permission (GsPluginJob *self)
+{
+       g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), NULL);
+       return self->permission;
+}
+
+void
+gs_plugin_job_set_permission_value (GsPluginJob *self, gboolean value)
+{
+       g_return_if_fail (GS_IS_PLUGIN_JOB (self));
+       self->permission_value = value;
+}
+
+gboolean
+gs_plugin_job_get_permission_value (GsPluginJob *self)
+{
+       g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), FALSE);
+       return self->permission_value;
+}
+
 static void
 gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec)
 {
@@ -481,6 +516,12 @@ gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSp
        case PROP_TIMEOUT:
                g_value_set_uint (value, self->timeout);
                break;
+       case PROP_PERMISSION:
+               g_value_set_object (value, self->permission);
+               break;
+       case PROP_PERMISSION_VALUE:
+               g_value_set_boolean (value, self->permission_value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
                break;
@@ -538,6 +579,12 @@ gs_plugin_job_set_property (GObject *obj, guint prop_id, const GValue *value, GP
        case PROP_PRICE:
                gs_plugin_job_set_price (self, g_value_get_object (value));
                break;
+       case PROP_PERMISSION:
+               gs_plugin_job_set_permission (self, g_value_get_object (value));
+               break;
+       case PROP_PERMISSION_VALUE:
+               gs_plugin_job_set_permission_value (self, g_value_get_boolean (value));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
                break;
@@ -557,6 +604,7 @@ gs_plugin_job_finalize (GObject *obj)
        g_clear_object (&self->category);
        g_clear_object (&self->review);
        g_clear_object (&self->price);
+       g_clear_object (&self->permission);
        G_OBJECT_CLASS (gs_plugin_job_parent_class)->finalize (obj);
 }
 
@@ -645,6 +693,16 @@ gs_plugin_job_class_init (GsPluginJobClass *klass)
                                     GS_TYPE_PRICE,
                                     G_PARAM_READWRITE);
        g_object_class_install_property (object_class, PROP_PRICE, pspec);
+
+       pspec = g_param_spec_object ("permission", NULL, NULL,
+                                    GS_TYPE_PERMISSION,
+                                    G_PARAM_READWRITE);
+       g_object_class_install_property (object_class, PROP_PERMISSION, pspec);
+
+       pspec = g_param_spec_boolean ("permission-value", NULL, NULL,
+                                     FALSE,
+                                     G_PARAM_READWRITE);
+       g_object_class_install_property (object_class, PROP_PERMISSION_VALUE, pspec);
 }
 
 static void
diff --git a/lib/gs-plugin-job.h b/lib/gs-plugin-job.h
index a7d72af..36270fb 100644
--- a/lib/gs-plugin-job.h
+++ b/lib/gs-plugin-job.h
@@ -29,6 +29,7 @@
 #include "gs-category.h"
 #include "gs-plugin-types.h"
 #include "gs-price.h"
+#include "gs-permission.h"
 
 G_BEGIN_DECLS
 
@@ -70,6 +71,10 @@ void          gs_plugin_job_set_review               (GsPluginJob    *self,
                                                         AsReview       *review);
 void            gs_plugin_job_set_price                (GsPluginJob    *self,
                                                         GsPrice        *price);
+void            gs_plugin_job_set_permission           (GsPluginJob    *self,
+                                                        GsPermission   *permission);
+void            gs_plugin_job_set_permission_value     (GsPluginJob    *self,
+                                                        gboolean        value);
 
 #define                 gs_plugin_job_newv(a,...)              
GS_PLUGIN_JOB(g_object_new(GS_TYPE_PLUGIN_JOB, "action", a, __VA_ARGS__))
 
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index a2f60f5..f498300 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -128,6 +128,12 @@ typedef gboolean    (*GsPluginPurchaseFunc)        (GsPlugin       *plugin,
                                                         GsPrice        *price,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+typedef gboolean        (*GsPluginSetPermissionFunc)   (GsPlugin       *plugin,
+                                                        GsApp          *app,
+                                                        GsPermission   *permission,
+                                                        gboolean        value,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
 typedef gboolean        (*GsPluginReviewFunc)          (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         AsReview       *review,
@@ -599,6 +605,15 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
                                           cancellable, &error_local);
                }
                break;
+       case GS_PLUGIN_ACTION_SET_PERMISSION:
+               {
+                       GsPluginSetPermissionFunc plugin_func = func;
+                       ret = plugin_func (plugin, app,
+                                          gs_plugin_job_get_permission (helper->plugin_job),
+                                          gs_plugin_job_get_permission_value (helper->plugin_job),
+                                          cancellable, &error_local);
+               }
+               break;
        case GS_PLUGIN_ACTION_REVIEW_SUBMIT:
        case GS_PLUGIN_ACTION_REVIEW_UPVOTE:
        case GS_PLUGIN_ACTION_REVIEW_DOWNVOTE:
diff --git a/lib/gs-plugin-types.h b/lib/gs-plugin-types.h
index 244b323..8ecb6b5 100644
--- a/lib/gs-plugin-types.h
+++ b/lib/gs-plugin-types.h
@@ -270,6 +270,7 @@ typedef enum {
  * @GS_PLUGIN_ACTION_INITIALIZE:               Initialize the plugin
  * @GS_PLUGIN_ACTION_DESTROY:                  Destroy the plugin
  * @GS_PLUGIN_ACTION_PURCHASE:                 Purchase an app
+ * @GS_PLUGIN_ACTION_SET_PERMISSION:           Set app permission
  *
  * The plugin action.
  **/
@@ -317,6 +318,7 @@ typedef enum {
        GS_PLUGIN_ACTION_INITIALIZE,
        GS_PLUGIN_ACTION_DESTROY,
        GS_PLUGIN_ACTION_PURCHASE,
+       GS_PLUGIN_ACTION_SET_PERMISSION,
        /*< private >*/
        GS_PLUGIN_ACTION_LAST
 } GsPluginAction;
diff --git a/lib/gs-plugin-vfuncs.h b/lib/gs-plugin-vfuncs.h
index f8d48e7..8f0c623 100644
--- a/lib/gs-plugin-vfuncs.h
+++ b/lib/gs-plugin-vfuncs.h
@@ -41,6 +41,7 @@
 #include "gs-app-list.h"
 #include "gs-category.h"
 #include "gs-price.h"
+#include "gs-permission.h"
 
 G_BEGIN_DECLS
 
@@ -728,6 +729,26 @@ gboolean    gs_plugin_app_upgrade_trigger          (GsPlugin       *plugin,
                                                         GError         **error);
 
 /**
+ * gs_plugin_app_set_permission:
+ * @plugin: a #GsPlugin
+ * @app: a #GsApp
+ * @permission: a #GsPermission to set
+ * @value: value to set for the permission
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Set an app permission.
+ *
+ * Returns: %TRUE for success or if not relevant
+ **/
+gboolean        gs_plugin_app_set_permission           (GsPlugin       *plugin,
+                                                        GsApp          *app,
+                                                        GsPermission   *permission,
+                                                        gboolean        value,
+                                                        GCancellable   *cancellable,
+                                                        GError         **error);
+
+/**
  * gs_plugin_review_submit:
  * @plugin: a #GsPlugin
  * @app: a #GsApp
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index 8fcf031..86bdd9c 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -1820,6 +1820,8 @@ gs_plugin_action_to_function_name (GsPluginAction action)
                return "gs_plugin_destroy";
        if (action == GS_PLUGIN_ACTION_PURCHASE)
                return "gs_plugin_app_purchase";
+       if (action == GS_PLUGIN_ACTION_SET_PERMISSION)
+               return "gs_plugin_app_set_permission";
        return NULL;
 }
 
@@ -1920,6 +1922,8 @@ gs_plugin_action_to_string (GsPluginAction action)
                return "destroy";
        if (action == GS_PLUGIN_ACTION_PURCHASE)
                return "purchase";
+       if (action == GS_PLUGIN_ACTION_SET_PERMISSION)
+               return "set-permission";
        return NULL;
 }
 
@@ -2020,6 +2024,8 @@ gs_plugin_action_from_string (const gchar *action)
                return GS_PLUGIN_ACTION_DESTROY;
        if (g_strcmp0 (action, "purchase") == 0)
                return GS_PLUGIN_ACTION_PURCHASE;
+       if (g_strcmp0 (action, "set-permission") == 0)
+               return GS_PLUGIN_ACTION_SET_PERMISSION;
        return GS_PLUGIN_ACTION_UNKNOWN;
 }
 
diff --git a/plugins/snap/gs-plugin-snap.c b/plugins/snap/gs-plugin-snap.c
index 32e7f28..89347d5 100644
--- a/plugins/snap/gs-plugin-snap.c
+++ b/plugins/snap/gs-plugin-snap.c
@@ -758,6 +758,21 @@ gs_plugin_app_remove (GsPlugin *plugin,
 }
 
 gboolean
+gs_plugin_app_set_permission (GsPlugin *plugin,
+                             GsApp *app,
+                             GsPermission *permission,
+                             gboolean value,
+                             GCancellable *cancellable,
+                             GError **error)
+{
+       /* We can set permissions on apps we know of */
+       if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0)
+               return TRUE;
+
+       return TRUE;
+}
+
+gboolean
 gs_plugin_auth_login (GsPlugin *plugin, GsAuth *auth,
                      GCancellable *cancellable, GError **error)
 {
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index b104485..9add994 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -1753,11 +1753,21 @@ gs_details_page_app_cancel_button_cb (GtkWidget *widget, GsDetailsPage *self)
 }
 
 static void
+gs_details_page_permission_changed_cb (GsPermissionDialog *dialog, GsPermission *permission, gboolean value, 
GsDetailsPage *self)
+{
+       g_autoptr(GCancellable) cancellable = g_cancellable_new ();
+       g_set_object (&self->cancellable, cancellable);
+       gs_page_set_app_permission (GS_PAGE (self), self->app, permission, value, self->cancellable);
+}
+
+static void
 gs_details_page_app_permissions_button_cb (GtkWidget *widget, GsDetailsPage *self)
 {
        GtkWidget *dialog;
 
        dialog = gs_permission_dialog_new (self->app);
+       g_signal_connect (dialog, "permission-changed",
+                         G_CALLBACK (gs_details_page_permission_changed_cb), self);
        gs_shell_modal_dialog_present (self->shell, GTK_DIALOG (dialog));
 
        /* just destroy */
diff --git a/src/gs-page.c b/src/gs-page.c
index 6102303..eaee346 100644
--- a/src/gs-page.c
+++ b/src/gs-page.c
@@ -734,6 +734,36 @@ gs_page_launch_app (GsPage *page, GsApp *app, GCancellable *cancellable)
 }
 
 static void
+gs_page_app_permission_set_cb (GObject *source,
+                              GAsyncResult *res,
+                              gpointer user_data)
+{
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+       g_autoptr(GError) error = NULL;
+       if (!gs_plugin_loader_job_action_finish (plugin_loader, res, &error)) {
+               g_warning ("failed to set permission on GsApp: %s", error->message);
+               return;
+       }
+}
+
+void
+gs_page_set_app_permission (GsPage *page, GsApp *app, GsPermission *permission, gboolean value, GCancellable 
*cancellable)
+{
+       GsPagePrivate *priv = gs_page_get_instance_private (page);
+       g_autoptr(GsPluginJob) plugin_job = NULL;
+       plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_SET_PERMISSION,
+                                        "app", app,
+                                        "failure-flags", GS_PLUGIN_FAILURE_FLAGS_USE_EVENTS,
+                                        "permission", permission,
+                                        "permission-value", value,
+                                        NULL);
+       gs_plugin_loader_job_process_async (priv->plugin_loader, plugin_job,
+                                           cancellable,
+                                           gs_page_app_permission_set_cb,
+                                           NULL);
+}
+
+static void
 gs_page_app_shortcut_added_cb (GObject *source,
                               GAsyncResult *res,
                               gpointer user_data)
diff --git a/src/gs-page.h b/src/gs-page.h
index ebd2792..df1b0ee 100644
--- a/src/gs-page.h
+++ b/src/gs-page.h
@@ -70,6 +70,11 @@ void          gs_page_update_app                     (GsPage         *page,
 void            gs_page_launch_app                     (GsPage         *page,
                                                         GsApp          *app,
                                                         GCancellable   *cancellable);
+void            gs_page_set_app_permission             (GsPage         *page,
+                                                        GsApp          *app,
+                                                        GsPermission   *permission,
+                                                        gboolean        value,
+                                                        GCancellable   *cancellable);
 void            gs_page_shortcut_add                   (GsPage         *page,
                                                         GsApp          *app,
                                                         GCancellable   *cancellable);
diff --git a/src/gs-permission-dialog.c b/src/gs-permission-dialog.c
index 9bb213d..2740ca8 100644
--- a/src/gs-permission-dialog.c
+++ b/src/gs-permission-dialog.c
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include "gs-permission-dialog.h"
+#include "gs-permission-switch.h"
 
 struct _GsPermissionDialog
 {
@@ -34,6 +35,13 @@ struct _GsPermissionDialog
 
 G_DEFINE_TYPE (GsPermissionDialog, gs_permission_dialog, GTK_TYPE_DIALOG)
 
+enum {
+       SIGNAL_PERMISSION_CHANGED,
+       SIGNAL_LAST
+};
+
+static guint signals [SIGNAL_LAST] = { 0 };
+
 static void
 close_button_clicked (GtkWidget *widget, GsPermissionDialog *dialog)
 {
@@ -67,6 +75,13 @@ gs_permission_dialog_class_init (GsPermissionDialogClass *klass)
 
        object_class->dispose = gs_permission_dialog_dispose;
 
+       signals [SIGNAL_PERMISSION_CHANGED] =
+               g_signal_new ("permission-changed",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             0,
+                             NULL, NULL, g_cclosure_marshal_generic,
+                             G_TYPE_NONE, 2, GS_TYPE_PERMISSION, G_TYPE_BOOLEAN);
+
        gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/Software/gs-permission-dialog.ui");
 
        gtk_widget_class_bind_template_child (widget_class, GsPermissionDialog, permission_grid);
@@ -74,21 +89,29 @@ gs_permission_dialog_class_init (GsPermissionDialogClass *klass)
 }
 
 static void
-set_row (GsPermissionDialog *dialog, int row, const gchar *text, gboolean enabled)
+switch_changed_cb (GsPermissionSwitch *sw, gboolean value, GsPermissionDialog *dialog)
+{
+       g_signal_emit (dialog, signals[SIGNAL_PERMISSION_CHANGED], 0,
+                      gs_permission_switch_get_permission (sw),
+                      value);
+}
+
+static void
+set_row (GsPermissionDialog *dialog, int row, GsPermission *permission)
 {
        GtkWidget *label;
-       GtkWidget *sw;
+       GsPermissionSwitch *sw;
 
-       label = gtk_label_new (text);
+       label = gtk_label_new (gs_permission_get_label (permission));
        gtk_label_set_xalign (GTK_LABEL (label), 1.0);
        gtk_widget_set_hexpand (label, TRUE);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (dialog->permission_grid), label, 0, row, 1, 1);
 
-       sw = gtk_switch_new ();
-       gtk_switch_set_active (GTK_SWITCH (sw), enabled);
-       gtk_widget_show (sw);
-       gtk_grid_attach (GTK_GRID (dialog->permission_grid), sw, 1, row, 1, 1);
+       sw = gs_permission_switch_new (permission);
+       gtk_widget_show (GTK_WIDGET (sw));
+       g_signal_connect (sw, "changed", G_CALLBACK (switch_changed_cb), dialog);
+       gtk_grid_attach (GTK_GRID (dialog->permission_grid), GTK_WIDGET (sw), 1, row, 1, 1);
 }
 
 GtkWidget *
@@ -106,9 +129,7 @@ gs_permission_dialog_new (GsApp *app)
        permissions = gs_app_get_permissions (app);
        for (i = 0; i < permissions->len; i++) {
                GsPermission *permission = g_ptr_array_index (permissions, i);
-               set_row (dialog, i,
-                        gs_permission_get_label (permission),
-                        gs_permission_get_enabled (permission));
+               set_row (dialog, i, permission);
        }
 
        return GTK_WIDGET (dialog);
diff --git a/src/gs-permission-switch.c b/src/gs-permission-switch.c
new file mode 100644
index 0000000..3ba85ac
--- /dev/null
+++ b/src/gs-permission-switch.c
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2017 Canonical Ltd.
+ *
+ * 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-permission-switch.h"
+
+struct _GsPermissionSwitch
+{
+       GtkSwitch        parent_instance;
+
+       GsPermission    *permission;
+};
+
+G_DEFINE_TYPE (GsPermissionSwitch, gs_permission_switch, GTK_TYPE_SWITCH)
+
+enum {
+       SIGNAL_CHANGED,
+       SIGNAL_LAST
+};
+
+static guint signals [SIGNAL_LAST] = { 0 };
+
+GsPermission *
+gs_permission_switch_get_permission (GsPermissionSwitch *sw)
+{
+       g_return_val_if_fail (GS_IS_PERMISSION_SWITCH (sw), NULL);
+       return sw->permission;
+}
+
+static void
+active_changed_cb (GsPermissionSwitch *sw)
+{
+       g_signal_emit (sw, signals[SIGNAL_CHANGED], 0,
+                      gtk_switch_get_active (GTK_SWITCH (sw)));
+}
+
+static void
+gs_permission_switch_dispose (GObject *object)
+{
+       GsPermissionSwitch *sw = GS_PERMISSION_SWITCH (object);
+
+       g_clear_object (&sw->permission);
+
+       G_OBJECT_CLASS (gs_permission_switch_parent_class)->dispose (object);
+}
+
+static void
+gs_permission_switch_class_init (GsPermissionSwitchClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->dispose = gs_permission_switch_dispose;
+
+       signals [SIGNAL_CHANGED] =
+               g_signal_new ("changed",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             0,
+                             NULL, NULL, g_cclosure_marshal_generic,
+                             G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+static void
+gs_permission_switch_init (GsPermissionSwitch *sw)
+{
+}
+
+GsPermissionSwitch *
+gs_permission_switch_new (GsPermission *permission)
+{
+       GsPermissionSwitch *sw;
+
+       sw = g_object_new (GS_TYPE_PERMISSION_SWITCH, NULL);
+       sw->permission = g_object_ref (permission);
+       gtk_switch_set_active (GTK_SWITCH (sw), gs_permission_get_enabled (permission));
+       g_signal_connect (sw, "notify::active", G_CALLBACK (active_changed_cb), NULL);
+
+       return sw;
+}
diff --git a/src/gs-permission-switch.h b/src/gs-permission-switch.h
new file mode 100644
index 0000000..9c1e7d6
--- /dev/null
+++ b/src/gs-permission-switch.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2017 Canonical Ltd.
+ *
+ * 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_PERMISSION_SWITCH_H
+#define GS_PERMISSION_SWITCH_H
+
+#include <gtk/gtk.h>
+
+#include "gnome-software-private.h"
+
+G_BEGIN_DECLS
+
+#define GS_TYPE_PERMISSION_SWITCH (gs_permission_switch_get_type ())
+
+G_DECLARE_FINAL_TYPE (GsPermissionSwitch, gs_permission_switch, GS, PERMISSION_SWITCH, GtkSwitch)
+
+GsPermissionSwitch *gs_permission_switch_new (GsPermission *permission);
+
+GsPermission *gs_permission_switch_get_permission (GsPermissionSwitch *sw);
+
+G_END_DECLS
+
+#endif /* GS_PERMISSION_SWITCH_H */
diff --git a/src/meson.build b/src/meson.build
index 267880c..ca2e551 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -44,6 +44,7 @@ gnome_software_sources = [
   'gs-overview-page.c',
   'gs-page.c',
   'gs-permission-dialog.c',
+  'gs-permission-switch.c',
   'gs-popular-tile.c',
   'gs-progress-button.c',
   'gs-removal-dialog.c',


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