[network-manager-applet/bond: 1/6] connection-editor: move a bunch of code out of NMConnectionList
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet/bond: 1/6] connection-editor: move a bunch of code out of NMConnectionList
- Date: Mon, 13 Aug 2012 18:30:35 +0000 (UTC)
commit b07c655388d9e78a26ed2b93827938151f36644f
Author: Dan Winship <danw gnome org>
Date: Wed Mar 7 14:23:03 2012 -0500
connection-editor: move a bunch of code out of NMConnectionList
The bond page will need to pull up its own editors, so move some of
the logic out of nm-connection-list.c into nm-connection-editor.c and
new-connection.c, where it's more easily shared.
src/connection-editor/new-connection.c | 114 ++++++-
src/connection-editor/new-connection.h | 17 +-
src/connection-editor/nm-connection-editor.c | 183 +++++++++-
src/connection-editor/nm-connection-editor.h | 17 +-
src/connection-editor/nm-connection-list.c | 471 ++------------------------
src/connection-editor/nm-connection-list.h | 2 -
src/connection-editor/page-vpn.c | 16 +-
7 files changed, 345 insertions(+), 475 deletions(-)
---
diff --git a/src/connection-editor/new-connection.c b/src/connection-editor/new-connection.c
index c8715df..ed50998 100644
--- a/src/connection-editor/new-connection.c
+++ b/src/connection-editor/new-connection.c
@@ -24,6 +24,7 @@
#include "new-connection.h"
#include "nm-connection-list.h"
+#include "nm-connection-editor.h"
#include "page-ethernet.h"
#include "page-wifi.h"
#include "page-mobile.h"
@@ -251,7 +252,7 @@ set_up_connection_type_combo (GtkComboBox *combo,
typedef struct {
GtkWindow *parent_window;
NMRemoteSettings *settings;
- PageNewConnectionResultFunc result_func;
+ NewConnectionResultFunc result_func;
gpointer user_data;
} NewConnectionData;
@@ -262,13 +263,23 @@ new_connection_result (NMConnection *connection,
gpointer user_data)
{
NewConnectionData *ncd = user_data;
- PageNewConnectionResultFunc result_func;
+ NewConnectionResultFunc result_func;
+ GtkWindow *parent_window;
+ const char *default_message = _("The connection editor dialog could not be initialized due to an unknown error.");
result_func = ncd->result_func;
user_data = ncd->user_data;
+ parent_window = ncd->parent_window;
g_slice_free (NewConnectionData, ncd);
- result_func (connection, canceled, error, user_data);
+ if (!connection) {
+ nm_connection_editor_error (parent_window,
+ _("Could not create new connection"),
+ "%s",
+ (error && error->message) ? error->message : default_message);
+ }
+
+ result_func (connection, user_data);
}
void
@@ -276,7 +287,7 @@ new_connection_of_type (GtkWindow *parent_window,
const char *detail,
NMRemoteSettings *settings,
PageNewConnectionFunc new_func,
- PageNewConnectionResultFunc result_func,
+ NewConnectionResultFunc result_func,
gpointer user_data)
{
NewConnectionData *ncd;
@@ -298,7 +309,7 @@ void
new_connection_dialog (GtkWindow *parent_window,
NMRemoteSettings *settings,
NewConnectionTypeFilterFunc type_filter_func,
- PageNewConnectionResultFunc result_func,
+ NewConnectionResultFunc result_func,
gpointer user_data)
{
new_connection_dialog_full (parent_window, settings,
@@ -314,7 +325,7 @@ new_connection_dialog_full (GtkWindow *parent_window,
const char *primary_label,
const char *secondary_label,
NewConnectionTypeFilterFunc type_filter_func,
- PageNewConnectionResultFunc result_func,
+ NewConnectionResultFunc result_func,
gpointer user_data)
{
@@ -377,7 +388,96 @@ new_connection_dialog_full (GtkWindow *parent_window,
if (new_func)
new_connection_of_type (parent_window, vpn_type, settings, new_func, result_func, user_data);
else
- result_func (NULL, TRUE, NULL, user_data);
+ result_func (NULL, user_data);
g_free (vpn_type);
}
+
+typedef struct {
+ GtkWindow *parent_window;
+ NMConnectionEditor *editor;
+ DeleteConnectionResultFunc result_func;
+ gpointer user_data;
+} DeleteInfo;
+
+static void
+delete_cb (NMRemoteConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ DeleteInfo *info = user_data;
+ DeleteConnectionResultFunc result_func;
+
+ if (error) {
+ nm_connection_editor_error (info->parent_window,
+ _("Connection delete failed"),
+ "%s", error->message);
+ }
+
+ if (info->editor) {
+ nm_connection_editor_set_busy (info->editor, FALSE);
+ g_object_unref (info->editor);
+ }
+ if (info->parent_window)
+ g_object_unref (info->parent_window);
+
+ result_func = info->result_func;
+ user_data = info->user_data;
+ g_free (info);
+
+ if (result_func)
+ (*result_func) (connection, error == NULL, user_data);
+}
+
+void
+delete_connection (GtkWindow *parent_window,
+ NMRemoteConnection *connection,
+ DeleteConnectionResultFunc result_func,
+ gpointer user_data)
+{
+ NMConnectionEditor *editor;
+ NMSettingConnection *s_con;
+ GtkWidget *dialog;
+ const char *id;
+ guint result;
+ DeleteInfo *info;
+
+ editor = nm_connection_editor_get (NM_CONNECTION (connection));
+ if (editor && nm_connection_editor_get_busy (editor)) {
+ /* Editor already has an operation in progress, raise it */
+ nm_connection_editor_present (editor);
+ return;
+ }
+
+ s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
+ g_assert (s_con);
+ id = nm_setting_connection_get_id (s_con);
+
+ dialog = gtk_message_dialog_new (parent_window,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE,
+ _("Are you sure you wish to delete the connection %s?"),
+ id);
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_DELETE, GTK_RESPONSE_YES,
+ NULL);
+
+ result = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ if (result != GTK_RESPONSE_YES)
+ return;
+
+ info = g_malloc0 (sizeof (DeleteInfo));
+ info->editor = editor ? g_object_ref (editor) : NULL;
+ info->parent_window = parent_window ? g_object_ref (parent_window) : NULL;
+ info->result_func = result_func;
+ info->user_data = user_data;
+
+ if (editor)
+ nm_connection_editor_set_busy (editor, TRUE);
+
+ nm_remote_connection_delete (connection, delete_cb, info);
+}
diff --git a/src/connection-editor/new-connection.h b/src/connection-editor/new-connection.h
index 0cb4a70..3527352 100644
--- a/src/connection-editor/new-connection.h
+++ b/src/connection-editor/new-connection.h
@@ -34,26 +34,37 @@ ConnectionTypeData *get_connection_type_list (void);
typedef gboolean (*NewConnectionTypeFilterFunc) (GType type,
gpointer user_data);
+typedef void (*NewConnectionResultFunc) (NMConnection *connection,
+ gpointer user_data);
void new_connection_dialog (GtkWindow *parent_window,
NMRemoteSettings *settings,
NewConnectionTypeFilterFunc type_filter_func,
- PageNewConnectionResultFunc result_func,
+ NewConnectionResultFunc result_func,
gpointer user_data);
void new_connection_dialog_full (GtkWindow *parent_window,
NMRemoteSettings *settings,
const char *primary_label,
const char *secondary_label,
NewConnectionTypeFilterFunc type_filter_func,
- PageNewConnectionResultFunc result_func,
+ NewConnectionResultFunc result_func,
gpointer user_data);
void new_connection_of_type (GtkWindow *parent_window,
const char *detail,
NMRemoteSettings *settings,
PageNewConnectionFunc new_func,
- PageNewConnectionResultFunc result_func,
+ NewConnectionResultFunc result_func,
gpointer user_data);
+typedef void (*DeleteConnectionResultFunc) (NMRemoteConnection *connection,
+ gboolean deleted,
+ gpointer user_data);
+
+void delete_connection (GtkWindow *parent_window,
+ NMRemoteConnection *connection,
+ DeleteConnectionResultFunc result_func,
+ gpointer user_data);
+
#endif /* __CONNECTION_HELPERS_H__ */
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 84dda1c..f370318 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -79,6 +79,8 @@ enum {
static guint editor_signals[EDITOR_LAST_SIGNAL] = { 0 };
+static GHashTable *active_editors;
+
static gboolean nm_connection_editor_set_connection (NMConnectionEditor *editor,
NMConnection *connection,
GError **error);
@@ -324,6 +326,8 @@ dispose (GObject *object)
goto out;
editor->disposed = TRUE;
+ g_hash_table_remove (active_editors, editor->orig_connection);
+
g_slist_foreach (editor->initializing_pages, (GFunc) g_object_unref, NULL);
g_slist_free (editor->initializing_pages);
editor->initializing_pages = NULL;
@@ -355,6 +359,10 @@ dispose (GObject *object)
gtk_widget_destroy (editor->window);
editor->window = NULL;
}
+ if (editor->parent_window) {
+ g_object_unref (editor->parent_window);
+ editor->parent_window = NULL;
+ }
if (editor->builder) {
g_object_unref (editor->builder);
editor->builder = NULL;
@@ -363,6 +371,8 @@ dispose (GObject *object)
g_signal_handler_disconnect (editor->client, editor->permission_id);
g_object_unref (editor->client);
+ g_object_unref (editor->settings);
+
out:
G_OBJECT_CLASS (nm_connection_editor_parent_class)->dispose (object);
}
@@ -382,27 +392,30 @@ nm_connection_editor_class_init (NMConnectionEditorClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMConnectionEditorClass, done),
NULL, NULL,
- _nma_marshal_VOID__INT_POINTER,
- G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
+ _nma_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1, GTK_TYPE_RESPONSE_TYPE);
}
NMConnectionEditor *
-nm_connection_editor_new (NMConnection *connection,
+nm_connection_editor_new (GtkWindow *parent_window,
+ NMConnection *connection,
NMClient *client,
- GError **error)
+ NMRemoteSettings *settings)
{
NMConnectionEditor *editor;
GtkWidget *hbox;
+ gboolean is_new;
+ GError *error = NULL;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
- editor = g_object_new (NM_TYPE_CONNECTION_EDITOR, NULL);
- if (!editor) {
- g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "%s", _("Error creating connection editor dialog."));
- return NULL;
- }
+ is_new = !nm_remote_settings_get_connection_by_uuid (settings, nm_connection_get_uuid (connection));
+ editor = g_object_new (NM_TYPE_CONNECTION_EDITOR, NULL);
+ editor->parent_window = parent_window ? g_object_ref (parent_window) : NULL;
editor->client = g_object_ref (client);
+ editor->settings = g_object_ref (settings);
+ editor->is_new_connection = is_new;
editor->can_modify = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM);
editor->permission_id = g_signal_connect (editor->client,
@@ -427,14 +440,32 @@ nm_connection_editor_new (NMConnection *connection,
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)) {
+ if (!nm_connection_editor_set_connection (editor, connection, &error)) {
+ nm_connection_editor_error (parent_window,
+ is_new ? _("Could not create connection") : _("Could not edit connection"),
+ "%s",
+ error ? error->message : _("Unknown error creating connection editor dialog."));
+ g_clear_error (&error);
g_object_unref (editor);
return NULL;
}
+ if (!active_editors)
+ active_editors = g_hash_table_new (NULL, NULL);
+ g_hash_table_insert (active_editors, connection, editor);
+
return editor;
}
+NMConnectionEditor *
+nm_connection_editor_get (NMConnection *connection)
+{
+ if (!active_editors)
+ return NULL;
+
+ return g_hash_table_lookup (active_editors, connection);
+}
+
NMConnection *
nm_connection_editor_get_connection (NMConnectionEditor *editor)
{
@@ -478,15 +509,26 @@ update_secret_flags (NMSetting *setting,
}
gboolean
-nm_connection_editor_update_connection (NMConnectionEditor *editor, GError **error)
+nm_connection_editor_update_connection (NMConnectionEditor *editor)
{
GHashTable *settings;
gboolean everyone = FALSE;
+ GError *error = NULL;
g_return_val_if_fail (NM_IS_CONNECTION_EDITOR (editor), FALSE);
- if (!nm_connection_verify (editor->connection, error))
+ if (!nm_connection_verify (editor->connection, &error)) {
+ /* In theory, this cannot happen: the "Save..." button should only
+ * be sensitive if the connection is valid.
+ */
+ nm_connection_editor_error (GTK_WINDOW (editor->window),
+ _("Error saving connection"),
+ _("The property '%s' / '%s' is invalid: %d"),
+ g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
+ error->message, error->code);
+ g_error_free (error);
return FALSE;
+ }
/* Update secret flags at the end after all other settings have updated,
* otherwise the secret flags we set here might be overwritten during
@@ -582,7 +624,11 @@ page_initialized (CEPage *page, GError *error, gpointer user_data)
if (error) {
gtk_widget_hide (editor->window);
- g_signal_emit (editor, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_NONE, error);
+ nm_connection_editor_error (editor->parent_window,
+ _("Error initializing editor"),
+ "%s", error->message);
+ g_error_free (error);
+ g_signal_emit (editor, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_NONE);
return;
}
@@ -855,7 +901,13 @@ cancel_button_clicked_cb (GtkWidget *widget, gpointer user_data)
{
NMConnectionEditor *self = NM_CONNECTION_EDITOR (user_data);
- g_signal_emit (self, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_CANCEL, NULL);
+ /* If the dialog is busy waiting for authorization or something,
+ * don't destroy it until authorization returns.
+ */
+ if (self->busy)
+ return;
+
+ g_signal_emit (self, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_CANCEL);
}
static void
@@ -881,10 +933,58 @@ nag_dialog_response_cb (GtkDialog *dialog,
}
static void
+added_connection_cb (NMRemoteSettings *settings,
+ NMRemoteConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ NMConnectionEditor *self = user_data;
+
+ nm_connection_editor_set_busy (self, FALSE);
+
+ if (error) {
+ nm_connection_editor_error (self->parent_window, _("Connection add failed"),
+ "%s", error->message);
+
+ /* Leave the editor open */
+ return;
+ }
+
+ g_signal_emit (self, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_OK);
+}
+
+static void
+update_complete (NMConnectionEditor *self, GError *error)
+{
+ nm_connection_editor_set_busy (self, FALSE);
+ g_signal_emit (self, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_OK);
+}
+
+static void
+updated_connection_cb (NMRemoteConnection *connection, GError *error, gpointer user_data)
+{
+ NMConnectionEditor *self = NM_CONNECTION_EDITOR (user_data);
+
+ /* Clear secrets so they don't lay around in memory; they'll get requested
+ * again anyway next time the connection is edited.
+ */
+ nm_connection_clear_secrets (NM_CONNECTION (connection));
+
+ update_complete (self, error);
+}
+
+static void
ok_button_clicked_cb (GtkWidget *widget, gpointer user_data)
{
NMConnectionEditor *self = NM_CONNECTION_EDITOR (user_data);
GSList *iter;
+ GError *error = NULL;
+
+ /* If the dialog is busy waiting for authorization or something,
+ * don't destroy it until authorization returns.
+ */
+ if (self->busy)
+ return;
/* Make sure the user is warned about insecure security options like no
* CA certificate.
@@ -902,7 +1002,34 @@ ok_button_clicked_cb (GtkWidget *widget, gpointer user_data)
}
}
- g_signal_emit (self, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_OK, NULL);
+ if (!nm_connection_editor_update_connection (self))
+ return;
+
+ nm_connection_editor_set_busy (self, TRUE);
+
+ if (self->is_new_connection) {
+ nm_remote_settings_add_connection (self->settings,
+ self->orig_connection,
+ added_connection_cb,
+ self);
+ } else {
+ GHashTable *new_settings;
+
+ /* Connections need the certificates filled because the applet
+ * private values that we use to store the path to
+ * certificates and private keys don't go through D-Bus; they
+ * are private of course!
+ */
+ new_settings = nm_connection_to_hash (self->orig_connection, NM_SETTING_HASH_FLAG_ALL);
+ if (!nm_connection_replace_settings (self->orig_connection, new_settings, &error)) {
+ update_complete (self, error);
+ g_error_free (error);
+ return;
+ }
+
+ nm_remote_connection_commit_changes (NM_REMOTE_CONNECTION (self->orig_connection),
+ updated_connection_cb, self);
+ }
}
static void
@@ -986,3 +1113,29 @@ nm_connection_editor_set_busy (NMConnectionEditor *editor, gboolean busy)
}
}
+void
+nm_connection_editor_error (GtkWindow *parent, const char *heading, const char *format, ...)
+{
+ GtkWidget *dialog;
+ va_list args;
+ char *message;
+
+ dialog = gtk_message_dialog_new (parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "%s", heading);
+
+ va_start (args, format);
+ message = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+ g_free (message);
+
+ gtk_widget_show_all (dialog);
+ gtk_window_present (GTK_WINDOW (dialog));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h
index d1cfeee..b759a31 100644
--- a/src/connection-editor/nm-connection-editor.h
+++ b/src/connection-editor/nm-connection-editor.h
@@ -25,6 +25,7 @@
#include <glib-object.h>
#include <nm-client.h>
+#include <nm-remote-settings.h>
#include "utils.h"
#define NM_TYPE_CONNECTION_EDITOR (nm_connection_editor_get_type ())
@@ -37,12 +38,15 @@ typedef struct {
GObject parent;
gboolean disposed;
+ GtkWindow *parent_window;
NMClient *client;
guint permission_id;
+ NMRemoteSettings *settings;
/* private data */
NMConnection *connection;
NMConnection *orig_connection;
+ gboolean is_new_connection;
GetSecretsInfo *secrets_call;
GSList *pending_secrets_calls;
@@ -71,16 +75,23 @@ typedef struct {
} NMConnectionEditorClass;
GType nm_connection_editor_get_type (void);
-NMConnectionEditor *nm_connection_editor_new (NMConnection *connection,
+NMConnectionEditor *nm_connection_editor_new (GtkWindow *parent_window,
+ NMConnection *connection,
NMClient *client,
- GError **error);
+ NMRemoteSettings *settings);
+NMConnectionEditor *nm_connection_editor_get (NMConnection *connection);
void nm_connection_editor_present (NMConnectionEditor *editor);
void nm_connection_editor_run (NMConnectionEditor *editor);
NMConnection * nm_connection_editor_get_connection (NMConnectionEditor *editor);
-gboolean nm_connection_editor_update_connection (NMConnectionEditor *editor, GError **error);
+gboolean nm_connection_editor_update_connection (NMConnectionEditor *editor);
GtkWindow * nm_connection_editor_get_window (NMConnectionEditor *editor);
gboolean nm_connection_editor_get_busy (NMConnectionEditor *editor);
void nm_connection_editor_set_busy (NMConnectionEditor *editor, gboolean busy);
+void nm_connection_editor_error (GtkWindow *parent,
+ const char *heading,
+ const char *format,
+ ...);
+
#endif
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index 6cc6ddf..8fe0580 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -71,32 +71,6 @@ static guint list_signals[LIST_LAST_SIGNAL] = { 0 };
#define COL_GTYPE 4
#define COL_ORDER 5
-static void
-error_dialog (GtkWindow *parent, const char *heading, const char *format, ...)
-{
- GtkWidget *dialog;
- va_list args;
- char *message;
-
- dialog = gtk_message_dialog_new (parent,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s", heading);
-
- va_start (args, format);
- message = g_strdup_vprintf (format, args);
- va_end (args);
-
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", message);
- g_free (message);
-
- gtk_widget_show_all (dialog);
- gtk_window_present (GTK_WINDOW (dialog));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-}
-
static NMRemoteConnection *
get_active_connection (GtkTreeView *treeview)
{
@@ -257,281 +231,38 @@ update_connection_row (NMConnectionList *self,
/**********************************************/
-/* Connection deleting */
-
-typedef void (*DeleteResultFunc) (NMConnectionList *list,
- GError *error,
- gpointer user_data);
-
-typedef struct {
- NMConnectionList *list;
- NMRemoteConnection *original;
- NMConnectionEditor *editor;
- DeleteResultFunc callback;
- gpointer callback_data;
-} DeleteInfo;
-
-static void
-delete_cb (NMRemoteConnection *remote,
- GError *error,
- gpointer user_data)
-{
- DeleteInfo *info = user_data;
-
- if (info->editor)
- nm_connection_editor_set_busy (info->editor, FALSE);
-
- info->callback (info->list, error, info->callback_data);
- g_free (info);
-}
-
-static void
-delete_connection (NMConnectionList *list,
- NMRemoteConnection *connection,
- DeleteResultFunc callback,
- gpointer user_data)
-{
- DeleteInfo *info;
- NMConnectionEditor *editor;
-
- editor = g_hash_table_lookup (list->editors, connection);
-
- info = g_malloc0 (sizeof (DeleteInfo));
- info->list = list;
- info->callback = callback;
- info->callback_data = user_data;
- info->editor = editor;
-
- if (editor)
- nm_connection_editor_set_busy (editor, TRUE);
-
- nm_remote_connection_delete (connection, delete_cb, info);
-}
-
-/**********************************************/
-/* Connection adding */
-
-typedef void (*AddResultFunc) (NMConnectionList *list,
- GError *error,
- gpointer user_data);
-
-typedef struct {
- NMConnectionList *list;
- NMConnectionEditor *editor;
- AddResultFunc callback;
- gpointer callback_data;
-} AddInfo;
-
-static void
-add_cb (NMRemoteSettings *settings,
- NMRemoteConnection *connection,
- GError *error,
- gpointer user_data)
-{
- AddInfo *info = user_data;
-
- nm_connection_editor_set_busy (info->editor, FALSE);
- info->callback (info->list, error, info->callback_data);
- g_free (info);
-}
-
-static void
-add_connection (NMConnectionList *self,
- NMConnectionEditor *editor,
- AddResultFunc callback,
- gpointer callback_data)
-{
- AddInfo *info;
-
- info = g_malloc0 (sizeof (AddInfo));
- info->list = self;
- info->editor = editor;
- info->callback = callback;
- info->callback_data = callback_data;
-
- nm_connection_editor_set_busy (editor, TRUE);
-
- nm_remote_settings_add_connection (self->settings,
- nm_connection_editor_get_connection (editor),
- add_cb,
- info);
-}
-
-/**********************************************/
-/* Connection updating */
-
-typedef void (*UpdateResultFunc) (NMConnectionList *list,
- NMRemoteConnection *connection,
- GError *error,
- gpointer user_data);
-
-typedef struct {
- NMConnectionList *list;
- NMConnectionEditor *editor;
- NMRemoteConnection *connection;
- UpdateResultFunc callback;
- gpointer callback_data;
-} UpdateInfo;
-
-static void
-update_complete (UpdateInfo *info, GError *error)
-{
- info->callback (info->list, info->connection, error, info->callback_data);
- g_object_unref (info->connection);
- g_free (info);
-}
-
-static void
-update_cb (NMRemoteConnection *connection, GError *error, gpointer user_data)
-{
- UpdateInfo *info = user_data;
-
- nm_connection_editor_set_busy (info->editor, FALSE);
-
- /* Clear secrets so they don't lay around in memory; they'll get requested
- * again anyway next time the connection is edited.
- */
- nm_connection_clear_secrets (NM_CONNECTION (connection));
-
- update_complete (info, error);
-}
-
-static void
-update_connection (NMConnectionList *list,
- NMConnectionEditor *editor,
- NMRemoteConnection *connection,
- UpdateResultFunc callback,
- gpointer user_data)
-{
- UpdateInfo *info;
- GHashTable *new_settings;
- GError *error = NULL;
-
- info = g_malloc0 (sizeof (UpdateInfo));
- info->list = list;
- info->editor = editor;
- info->connection = g_object_ref (connection);
- info->callback = callback;
- info->callback_data = user_data;
-
- /* Connections need the certificates filled because the
- * applet private values that we use to store the path to certificates
- * and private keys don't go through D-Bus; they are private of course!
- */
- new_settings = nm_connection_to_hash (NM_CONNECTION (connection), NM_SETTING_HASH_FLAG_ALL);
- if (!nm_connection_replace_settings (NM_CONNECTION (connection), new_settings, &error)) {
- update_complete (info, error);
- g_error_free (error);
- return;
- }
-
- nm_connection_editor_set_busy (editor, TRUE);
- nm_remote_connection_commit_changes (connection, update_cb, info);
-}
-
-/**********************************************/
/* dialog/UI handling stuff */
static void
-add_finished_cb (NMConnectionList *list, GError *error, gpointer user_data)
-{
- NMConnectionEditor *editor = NM_CONNECTION_EDITOR (user_data);
- GtkWindow *parent;
-
- if (error) {
- parent = nm_connection_editor_get_window (editor);
- error_dialog (parent, _("Connection add failed"), "%s", error->message);
- }
-
- g_hash_table_remove (list->editors, nm_connection_editor_get_connection (editor));
-}
-
-
-static void
-add_response_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer user_data)
+add_response_cb (NMConnectionEditor *editor, GtkResponseType response, gpointer user_data)
{
NMConnectionList *list = user_data;
- GError *add_error = NULL;
- /* if the dialog is busy waiting for authorization or something,
- * don't destroy it until authorization returns.
- */
- if (nm_connection_editor_get_busy (editor))
- return;
-
- if (response == GTK_RESPONSE_OK) {
- /* Verify and commit user changes */
- if (nm_connection_editor_update_connection (editor, &add_error)) {
- /* Yay we can try to add the connection; it'll get removed from
- * list->editors when the add finishes.
- */
- add_connection (list, editor, add_finished_cb, editor);
- return;
- } else {
- error_dialog (GTK_WINDOW (editor->window),
- _("Error saving connection"),
- _("The property '%s' / '%s' is invalid: %d"),
- g_type_name (nm_connection_lookup_setting_type_by_quark (add_error->domain)),
- (add_error && add_error->message) ? add_error->message : "(unknown)",
- add_error ? add_error->code : -1);
- g_clear_error (&add_error);
- }
- } else if (response == GTK_RESPONSE_NONE) {
- const char *message = _("An unknown error occurred.");
-
- if (error && error->message)
- message = error->message;
- error_dialog (GTK_WINDOW (editor->window),
- _("Error initializing editor"),
- "%s", message);
- }
-
- g_hash_table_remove (list->editors, nm_connection_editor_get_connection (editor));
+ g_object_unref (editor);
g_signal_emit (list, list_signals[EDITING_DONE], 0, 0);
}
-
static void
really_add_connection (NMConnection *connection,
- gboolean canceled,
- GError *error,
gpointer user_data)
{
NMConnectionList *list = user_data;
NMConnectionEditor *editor;
- GError *editor_error = NULL;
- const char *message = _("The connection editor dialog could not be initialized due to an unknown error.");
-
- if (canceled) {
- g_signal_emit (list, list_signals[EDITING_DONE], 0, 0);
- return;
- }
if (!connection) {
- error_dialog (GTK_WINDOW (list->dialog),
- _("Could not create new connection"),
- "%s",
- (error && error->message) ? error->message : message);
g_signal_emit (list, list_signals[EDITING_DONE], 0, 0);
return;
}
- editor = nm_connection_editor_new (connection, list->nm_client, &error);
+ editor = nm_connection_editor_new (GTK_WINDOW (list->dialog), connection,
+ list->nm_client, list->settings);
if (!editor) {
g_object_unref (connection);
-
- error_dialog (GTK_WINDOW (list->dialog),
- _("Could not edit new connection"),
- "%s",
- (editor_error && editor_error->message) ? editor_error->message : message);
- g_clear_error (&editor_error);
g_signal_emit (list, list_signals[EDITING_DONE], 0, 0);
return;
}
g_signal_connect (editor, "done", G_CALLBACK (add_response_cb), list);
- g_hash_table_insert (list->editors, connection, editor);
-
nm_connection_editor_run (editor);
}
@@ -547,138 +278,42 @@ add_clicked (GtkButton *button, gpointer user_data)
list);
}
-typedef struct {
- NMConnectionList *list;
- NMConnectionEditor *editor;
-} EditInfo;
-
static void
-connection_updated_cb (NMConnectionList *list,
- NMRemoteConnection *connection,
- GError *error,
- gpointer user_data)
+edit_done_cb (NMConnectionEditor *editor, GtkResponseType response, gpointer user_data)
{
- EditInfo *info = user_data;
- GtkTreeIter iter;
-
- if (error) {
- /* Log the error and do nothing. We don't want to destroy the dialog
- * because that's not really useful. If there's a hard error, the user
- * will just have to cancel. This better handles the case where
- * PolicyKit authentication is required, but the user accidentally gets
- * their password wrong. Which used to close the dialog, and that's
- * completely unhelpful. Instead just let them hit 'Save' again.
- */
- g_warning ("Error updating connection '%s': (%d) %s",
- nm_connection_get_id (NM_CONNECTION (connection)),
- error->code,
- error->message);
- return;
- }
-
- /* Success */
- if (get_iter_for_connection (list, connection, &iter))
- update_connection_row (list, &iter, connection);
-
- /* This callback might be triggered long after it's caller was called,
- * if for example we've had to get PolicyKit authentication to perform
- * the update. So only signal we're done with editing when all that is
- * complete.
- */
- g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
-
- g_hash_table_remove (list->editors, connection);
- g_free (info);
-}
-
-static void
-edit_done_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer user_data)
-{
- EditInfo *info = user_data;
- const char *message = _("An unknown error occurred.");
- NMConnection *connection;
- GError *edit_error = NULL;
+ NMConnectionList *list = user_data;
- /* if the dialog is busy waiting for authorization or something,
- * don't destroy it until authorization returns.
- */
- if (nm_connection_editor_get_busy (editor))
- return;
+ if (response == GTK_RESPONSE_OK) {
+ NMRemoteConnection *connection = NM_REMOTE_CONNECTION (nm_connection_editor_get_connection (editor));
+ GtkTreeIter iter;
- connection = nm_connection_editor_get_connection (editor);
- g_assert (connection);
-
- switch (response) {
- case GTK_RESPONSE_OK:
- /* Verify and commit user changes */
- if (nm_connection_editor_update_connection (editor, &edit_error)) {
- /* Save the connection to backing storage */
- update_connection (info->list,
- editor,
- NM_REMOTE_CONNECTION (connection),
- connection_updated_cb,
- info);
- } else {
- g_warning ("%s: invalid connection after update: bug in the "
- "'%s' / '%s' invalid: %d",
- __func__,
- g_type_name (nm_connection_lookup_setting_type_by_quark (edit_error->domain)),
- edit_error->message, edit_error->code);
- connection_updated_cb (info->list,
- NM_REMOTE_CONNECTION (connection),
- edit_error,
- NULL);
- g_error_free (edit_error);
- }
- break;
- case GTK_RESPONSE_NONE:
- /* Show an error dialog if the editor initialization failed */
- if (error && error->message)
- message = error->message;
- error_dialog (GTK_WINDOW (editor->window), _("Error initializing editor"), "%s", message);
- /* fall through */
- case GTK_RESPONSE_CANCEL:
- default:
- g_hash_table_remove (info->list->editors, connection);
- g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
- g_free (info);
- break;
+ if (get_iter_for_connection (list, connection, &iter))
+ update_connection_row (list, &iter, connection);
}
+
+ g_object_unref (editor);
+ g_signal_emit (list, list_signals[EDITING_DONE], 0, 0);
}
static void
edit_connection (NMConnectionList *list, NMConnection *connection)
{
NMConnectionEditor *editor;
- EditInfo *edit_info;
- GError *error = NULL;
- const char *message = _("The connection editor dialog could not be initialized due to an unknown error.");
g_return_if_fail (connection != NULL);
/* Don't allow two editors for the same connection */
- editor = (NMConnectionEditor *) g_hash_table_lookup (list->editors, connection);
+ editor = nm_connection_editor_get (connection);
if (editor) {
nm_connection_editor_present (editor);
return;
}
- editor = nm_connection_editor_new (NM_CONNECTION (connection), list->nm_client, &error);
- if (!editor) {
- error_dialog (GTK_WINDOW (list->dialog),
- _("Could not edit connection"),
- "%s",
- (error && error->message) ? error->message : message);
- return;
- }
-
- edit_info = g_malloc0 (sizeof (EditInfo));
- edit_info->list = list;
- edit_info->editor = editor;
-
- g_signal_connect (editor, "done", G_CALLBACK (edit_done_cb), edit_info);
- g_hash_table_insert (list->editors, connection, editor);
-
+ editor = nm_connection_editor_new (GTK_WINDOW (list->dialog),
+ NM_CONNECTION (connection),
+ list->nm_client,
+ list->settings);
+ g_signal_connect (editor, "done", G_CALLBACK (edit_done_cb), list);
nm_connection_editor_run (editor);
}
@@ -689,62 +324,15 @@ do_edit (NMConnectionList *list)
}
static void
-delete_result_cb (NMConnectionList *list,
- GError *error,
- gpointer user_data)
-{
- GtkWindow *parent = GTK_WINDOW (user_data);
-
- if (error)
- error_dialog (parent, _("Connection delete failed"), "%s", error->message);
-}
-
-static void
delete_clicked (GtkButton *button, gpointer user_data)
{
NMConnectionList *list = user_data;
NMRemoteConnection *connection;
- NMConnectionEditor *editor;
- NMSettingConnection *s_con;
- GtkWidget *dialog;
- const char *id;
- guint result;
connection = get_active_connection (list->connection_list);
g_return_if_fail (connection != NULL);
- editor = g_hash_table_lookup (list->editors, connection);
- if (editor && nm_connection_editor_get_busy (editor)) {
- /* Editor already has an operation in progress, raise it */
- nm_connection_editor_present (editor);
- return;
- }
-
- s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
- g_assert (s_con);
- id = nm_setting_connection_get_id (s_con);
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (list->dialog),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- _("Are you sure you wish to delete the connection %s?"),
- id);
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_DELETE, GTK_RESPONSE_YES,
- NULL);
- gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (list->dialog));
-
- result = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- if (result == GTK_RESPONSE_YES) {
- delete_connection (list,
- connection,
- delete_result_cb,
- GTK_WINDOW (list->dialog));
- }
+ delete_connection (GTK_WINDOW (list->dialog), connection, NULL, NULL);
}
static void
@@ -802,9 +390,6 @@ dispose (GObject *object)
if (list->dialog)
gtk_widget_hide (list->dialog);
- if (list->editors)
- g_hash_table_destroy (list->editors);
-
if (list->gui)
g_object_unref (list->gui);
if (list->nm_client)
@@ -1235,8 +820,6 @@ nm_connection_list_new (void)
G_CALLBACK (initial_connections_read),
list);
- list->editors = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
-
list->connection_list = GTK_TREE_VIEW (gtk_builder_get_object (list->gui, "connection_list"));
initialize_treeview (list);
add_connection_buttons (list);
@@ -1281,9 +864,9 @@ nm_connection_list_create (NMConnectionList *self, GType ctype, const char *deta
break;
}
if (!types[i].name) {
- error_dialog (NULL,
- _("Error creating connection"),
- _("Don't know how to create '%s' connections"), g_type_name (ctype));
+ nm_connection_editor_error (NULL,
+ _("Error creating connection"),
+ _("Don't know how to create '%s' connections"), g_type_name (ctype));
} else {
new_connection_of_type (GTK_WINDOW (self->dialog),
detail,
@@ -1337,9 +920,9 @@ connections_read (NMRemoteSettings *settings, EditData *data)
G_CALLBACK (connections_read), data);
return;
} else {
- error_dialog (NULL,
- _("Error editing connection"),
- _("Did not find a connection with UUID '%s'"), data->uuid);
+ nm_connection_editor_error (NULL,
+ _("Error editing connection"),
+ _("Did not find a connection with UUID '%s'"), data->uuid);
}
if (signal_id != 0) {
diff --git a/src/connection-editor/nm-connection-list.h b/src/connection-editor/nm-connection-list.h
index 6099c76..e77c58a 100644
--- a/src/connection-editor/nm-connection-list.h
+++ b/src/connection-editor/nm-connection-list.h
@@ -37,8 +37,6 @@ typedef struct {
GObject parent;
/* private data */
- GHashTable *editors;
-
GtkTreeView *connection_list;
GtkTreeModel *model;
GtkTreeModelFilter *filter;
diff --git a/src/connection-editor/page-vpn.c b/src/connection-editor/page-vpn.c
index 9cdce22..a98628e 100644
--- a/src/connection-editor/page-vpn.c
+++ b/src/connection-editor/page-vpn.c
@@ -279,6 +279,15 @@ vpn_type_filter_func (GType type, gpointer user_data)
return type == NM_TYPE_SETTING_VPN;
}
+static void
+vpn_type_result_func (NMConnection *connection, gpointer user_data)
+{
+ NewVpnInfo *info = user_data;
+
+ info->result_func (connection, connection == NULL, NULL, info->user_data);
+ g_slice_free (NewVpnInfo, info);
+}
+
void
vpn_connection_new (GtkWindow *parent,
const char *detail,
@@ -290,15 +299,20 @@ vpn_connection_new (GtkWindow *parent,
NMSetting *s_vpn;
if (!detail) {
+ NewVpnInfo *info;
+
/* This will happen if nm-c-e is launched from the command line
* with "--create --type vpn". Dump the user back into the
* new connection dialog to let them pick a subtype now.
*/
+ info = g_slice_new (NewVpnInfo);
+ info->result_func = result_func;
+ info->user_data = user_data;
new_connection_dialog_full (parent, settings,
NEW_VPN_CONNECTION_PRIMARY_LABEL,
NEW_VPN_CONNECTION_SECONDARY_LABEL,
vpn_type_filter_func,
- result_func, user_data);
+ vpn_type_result_func, info);
return;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]