[network-manager-applet/polkit1] editor: re-add UI authorization/permissions hints
- From: Dan Williams <dcbw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [network-manager-applet/polkit1] editor: re-add UI authorization/permissions hints
- Date: Tue, 25 Aug 2009 16:15:56 +0000 (UTC)
commit d1707fb188ac50933dae966826423b1675a557de
Author: Dan Williams <dcbw redhat com>
Date: Tue Aug 25 11:12:30 2009 -0500
editor: re-add UI authorization/permissions hints
polkit 0.92 and later got rid of the GtkAction subclass that
provided these hints through button sensitivity and icon changes.
Roll our own so that the user knows what they can and cannot do
before clicking on a button that may well just deny their action
if they aren't authorized.
src/connection-editor/Makefile.am | 4 +-
src/connection-editor/ce-polkit-button.c | 260 +++++++++++++++++
src/connection-editor/ce-polkit-button.h | 69 +++++
src/connection-editor/nm-connection-editor.c | 331 +++++++++-------------
src/connection-editor/nm-connection-editor.glade | 13 +-
src/connection-editor/nm-connection-editor.h | 8 +-
src/connection-editor/nm-connection-list.c | 217 ++------------
src/connection-editor/nm-connection-list.h | 4 -
8 files changed, 502 insertions(+), 404 deletions(-)
---
diff --git a/src/connection-editor/Makefile.am b/src/connection-editor/Makefile.am
index 1e503f7..b5af0b0 100644
--- a/src/connection-editor/Makefile.am
+++ b/src/connection-editor/Makefile.am
@@ -51,7 +51,9 @@ nm_connection_editor_SOURCES = \
ip6-routes-dialog.h \
ip6-routes-dialog.c \
ppp-auth-methods-dialog.c \
- ppp-auth-methods-dialog.h
+ ppp-auth-methods-dialog.h \
+ ce-polkit-button.c \
+ ce-polkit-button.h
nm-connection-editor-service-glue.h: $(top_srcdir)/src/connection-editor/nm-connection-editor-service.xml
dbus-binding-tool --prefix=nm_connection_editor_service --mode=glib-server --output=$@ $<
diff --git a/src/connection-editor/ce-polkit-button.c b/src/connection-editor/ce-polkit-button.c
new file mode 100644
index 0000000..dc2d2a5
--- /dev/null
+++ b/src/connection-editor/ce-polkit-button.c
@@ -0,0 +1,260 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * 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.
+ *
+ * (C) Copyright 2009 Red Hat, Inc.
+ */
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "ce-polkit-button.h"
+
+G_DEFINE_TYPE (CEPolkitButton, ce_polkit_button, GTK_TYPE_BUTTON)
+
+#define CE_POLKIT_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_POLKIT_BUTTON, CEPolkitButtonPrivate))
+
+typedef struct {
+ char *label;
+ char *tooltip;
+ char *auth_label;
+ char *auth_tooltip;
+ gboolean master_sensitive;
+
+ GtkWidget *stock;
+ GtkWidget *auth;
+
+ NMRemoteSettingsSystem *settings;
+ NMSettingsSystemPermissions permission;
+ gboolean use_polkit;
+ /* authorized = TRUE if either explicitly authorized or if the action
+ * could be performed if the user successfully authenticated to gain the
+ * authorization.
+ */
+ gboolean authorized;
+
+ guint check_id;
+} CEPolkitButtonPrivate;
+
+enum {
+ ACTIONABLE,
+ AUTHORIZED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+update_button (CEPolkitButton *self, gboolean actionable)
+{
+ CEPolkitButtonPrivate *priv = CE_POLKIT_BUTTON_GET_PRIVATE (self);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (self), actionable);
+
+ if (priv->use_polkit && priv->authorized) {
+ gtk_button_set_label (GTK_BUTTON (self), priv->auth_label);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), priv->auth_tooltip);
+ gtk_button_set_image (GTK_BUTTON (self), priv->auth);
+ } else {
+ gtk_button_set_label (GTK_BUTTON (self), priv->label);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self), priv->tooltip);
+ gtk_button_set_image (GTK_BUTTON (self), priv->stock);
+ }
+}
+
+static void
+update_and_emit (CEPolkitButton *self, gboolean old_actionable)
+{
+ gboolean new_actionable;
+
+ new_actionable = ce_polkit_button_get_actionable (self);
+ update_button (self, new_actionable);
+ if (new_actionable != old_actionable)
+ g_signal_emit (self, signals[ACTIONABLE], 0, new_actionable);
+}
+
+void
+ce_polkit_button_set_use_polkit (CEPolkitButton *self, gboolean use_polkit)
+{
+ CEPolkitButtonPrivate *priv = CE_POLKIT_BUTTON_GET_PRIVATE (self);
+ gboolean old_actionable;
+
+ old_actionable = ce_polkit_button_get_actionable (self);
+ priv->use_polkit = use_polkit;
+ update_and_emit (self, old_actionable);
+}
+
+void
+ce_polkit_button_set_master_sensitive (CEPolkitButton *self, gboolean sensitive)
+{
+ CEPolkitButtonPrivate *priv = CE_POLKIT_BUTTON_GET_PRIVATE (self);
+ gboolean old_actionable;
+
+ old_actionable = ce_polkit_button_get_actionable (self);
+ priv->master_sensitive = sensitive;
+ update_and_emit (self, old_actionable);
+}
+
+gboolean
+ce_polkit_button_get_actionable (CEPolkitButton *self)
+{
+ CEPolkitButtonPrivate *priv = CE_POLKIT_BUTTON_GET_PRIVATE (self);
+
+ if (!priv->master_sensitive)
+ return FALSE;
+
+ /* If polkit is in-use, the button is only actionable if the operation is
+ * authorized or able to be authorized via user authentication. If polkit
+ * isn't in-use, the button will always be actionable unless insensitive.
+ */
+ return priv->use_polkit ? priv->authorized : TRUE;
+}
+
+gboolean
+ce_polkit_button_get_authorized (CEPolkitButton *self)
+{
+ return CE_POLKIT_BUTTON_GET_PRIVATE (self)->authorized;
+}
+
+static void
+get_permissions_cb (NMSettingsSystemInterface *settings,
+ NMSettingsSystemPermissions permissions,
+ GError *error,
+ gpointer user_data)
+{
+ CEPolkitButton *self = CE_POLKIT_BUTTON (user_data);
+ CEPolkitButtonPrivate *priv = CE_POLKIT_BUTTON_GET_PRIVATE (self);
+ gboolean old_actionable, old_authorized;
+
+ old_actionable = ce_polkit_button_get_actionable (self);
+ old_authorized = priv->authorized;
+
+ priv->authorized = (permissions & priv->permission);
+ if (priv->use_polkit)
+ update_and_emit (self, old_actionable);
+
+ if (priv->authorized != old_authorized)
+ g_signal_emit (self, signals[AUTHORIZED], 0, priv->authorized);
+}
+
+static void
+check_permissions_cb (NMRemoteSettingsSystem *settings, CEPolkitButton *self)
+{
+ /* recheck permissions */
+ nm_settings_system_interface_get_permissions (NM_SETTINGS_SYSTEM_INTERFACE (settings),
+ get_permissions_cb,
+ self);
+}
+
+GtkWidget *
+ce_polkit_button_new (const char *label,
+ const char *tooltip,
+ const char *auth_label,
+ const char *auth_tooltip,
+ const char *stock_icon,
+ NMRemoteSettingsSystem *settings,
+ NMSettingsSystemPermissions permission)
+{
+ GObject *object;
+ CEPolkitButtonPrivate *priv;
+
+ object = g_object_new (CE_TYPE_POLKIT_BUTTON, NULL);
+ if (!object)
+ return NULL;
+
+ priv = CE_POLKIT_BUTTON_GET_PRIVATE (object);
+
+ priv->label = g_strdup (label);
+ priv->tooltip = g_strdup (tooltip);
+ priv->auth_label = g_strdup (auth_label);
+ priv->auth_tooltip = g_strdup (auth_tooltip);
+ priv->permission = permission;
+ priv->use_polkit = FALSE;
+
+ priv->settings = g_object_ref (settings);
+ priv->check_id = g_signal_connect (settings,
+ NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS,
+ G_CALLBACK (check_permissions_cb),
+ object);
+
+ priv->stock = gtk_image_new_from_stock (stock_icon, GTK_ICON_SIZE_BUTTON);
+ g_object_ref_sink (priv->stock);
+ priv->auth = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_BUTTON);
+ g_object_ref_sink (priv->auth);
+
+ update_button (CE_POLKIT_BUTTON (object),
+ ce_polkit_button_get_actionable (CE_POLKIT_BUTTON (object)));
+
+ check_permissions_cb (settings, CE_POLKIT_BUTTON (object));
+
+ return GTK_WIDGET (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ CEPolkitButtonPrivate *priv = CE_POLKIT_BUTTON_GET_PRIVATE (object);
+
+ g_free (priv->label);
+ g_free (priv->auth_label);
+ g_free (priv->tooltip);
+ g_free (priv->auth_tooltip);
+
+ if (priv->check_id)
+ g_signal_handler_disconnect (priv->settings, priv->check_id);
+
+ g_object_unref (priv->settings);
+ g_object_unref (priv->auth);
+ g_object_unref (priv->stock);
+
+ G_OBJECT_CLASS (ce_polkit_button_parent_class)->finalize (object);
+}
+
+static void
+ce_polkit_button_init (CEPolkitButton *self)
+{
+}
+
+static void
+ce_polkit_button_class_init (CEPolkitButtonClass *pb_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (pb_class);
+
+ g_type_class_add_private (object_class, sizeof (CEPolkitButtonPrivate));
+
+ object_class->finalize = finalize;
+
+ signals[ACTIONABLE] = g_signal_new ("actionable",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CEPolkitButtonClass, actionable),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ signals[AUTHORIZED] = g_signal_new ("authorized",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CEPolkitButtonClass, authorized),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
diff --git a/src/connection-editor/ce-polkit-button.h b/src/connection-editor/ce-polkit-button.h
new file mode 100644
index 0000000..bb31bbc
--- /dev/null
+++ b/src/connection-editor/ce-polkit-button.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Connection editor -- Connection editor for NetworkManager
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * 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.
+ *
+ * (C) Copyright 2009 Red Hat, Inc.
+ */
+
+#ifndef __CE_POLKIT_BUTTON_H__
+#define __CE_POLKIT_BUTTON_H__
+
+#include <gtk/gtk.h>
+
+#include "nm-remote-settings-system.h"
+
+#define CE_TYPE_POLKIT_BUTTON (ce_polkit_button_get_type ())
+#define CE_POLKIT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_POLKIT_BUTTON, CEPolkitButton))
+#define CE_POKLIT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_POLKIT_BUTTON, CEPolkitButtonClass))
+#define CE_IS_POLKIT_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_POLKIT_BUTTON))
+#define CE_IS_POLKIT_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CE_TYPE_POLKIT_BUTTON))
+#define CE_POLKIT_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_POLKIT_BUTTON, CEPolkitButtonClass))
+
+typedef struct {
+ GtkButton parent;
+} CEPolkitButton;
+
+typedef struct {
+ GtkButtonClass parent;
+
+ /* Signals */
+ void (*actionable) (CEPolkitButton *self, gboolean actionable);
+
+ void (*authorized) (CEPolkitButton *self, gboolean authorized);
+} CEPolkitButtonClass;
+
+GType ce_polkit_button_get_type (void);
+
+GtkWidget *ce_polkit_button_new (const char *label,
+ const char *tooltip,
+ const char *auth_label,
+ const char *auth_tooltip,
+ const char *stock_icon,
+ NMRemoteSettingsSystem *settings,
+ NMSettingsSystemPermissions permission);
+
+void ce_polkit_button_set_use_polkit (CEPolkitButton *button, gboolean use_polkit);
+
+void ce_polkit_button_set_master_sensitive (CEPolkitButton *button, gboolean sensitive);
+
+gboolean ce_polkit_button_get_actionable (CEPolkitButton *button);
+
+gboolean ce_polkit_button_get_authorized (CEPolkitButton *button);
+
+#endif /* __CE_POLKIT_BUTTON_H__ */
+
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 3f5d3c5..b647b58 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -69,6 +69,7 @@
#include "page-mobile.h"
#include "page-ppp.h"
#include "page-vpn.h"
+#include "ce-polkit-button.h"
G_DEFINE_TYPE (NMConnectionEditor, nm_connection_editor, G_TYPE_OBJECT)
@@ -136,80 +137,40 @@ ui_to_setting (NMConnectionEditor *editor)
}
static void
-connection_editor_validate (NMConnectionEditor *editor)
+update_sensitivity (NMConnectionEditor *editor)
{
- gboolean valid = FALSE;
+ NMSettingConnection *s_con;
+ gboolean actionable = FALSE, authorized = FALSE, sensitive = FALSE;
+ GtkWidget *widget;
GSList *iter;
- if (!editor->initialized)
- goto done;
-
- if (!ui_to_setting (editor))
- goto done;
-
- for (iter = editor->pages; iter; iter = g_slist_next (iter)) {
- GError *error = NULL;
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (editor->connection, NM_TYPE_SETTING_CONNECTION));
- if (!ce_page_validate (CE_PAGE (iter->data), editor->connection, &error)) {
- /* FIXME: use the error to indicate which UI widgets are invalid */
- if (error) {
- g_warning ("Invalid setting %s: %s", CE_PAGE (iter->data)->title, error->message);
- g_error_free (error);
- } else
- g_warning ("Invalid setting %s", CE_PAGE (iter->data)->title);
+ /* Can't modify read-only connections; can't modify anything before the
+ * editor is initialized either.
+ */
+ if (!nm_setting_connection_get_read_only (s_con) && editor->initialized) {
+ if (editor->system_settings_can_modify) {
+ actionable = ce_polkit_button_get_actionable (CE_POLKIT_BUTTON (editor->ok_button));
+ authorized = actionable && ce_polkit_button_get_authorized (CE_POLKIT_BUTTON (editor->ok_button));
+ }
- goto done;
+ if (editor->orig_scope == NM_CONNECTION_SCOPE_SYSTEM) {
+ /* If the user cannot ever be authorized to change system connections, and
+ * the connection is a system connection, we desensitize the entire dialog.
+ */
+ sensitive = actionable;
+ } else {
+ /* Otherwise, if the connection is originally a user-connection,
+ * then everything is sensitive except possible the system checkbutton,
+ * which will be insensitive if the user has no possibility of
+ * authorizing.
+ */
+ sensitive = TRUE;
}
}
- valid = TRUE;
-
-done:
- gtk_widget_set_sensitive (editor->system_checkbutton, valid);
- gtk_widget_set_sensitive (editor->ok_button, valid);
-#if 0
- g_object_set (editor->system_gnome_action, "master-sensitive", valid, NULL);
-#endif
-}
-
-static void
-system_checkbutton_toggled_cb (GtkWidget *widget, NMConnectionEditor *editor)
-{
- gboolean req_privs = FALSE;
- NMSettingConnection *s_con;
-
- /* If the connection was originally a system connection, obviously
- * privileges are required to change it. If it was originally a user
- * connection, but the user requests that it be changed to a system
- * connection, privileges are also required.
- */
-
- if (editor->orig_scope == NM_CONNECTION_SCOPE_USER) {
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
- req_privs = TRUE;
- } else
- req_privs = TRUE;
-#if 0
- if (req_privs)
- g_object_set (editor->system_gnome_action, "polkit-action", editor->system_action, NULL);
- else
- g_object_set (editor->system_gnome_action, "polkit-action", NULL, NULL);
-#endif
-
- /* Can't ever modify read-only connections */
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (editor->connection, NM_TYPE_SETTING_CONNECTION));
- if (nm_setting_connection_get_read_only (s_con))
- gtk_widget_set_sensitive (editor->ok_button, FALSE);
-
- if (editor->initialized)
- connection_editor_validate (editor);
-}
-
-static void
-set_editor_sensitivity (NMConnectionEditor *editor, gboolean sensitive)
-{
- GtkWidget *widget;
- GSList *iter;
+ gtk_widget_set_sensitive (GTK_WIDGET (editor->system_checkbutton), authorized);
/* Cancel button is always sensitive */
gtk_widget_set_sensitive (GTK_WIDGET (editor->cancel_button), TRUE);
@@ -226,76 +187,84 @@ set_editor_sensitivity (NMConnectionEditor *editor, gboolean sensitive)
widget = glade_xml_get_widget (editor->xml, "connection_name");
gtk_widget_set_sensitive (widget, sensitive);
- if (editor->system_settings_can_modify)
- gtk_widget_set_sensitive (GTK_WIDGET (editor->system_checkbutton), sensitive);
-
for (iter = editor->pages; iter; iter = g_slist_next (iter)) {
widget = ce_page_get_page (CE_PAGE (iter->data));
gtk_widget_set_sensitive (widget, sensitive);
}
}
-typedef guint32 PolKitResult;
-#define POLKIT_RESULT_UNKNOWN 0
-
static void
-update_sensitivity (NMConnectionEditor *editor, PolKitResult pk_result)
+connection_editor_validate (NMConnectionEditor *editor)
{
NMSettingConnection *s_con;
- gboolean denied = FALSE;
+ gboolean valid = FALSE;
+ GSList *iter;
+
+ if (!editor->initialized)
+ goto done;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (editor->connection, NM_TYPE_SETTING_CONNECTION));
- /* Can't ever modify read-only connections */
- if (nm_setting_connection_get_read_only (s_con)) {
- set_editor_sensitivity (editor, FALSE);
- return;
- }
+ g_assert (s_con);
+ if (nm_setting_connection_get_read_only (s_con))
+ goto done;
+
+ if (!ui_to_setting (editor))
+ goto done;
+
+ for (iter = editor->pages; iter; iter = g_slist_next (iter)) {
+ GError *error = NULL;
-#if 0
- if (pk_result == POLKIT_RESULT_UNKNOWN)
- pk_result = polkit_gnome_action_get_polkit_result (editor->system_gnome_action);
-
- if (pk_result == POLKIT_RESULT_NO || pk_result == POLKIT_RESULT_UNKNOWN)
- denied = TRUE;
-#endif
-
- switch (editor->orig_scope) {
- case NM_CONNECTION_SCOPE_SYSTEM:
- /* If the user cannot ever be authorized to change system connections, and
- * the connection is a system connection, we desensitize the entire dialog.
- */
- set_editor_sensitivity (editor, !denied);
- break;
- default:
- /* If the user cannot ever be authorized to change system connections, and
- * the connection is a user connection, we desensitize system_checkbutton.
- */
- set_editor_sensitivity (editor, TRUE);
- if (denied)
- gtk_widget_set_sensitive (GTK_WIDGET (editor->system_checkbutton), FALSE);
- break;
+ if (!ce_page_validate (CE_PAGE (iter->data), editor->connection, &error)) {
+ /* FIXME: use the error to indicate which UI widgets are invalid */
+ if (error) {
+ g_warning ("Invalid setting %s: %s", CE_PAGE (iter->data)->title, error->message);
+ g_error_free (error);
+ } else
+ g_warning ("Invalid setting %s", CE_PAGE (iter->data)->title);
+
+ goto done;
+ }
}
+ valid = TRUE;
+
+done:
+ ce_polkit_button_set_master_sensitive (CE_POLKIT_BUTTON (editor->ok_button), valid);
+ update_sensitivity (editor);
+}
+
+static void
+ok_button_actionable_cb (GtkWidget *button,
+ gboolean actionable,
+ NMConnectionEditor *editor)
+{
+ connection_editor_validate (editor);
+}
+
+static void
+can_modify_changed_cb (NMRemoteSettingsSystem *settings,
+ GParamSpec *pspec,
+ NMConnectionEditor *editor)
+{
+ connection_editor_validate (editor);
}
-#if 0
static void
-system_pk_result_changed_cb (PolKitGnomeAction *gnome_action,
- PolKitResult result,
- NMConnectionEditor *editor)
+system_checkbutton_toggled_cb (GtkWidget *widget, NMConnectionEditor *editor)
{
- update_sensitivity (editor, result);
+ /* Whether the Apply button uses system settings permissions as part of
+ * it's sensitivity determination depends on whether the system checkbutton
+ * is toggled or not.
+ */
+ ce_polkit_button_set_use_polkit (CE_POLKIT_BUTTON (editor->ok_button),
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
+
+ connection_editor_validate (editor);
}
-#endif
static void
nm_connection_editor_init (NMConnectionEditor *editor)
{
GtkWidget *dialog;
-#if 0
- GtkWidget *hbox;
- const char *auth_label, *auth_tooltip;
- const char *label, *tooltip;
-#endif
/* Yes, we mean applet.glade, not nm-connection-editor.glade. The wireless security bits
are taken from applet.glade. */
@@ -327,59 +296,6 @@ nm_connection_editor_init (NMConnectionEditor *editor)
editor->window = glade_xml_get_widget (editor->xml, "nm-connection-editor");
editor->cancel_button = glade_xml_get_widget (editor->xml, "cancel_button");
editor->system_checkbutton = glade_xml_get_widget (editor->xml, "system_checkbutton");
- editor->ok_button = glade_xml_get_widget (editor->xml, "apply_button");
-
-#if 0
- editor->system_action = polkit_action_new ();
- polkit_action_set_action_id (editor->system_action, "org.freedesktop.network-manager-settings.system.modify");
-
- editor->system_gnome_action = polkit_gnome_action_new ("system");
-
- auth_label = _("Apply...");
- auth_tooltip = _("Authenticate to save this connection for all users of this machine.");
- label = _("Apply");
- tooltip = _("Save this connection for all users of this machine.");
- g_object_set (editor->system_gnome_action,
- "polkit-action", NULL,
-
- "self-blocked-visible", TRUE,
- "self-blocked-sensitive", FALSE,
- "self-blocked-short-label", label,
- "self-blocked-label", label,
- "self-blocked-tooltip", tooltip,
- "self-blocked-icon-name", GTK_STOCK_APPLY,
-
- "no-visible", TRUE,
- "no-sensitive", FALSE,
- "no-short-label", label,
- "no-label", label,
- "no-tooltip", tooltip,
- "no-icon-name", GTK_STOCK_APPLY,
-
- "auth-visible", TRUE,
- "auth-sensitive", TRUE,
- "auth-short-label", auth_label,
- "auth-label", auth_label,
- "auth-tooltip", auth_tooltip,
- "auth-icon-name", GTK_STOCK_DIALOG_AUTHENTICATION,
-
- "yes-visible", TRUE,
- "yes-sensitive", TRUE,
- "yes-short-label", label,
- "yes-label", label,
- "yes-tooltip", tooltip,
- "yes-icon-name", GTK_STOCK_APPLY,
-
- "master-visible", TRUE,
- "master-sensitive", TRUE,
- NULL);
- g_signal_connect (editor->system_gnome_action, "polkit-result-changed",
- G_CALLBACK (system_pk_result_changed_cb), editor);
-
- editor->ok_button = polkit_gnome_action_create_button (editor->system_gnome_action);
- hbox = glade_xml_get_widget (editor->xml, "action_area_hbox");
- gtk_box_pack_end (GTK_BOX (hbox), editor->ok_button, TRUE, TRUE, 0);
-#endif
}
static void
@@ -392,28 +308,17 @@ dispose (GObject *object)
editor->pages = NULL;
if (editor->connection) {
- g_object_unref (editor->connection);
- editor->connection = NULL;
- }
- if (editor->window) {
- gtk_widget_destroy (editor->window);
- editor->window = NULL;
- }
- if (editor->xml) {
- g_object_unref (editor->xml);
- editor->xml = NULL;
- }
-
-#if 0
- if (editor->system_action) {
- polkit_action_unref (editor->system_action);
- editor->system_action = NULL;
- }
- if (editor->system_gnome_action) {
- g_object_unref (editor->system_gnome_action);
- editor->system_gnome_action = NULL;
- }
-#endif
+ g_object_unref (editor->connection);
+ editor->connection = NULL;
+ }
+ if (editor->window) {
+ gtk_widget_destroy (editor->window);
+ editor->window = NULL;
+ }
+ if (editor->xml) {
+ g_object_unref (editor->xml);
+ editor->xml = NULL;
+ }
G_OBJECT_CLASS (nm_connection_editor_parent_class)->dispose (object);
}
@@ -439,10 +344,12 @@ nm_connection_editor_class_init (NMConnectionEditorClass *klass)
NMConnectionEditor *
nm_connection_editor_new (NMConnection *connection,
- gboolean system_settings_can_modify,
+ NMRemoteSettingsSystem *settings,
GError **error)
{
NMConnectionEditor *editor;
+ GtkWidget *hbox;
+ gboolean sensitive = TRUE, use_polkit = FALSE;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
@@ -452,7 +359,40 @@ nm_connection_editor_new (NMConnection *connection,
return NULL;
}
- editor->system_settings_can_modify = system_settings_can_modify;
+ g_object_get (settings,
+ NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY,
+ &editor->system_settings_can_modify,
+ NULL);
+ g_signal_connect (settings,
+ "notify::" NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY,
+ G_CALLBACK (can_modify_changed_cb),
+ editor);
+
+ /* If this is a system connection that we can't ever modify,
+ * set the editor's Apply button always insensitive.
+ */
+ if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) {
+ sensitive = editor->system_settings_can_modify;
+ use_polkit = TRUE;
+ }
+
+ editor->ok_button = ce_polkit_button_new (_("Apply"),
+ _("Save this connection for all users of this machine."),
+ _("Apply..."),
+ _("Authenticate to save this connection for all users of this machine."),
+ GTK_STOCK_APPLY,
+ settings,
+ NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY);
+ ce_polkit_button_set_use_polkit (CE_POLKIT_BUTTON (editor->ok_button), use_polkit);
+
+ g_signal_connect (editor->ok_button, "actionable",
+ G_CALLBACK (ok_button_actionable_cb), editor);
+ g_signal_connect (editor->ok_button, "authorized",
+ G_CALLBACK (ok_button_actionable_cb), editor);
+ hbox = glade_xml_get_widget (editor->xml, "action_area_hbox");
+ gtk_box_pack_end (GTK_BOX (hbox), editor->ok_button, TRUE, TRUE, 0);
+ gtk_widget_show_all (editor->ok_button);
+
if (!nm_connection_editor_set_connection (editor, connection, error)) {
g_object_unref (editor);
return NULL;
@@ -493,14 +433,12 @@ populate_connection_ui (NMConnectionEditor *editor)
g_signal_connect_swapped (name, "changed", G_CALLBACK (connection_editor_validate), editor);
g_signal_connect_swapped (autoconnect, "toggled", G_CALLBACK (connection_editor_validate), editor);
- if (!editor->system_settings_can_modify)
- gtk_widget_set_sensitive (editor->system_checkbutton, FALSE);
g_signal_connect (editor->system_checkbutton, "toggled", G_CALLBACK (system_checkbutton_toggled_cb), editor);
if (editor->orig_scope == NM_CONNECTION_SCOPE_SYSTEM)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->system_checkbutton), TRUE);
- update_sensitivity (editor, POLKIT_RESULT_UNKNOWN);
+ connection_editor_validate (editor);
}
static void
@@ -526,16 +464,15 @@ recheck_initialization (NMConnectionEditor *editor)
/* Check if all pages are initialized; if not, desensitize the editor */
for (iter = editor->pages; iter; iter = g_slist_next (iter)) {
if (!ce_page_get_initialized (CE_PAGE (iter->data))) {
- set_editor_sensitivity (editor, FALSE);
+ update_sensitivity (editor);
return;
}
}
- populate_connection_ui (editor);
- update_sensitivity (editor, POLKIT_RESULT_UNKNOWN);
-
editor->initialized = TRUE;
+ populate_connection_ui (editor);
+
/* Validate the connection from an idle handler to ensure that stuff like
* GtkFileChoosers have had a chance to asynchronously find their files.
*/
diff --git a/src/connection-editor/nm-connection-editor.glade b/src/connection-editor/nm-connection-editor.glade
index b634693..5988d70 100644
--- a/src/connection-editor/nm-connection-editor.glade
+++ b/src/connection-editor/nm-connection-editor.glade
@@ -599,18 +599,7 @@
</packing>
</child>
<child>
- <widget class="GtkButton" id="apply_button">
- <property name="label">gtk-apply</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
+ <placeholder/>
</child>
</widget>
<packing>
diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h
index 9bab69d..e5bce34 100644
--- a/src/connection-editor/nm-connection-editor.h
+++ b/src/connection-editor/nm-connection-editor.h
@@ -28,6 +28,8 @@
#include <glib-object.h>
#include <glade/glade-xml.h>
+#include "nm-remote-settings-system.h"
+
#define NM_TYPE_CONNECTION_EDITOR (nm_connection_editor_get_type ())
#define NM_IS_CONNECTION_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_EDITOR))
#define NM_CONNECTION_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_EDITOR, NMConnectionEditor))
@@ -40,10 +42,6 @@ typedef struct {
gboolean initialized;
NMConnectionScope orig_scope;
-#if 0
- PolKitAction *system_action;
- PolKitGnomeAction *system_gnome_action;
-#endif
GtkWidget *system_checkbutton;
gboolean system_settings_can_modify;
@@ -64,7 +62,7 @@ typedef struct {
GType nm_connection_editor_get_type (void);
NMConnectionEditor *nm_connection_editor_new (NMConnection *connection,
- gboolean system_settings_can_modify,
+ NMRemoteSettingsSystem *settings,
GError **error);
void nm_connection_editor_present (NMConnectionEditor *editor);
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index ec4c197..1e2b971 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -57,6 +57,7 @@
#include "gconf-helpers.h"
#include "utils.h"
#include "vpn-helpers.h"
+#include "ce-polkit-button.h"
G_DEFINE_TYPE (NMConnectionList, nm_connection_list, G_TYPE_OBJECT)
@@ -607,7 +608,6 @@ really_add_connection (NMConnection *connection,
NMConnectionEditor *editor;
GError *editor_error = NULL;
const char *message = _("The connection editor dialog could not be initialized due to an unknown error.");
- gboolean can_modify = FALSE;
g_return_if_fail (info != NULL);
@@ -622,12 +622,7 @@ really_add_connection (NMConnection *connection,
return;
}
- g_object_get (G_OBJECT (info->list->system_settings),
- NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY,
- &can_modify,
- NULL);
-
- editor = nm_connection_editor_new (connection, can_modify, &error);
+ editor = nm_connection_editor_new (connection, info->list->system_settings, &error);
if (!editor) {
error_dialog (info->list_window,
_("Could not edit new connection"),
@@ -750,7 +745,6 @@ do_edit (ActionInfo *info)
EditInfo *edit_info;
GError *error = NULL;
const char *message = _("The connection editor dialog could not be initialized due to an unknown error.");
- gboolean can_modify = FALSE;
connection = get_active_connection (info->treeview);
g_return_if_fail (connection != NULL);
@@ -762,12 +756,8 @@ do_edit (ActionInfo *info)
return;
}
- g_object_get (G_OBJECT (info->list->system_settings),
- NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY, &can_modify,
- NULL);
-
duplicated = nm_gconf_connection_duplicate (NM_CONNECTION (connection));
- editor = nm_connection_editor_new (duplicated, can_modify, &error);
+ editor = nm_connection_editor_new (duplicated, info->list->system_settings, &error);
g_object_unref (duplicated);
if (!editor) {
@@ -842,43 +832,6 @@ delete_clicked (GtkButton *button, gpointer user_data)
delete_connection (info->list, connection, delete_result_cb, GTK_WINDOW (info->list->dialog));
}
-typedef guint32 PolKitResult;
-#define POLKIT_RESULT_UNKNOWN 0
-
-static gboolean
-check_sensitivity (ActionInfo *info, PolKitResult pk_result)
-{
- gboolean sensitive = TRUE;
- NMSettingsConnectionInterface *connection = NULL;
-
- connection = get_active_connection (info->treeview);
- if (!connection)
- return FALSE;
-
- if (nm_connection_get_scope (NM_CONNECTION (connection)) != NM_CONNECTION_SCOPE_SYSTEM)
- return TRUE;
-
-#if 0
- if (pk_result == POLKIT_RESULT_UNKNOWN)
- pk_result = polkit_gnome_action_get_polkit_result (info->gnome_action);
-
- if (pk_result == POLKIT_RESULT_NO || pk_result == POLKIT_RESULT_UNKNOWN)
- sensitive = FALSE;
-#endif
-
- return sensitive;
-}
-
-#if 0
-static void
-system_pk_result_changed_cb (PolKitGnomeAction *gnome_action,
- PolKitResult result,
- ActionInfo *info)
-{
- gtk_widget_set_sensitive (info->button, check_sensitivity (info, result));
-}
-#endif
-
static void
pk_button_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
{
@@ -887,8 +840,9 @@ pk_button_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
GtkTreeModel *model;
NMSettingsConnectionInterface *connection;
NMSettingConnection *s_con;
- gboolean can_do_action = FALSE;
- gboolean req_privs = FALSE;
+ NMConnectionScope scope;
+ gboolean sensitive = FALSE;
+ gboolean use_polkit = FALSE;
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
goto done;
@@ -897,24 +851,18 @@ pk_button_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
if (!connection)
goto done;
+ scope = nm_connection_get_scope (NM_CONNECTION (connection));
+ use_polkit = (scope == NM_CONNECTION_SCOPE_SYSTEM);
+
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection),
NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
- if (nm_connection_get_scope (NM_CONNECTION (connection)) != NM_CONNECTION_SCOPE_SYSTEM)
- can_do_action = !nm_setting_connection_get_read_only (s_con);
- else {
- if (!nm_setting_connection_get_read_only (s_con))
- can_do_action = check_sensitivity (info, POLKIT_RESULT_UNKNOWN);
- req_privs = TRUE;
- }
+ sensitive = !nm_setting_connection_get_read_only (s_con);
done:
- gtk_widget_set_sensitive (info->button, can_do_action);
-#if 0
- g_object_set (info->gnome_action, "polkit-action", req_privs ? info->action : NULL, NULL);
- g_object_set (info->gnome_action, "master-sensitive", can_do_action, NULL);
-#endif
+ ce_polkit_button_set_use_polkit (CE_POLKIT_BUTTON (info->button), use_polkit);
+ ce_polkit_button_set_master_sensitive (CE_POLKIT_BUTTON (info->button), sensitive);
}
static void
@@ -966,7 +914,6 @@ import_success_cb (NMConnection *connection, gpointer user_data)
char *s;
GError *error = NULL;
const char *message = _("The connection editor dialog could not be initialized due to an unknown error.");
- gboolean can_modify = FALSE;
/* Basic sanity checks of the connection */
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
@@ -1022,12 +969,7 @@ import_success_cb (NMConnection *connection, gpointer user_data)
return;
}
- g_object_get (G_OBJECT (info->list->system_settings),
- NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY,
- &can_modify,
- NULL);
-
- editor = nm_connection_editor_new (connection, can_modify, &error);
+ editor = nm_connection_editor_new (connection, info->list->system_settings, &error);
if (!editor) {
error_dialog (info->list_window,
_("Could not edit imported connection"),
@@ -1067,7 +1009,7 @@ connection_double_clicked_cb (GtkTreeView *tree_view,
{
ActionInfo *info = user_data;
- if (GTK_WIDGET_SENSITIVE (info->button))
+ if (ce_polkit_button_get_actionable (CE_POLKIT_BUTTON (info->button)))
gtk_button_clicked (GTK_BUTTON (info->button));
}
@@ -1080,10 +1022,6 @@ dialog_response_cb (GtkDialog *dialog, guint response, gpointer user_data)
static void
nm_connection_list_init (NMConnectionList *list)
{
-#if 0
- list->system_action = polkit_action_new ();
- polkit_action_set_action_id (list->system_action, "org.freedesktop.network-manager-settings.system.modify");
-#endif
}
static void
@@ -1108,10 +1046,6 @@ dispose (GObject *object)
if (list->unknown_icon)
g_object_unref (list->unknown_icon);
-#if 0
- polkit_action_unref (list->system_action);
-#endif
-
if (list->dialog)
gtk_widget_destroy (list->dialog);
if (list->gui)
@@ -1201,11 +1135,6 @@ static void
action_info_free (ActionInfo *info)
{
g_return_if_fail (info != NULL);
-
-#if 0
- /* gnome_action should have been destroyed when the dialog got destroyed */
- polkit_action_unref (info->action);
-#endif
g_free (info);
}
@@ -1234,11 +1163,6 @@ action_info_set_button (ActionInfo *info,
g_return_if_fail (info != NULL);
info->button = button;
-#if 0
- if (info->gnome_action)
- g_object_unref (info->gnome_action);
- info->gnome_action = gnome_action;
-#endif
}
static void
@@ -1263,74 +1187,6 @@ check_vpn_import_supported (gpointer key, gpointer data, gpointer user_data)
*import_supported = TRUE;
}
-static GtkWidget *
-create_system_action_button (const char *name,
- const char *auth_label,
- const char *auth_tooltip,
- const char *label,
- const char *tooltip,
- const char *stock_icon,
- const char *auth_icon,
-#if 0
- GCallback result_callback,
-#endif
- GtkWidget *hbox,
- gpointer user_data)
-{
- GtkWidget *button;
-#if 0
- PolKitGnomeAction *action;
-
- action = polkit_gnome_action_new (name);
-
- g_object_set (action,
- "polkit-action", NULL,
-
- "self-blocked-visible", TRUE,
- "self-blocked-sensitive", FALSE,
- "self-blocked-short-label", label,
- "self-blocked-label", label,
- "self-blocked-tooltip", tooltip,
- "self-blocked-icon-name", stock_icon,
-
- "no-visible", TRUE,
- "no-sensitive", FALSE,
- "no-short-label", label,
- "no-label", label,
- "no-tooltip", tooltip,
- "no-icon-name", stock_icon,
-
- "auth-visible", TRUE,
- "auth-sensitive", TRUE,
- "auth-short-label", auth_label,
- "auth-label", auth_label,
- "auth-tooltip", auth_tooltip,
- "auth-icon-name", auth_icon,
-
- "yes-visible", TRUE,
- "yes-sensitive", TRUE,
- "yes-short-label", label,
- "yes-label", label,
- "yes-tooltip", tooltip,
- "yes-icon-name", stock_icon,
-
- "master-visible", TRUE,
- "master-sensitive", TRUE,
- NULL);
- g_signal_connect (action, "polkit-result-changed",
- G_CALLBACK (result_callback), user_data);
-
- button = polkit_gnome_action_create_button (action);
-#endif
- button = gtk_button_new_from_stock (stock_icon);
- gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
-
-#if 0
- *out_action = action;
-#endif
- return button;
-}
-
static void
add_connection_buttons (NMConnectionList *self,
const char *prefix,
@@ -1342,9 +1198,6 @@ add_connection_buttons (NMConnectionList *self,
GtkWidget *button, *hbox;
ActionInfo *info;
GtkTreeSelection *selection;
-#if 0
- PolKitGnomeAction *action = NULL;
-#endif
selection = gtk_tree_view_get_selection (treeview);
@@ -1370,18 +1223,15 @@ add_connection_buttons (NMConnectionList *self,
/* Edit */
info = action_info_new (self, treeview, GTK_WINDOW (self->dialog), NULL);
- button = create_system_action_button ("system-edit",
- _("Edit..."),
- _("Authenticate to edit the selected connection."),
- _("Edit"),
- _("Edit the selected connection."),
- GTK_STOCK_EDIT,
- GTK_STOCK_DIALOG_AUTHENTICATION,
-#if 0
- G_CALLBACK (system_pk_result_changed_cb),
-#endif
- hbox,
- info);
+ button = ce_polkit_button_new (_("Edit"),
+ _("Edit the selected connection"),
+ _("Edit..."),
+ _("Authenticate to edit the selected connection"),
+ GTK_STOCK_EDIT,
+ self->system_settings,
+ NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY);
+ gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
action_info_set_button (info, button);
g_signal_connect (button, "clicked", G_CALLBACK (edit_connection_cb), info);
g_signal_connect (treeview, "row-activated", G_CALLBACK (connection_double_clicked_cb), info);
@@ -1390,18 +1240,15 @@ add_connection_buttons (NMConnectionList *self,
/* Delete */
info = action_info_new (self, treeview, GTK_WINDOW (self->dialog), NULL);
- button = create_system_action_button ("system-delete",
- _("Delete..."),
- _("Authenticate to delete the selected connection."),
- _("Delete"),
- _("Delete the selected connection."),
- GTK_STOCK_DELETE,
- GTK_STOCK_DIALOG_AUTHENTICATION,
-#if 0
- G_CALLBACK (system_pk_result_changed_cb),
-#endif
- hbox,
- info);
+ button = ce_polkit_button_new (_("Delete"),
+ _("Delete the selected connection"),
+ _("Delete..."),
+ _("Authenticate to delete the selected connection"),
+ GTK_STOCK_DELETE,
+ self->system_settings,
+ NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY);
+ gtk_box_pack_end (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+
action_info_set_button (info, button);
g_signal_connect (button, "clicked", G_CALLBACK (delete_clicked), info);
g_signal_connect (selection, "changed", G_CALLBACK (pk_button_selection_changed_cb), info);
diff --git a/src/connection-editor/nm-connection-list.h b/src/connection-editor/nm-connection-list.h
index 218087d..c27317c 100644
--- a/src/connection-editor/nm-connection-list.h
+++ b/src/connection-editor/nm-connection-list.h
@@ -49,10 +49,6 @@ typedef struct {
GladeXML *gui;
GtkWidget *dialog;
-#if 0
- PolKitAction *system_action;
-#endif
-
GdkPixbuf *wired_icon;
GdkPixbuf *wireless_icon;
GdkPixbuf *wwan_icon;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]