[gnome-software/wip/rancell/permissions] Connect permission changes through to plugins
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/rancell/permissions] Connect permission changes through to plugins
- Date: Tue, 15 Aug 2017 03:53:09 +0000 (UTC)
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]