[network-manager-applet/bond-editor: 1/4] connection-editor: move a bunch of code out of NMConnectionList



commit ef447297a2436f3a54f5a062c456c646e84f48de
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       |  110 ++++++-
 src/connection-editor/new-connection.h       |   16 +-
 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/marshallers/nma-marshal.list             |    2 +-
 7 files changed, 329 insertions(+), 472 deletions(-)
---
diff --git a/src/connection-editor/new-connection.c b/src/connection-editor/new-connection.c
index 7b4f3ec..608c85c 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-wired.h"
 #include "page-wireless.h"
 #include "page-mobile.h"
@@ -265,7 +266,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;
 
@@ -284,13 +285,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
@@ -298,7 +309,7 @@ new_connection_of_type (GtkWindow *parent_window,
                         NMRemoteSettings *settings,
                         PageNewConnectionFunc new_func,
                         const char *detail,
-                        PageNewConnectionResultFunc result_func,
+                        NewConnectionResultFunc result_func,
                         gpointer user_data)
 {
 	NewConnectionData *ncd;
@@ -319,7 +330,7 @@ new_connection_of_type (GtkWindow *parent_window,
 void
 new_connection_dialog (GtkWindow *parent_window,
                        NMRemoteSettings *settings,
-                       PageNewConnectionResultFunc result_func,
+                       NewConnectionResultFunc result_func,
                        gpointer user_data)
 {
 	const char *objects[] = { "new-connection-dialog", "new-connection-combo-model", NULL };
@@ -375,3 +386,92 @@ new_connection_dialog (GtkWindow *parent_window,
 		new_connection_of_type (parent_window, settings, new_func, vpn_type, result_func, 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 ea40130..6c78a14 100644
--- a/src/connection-editor/new-connection.h
+++ b/src/connection-editor/new-connection.h
@@ -33,16 +33,28 @@ typedef struct {
 
 ConnectionTypeData *get_connection_type_list (void);
 
+typedef void (*NewConnectionResultFunc) (NMConnection *connection,
+                                         gpointer user_data);
+
 void new_connection_dialog  (GtkWindow *parent_window,
                              NMRemoteSettings *settings,
-                             PageNewConnectionResultFunc result_func,
+                             NewConnectionResultFunc result_func,
                              gpointer user_data);
 void new_connection_of_type (GtkWindow *parent_window,
                              NMRemoteSettings *settings,
                              PageNewConnectionFunc new_func,
                              const char *detail,
-                             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 1f23c64..ed83fdf 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);
@@ -321,6 +323,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;
@@ -352,6 +356,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;
@@ -360,6 +368,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);
 }
@@ -379,27 +389,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,
@@ -424,14 +437,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)
 {
@@ -475,15 +506,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
@@ -579,7 +621,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;
 	}
 
@@ -849,7 +895,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
@@ -875,10 +927,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.
@@ -896,7 +996,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
@@ -980,3 +1107,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 9fda1a9..f0d32be 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -79,32 +79,6 @@ static guint list_signals[LIST_LAST_SIGNAL] = { 0 };
 #define COL_GTYPE      5
 #define COL_ORDER      6
 
-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)
 {
@@ -265,281 +239,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);
 }
 
@@ -554,138 +285,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);
 }
 
@@ -696,62 +331,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
@@ -809,9 +397,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)
@@ -1248,8 +833,6 @@ nm_connection_list_new (void)
 	                  G_CALLBACK (connection_added),
 	                  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);
@@ -1294,9 +877,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),
 		                        self->settings,
@@ -1350,9 +933,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/marshallers/nma-marshal.list b/src/marshallers/nma-marshal.list
index 8d8a6ee..4c4aa57 100644
--- a/src/marshallers/nma-marshal.list
+++ b/src/marshallers/nma-marshal.list
@@ -2,7 +2,7 @@ VOID:POINTER
 VOID:STRING,STRING,STRING
 VOID:POINTER,POINTER,STRING,POINTER,UINT,POINTER,POINTER
 VOID:POINTER,POINTER
-VOID:INT,POINTER
+VOID:ENUM
 VOID:STRING,BOXED
 VOID:UINT,UINT
 VOID:UINT,STRING,STRING



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