network-manager-applet r760 - in trunk: . src/connection-editor



Author: tambeti
Date: Fri Jun 20 11:17:52 2008
New Revision: 760
URL: http://svn.gnome.org/viewvc/network-manager-applet?rev=760&view=rev

Log:
2008-06-20  Tambet Ingo  <tambet gmail com>

	* src/connection-editor/ce-page.c
	src/connection-editor/ce-page.h
	src/connection-editor/nm-connection-editor.c
	src/connection-editor/nm-connection-editor.h
	src/connection-editor/nm-connection-list.c
	src/connection-editor/page-dsl.c
	src/connection-editor/page-ip4.c
	src/connection-editor/page-mobile.c
	src/connection-editor/page-ppp.c
	src/connection-editor/page-vpn.c
	src/connection-editor/page-wired-security.c
	src/connection-editor/page-wired.c
	src/connection-editor/page-wireless-security.c
	src/connection-editor/page-wireless-security.h
	src/connection-editor/page-wireless.c

	Use a copy of the real connection in the connection editor. Fixes issues
	where the connection is updated but writing it fails for some reason.
	Keep the connection that's been edited updated after every UI change so
	that pages can act on changes to other pages.


Modified:
   trunk/ChangeLog
   trunk/src/connection-editor/ce-page.c
   trunk/src/connection-editor/ce-page.h
   trunk/src/connection-editor/nm-connection-editor.c
   trunk/src/connection-editor/nm-connection-editor.h
   trunk/src/connection-editor/nm-connection-list.c
   trunk/src/connection-editor/page-dsl.c
   trunk/src/connection-editor/page-ip4.c
   trunk/src/connection-editor/page-mobile.c
   trunk/src/connection-editor/page-ppp.c
   trunk/src/connection-editor/page-vpn.c
   trunk/src/connection-editor/page-wired-security.c
   trunk/src/connection-editor/page-wired.c
   trunk/src/connection-editor/page-wireless-security.c
   trunk/src/connection-editor/page-wireless-security.h
   trunk/src/connection-editor/page-wireless.c

Modified: trunk/src/connection-editor/ce-page.c
==============================================================================
--- trunk/src/connection-editor/ce-page.c	(original)
+++ trunk/src/connection-editor/ce-page.c	Fri Jun 20 11:17:52 2008
@@ -39,21 +39,18 @@
 static guint signals[LAST_SIGNAL] = { 0 };
 
 gboolean
-ce_page_validate (CEPage *self, GError **error)
+ce_page_validate (CEPage *self, NMConnection *connection, GError **error)
 {
+	g_return_val_if_fail (CE_IS_PAGE (self), FALSE);
+	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
 	if (CE_PAGE_GET_CLASS (self)->validate)
-		return CE_PAGE_GET_CLASS (self)->validate (self, error);
+		return CE_PAGE_GET_CLASS (self)->validate (self, connection, error);
 
 	return TRUE;
 }
 
 void
-ce_page_update_connection (CEPage *self, NMConnection *connection)
-{
-	CE_PAGE_GET_CLASS (self)->update_connection (self, connection);
-}
-
-void
 ce_page_mac_to_entry (GByteArray *mac, GtkEntry *entry)
 {
 	struct ether_addr addr;

Modified: trunk/src/connection-editor/ce-page.h
==============================================================================
--- trunk/src/connection-editor/ce-page.h	(original)
+++ trunk/src/connection-editor/ce-page.h	Fri Jun 20 11:17:52 2008
@@ -53,8 +53,7 @@
 	GObjectClass parent;
 
 	/* Virtual functions */
-	gboolean    (*validate)            (CEPage *self, GError **error);
-	void        (*update_connection)   (CEPage *self, NMConnection *connection);
+	gboolean    (*validate)            (CEPage *self, NMConnection *connection, GError **error);
 
 	/* Signals */
 	void        (*changed)             (CEPage *self);
@@ -66,9 +65,7 @@
 
 const char * ce_page_get_title (CEPage *self);
 
-gboolean ce_page_validate (CEPage *self, GError **error);
-
-void ce_page_update_connection (CEPage *self, NMConnection *connection);
+gboolean ce_page_validate (CEPage *self, NMConnection *connection, GError **error);
 
 void ce_page_changed (CEPage *self);
 

Modified: trunk/src/connection-editor/nm-connection-editor.c
==============================================================================
--- trunk/src/connection-editor/nm-connection-editor.c	(original)
+++ trunk/src/connection-editor/nm-connection-editor.c	Fri Jun 20 11:17:52 2008
@@ -71,7 +71,7 @@
 static guint editor_signals[EDITOR_LAST_SIGNAL] = { 0 };
 
 static void nm_connection_editor_set_connection (NMConnectionEditor *editor,
-									    NMExportedConnection *exported);
+									    NMConnection *connection);
 
 static void
 dialog_response_cb (GtkDialog *dialog, guint response, gpointer user_data)
@@ -147,7 +147,7 @@
 	for (iter = editor->pages; iter; iter = g_slist_next (iter)) {
 		GError *error = NULL;
 
-		if (!ce_page_validate (CE_PAGE (iter->data), &error)) {
+		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_error_free (error);
@@ -233,8 +233,8 @@
 	g_slist_free (editor->pages);
 	editor->pages = NULL;
 
-	if (editor->exported)
-		g_object_unref (editor->exported);
+	if (editor->connection)
+		g_object_unref (editor->connection);
 
 	gtk_widget_destroy (editor->dialog);
 	g_object_unref (editor->xml);
@@ -262,24 +262,24 @@
 }
 
 NMConnectionEditor *
-nm_connection_editor_new (NMExportedConnection *exported)
+nm_connection_editor_new (NMConnection *connection)
 {
 	NMConnectionEditor *editor;
 
-	g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (exported), NULL);
+	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
 
 	editor = g_object_new (NM_TYPE_CONNECTION_EDITOR, NULL);
-	nm_connection_editor_set_connection (editor, exported);
+	nm_connection_editor_set_connection (editor, connection);
 
 	return editor;
 }
 
-NMExportedConnection *
+NMConnection *
 nm_connection_editor_get_connection (NMConnectionEditor *editor)
 {
 	g_return_val_if_fail (NM_IS_CONNECTION_EDITOR (editor), NULL);
 
-	return editor->exported;
+	return editor->connection;
 }
 
 gint
@@ -356,20 +356,18 @@
 }
 
 static void
-nm_connection_editor_set_connection (NMConnectionEditor *editor, NMExportedConnection *exported)
+nm_connection_editor_set_connection (NMConnectionEditor *editor, NMConnection *connection)
 {
 	NMSettingConnection *s_con;
 
 	g_return_if_fail (NM_IS_CONNECTION_EDITOR (editor));
-	g_return_if_fail (NM_IS_EXPORTED_CONNECTION (exported));
+	g_return_if_fail (NM_IS_CONNECTION (connection));
 
 	/* clean previous connection */
-	if (editor->exported)
-		g_object_unref (editor->exported);
-
-	editor->exported = g_object_ref (exported);
-	editor->connection = nm_exported_connection_get_connection (exported);
+	if (editor->connection)
+		g_object_unref (editor->connection);
 
+	editor->connection = g_object_ref (connection);
 	nm_connection_editor_update_title (editor);
 
 	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (editor->connection, NM_TYPE_SETTING_CONNECTION));
@@ -380,15 +378,8 @@
 		add_page (editor, CE_PAGE (ce_page_wired_security_new (editor->connection)));
 		add_page (editor, CE_PAGE (ce_page_ip4_new (editor->connection)));
 	} else if (!strcmp (s_con->type, NM_SETTING_WIRELESS_SETTING_NAME)) {
-		CEPageWireless *wireless_page;
-		CEPageWirelessSecurity *wireless_security_page;
-
-		wireless_page = ce_page_wireless_new (editor->connection);
-		add_page (editor, CE_PAGE (wireless_page));
-
-		wireless_security_page = ce_page_wireless_security_new (editor->connection, wireless_page);
-		add_page (editor, CE_PAGE (wireless_security_page));
-
+		add_page (editor, CE_PAGE (ce_page_wireless_new (editor->connection)));
+		add_page (editor, CE_PAGE (ce_page_wireless_security_new (editor->connection)));
 		add_page (editor, CE_PAGE (ce_page_ip4_new (editor->connection)));
 	} else if (!strcmp (s_con->type, NM_SETTING_VPN_SETTING_NAME)) {
 		add_page (editor, CE_PAGE (ce_page_vpn_new (editor->connection)));
@@ -418,12 +409,6 @@
 }
 
 static void
-update_one_page (gpointer data, gpointer user_data)
-{
-	ce_page_update_connection (CE_PAGE (data), NM_CONNECTION (user_data));
-}
-
-static void
 connection_editor_update_connection (NMConnectionEditor *editor)
 {
 	NMSettingConnection *s_con;
@@ -448,8 +433,6 @@
 		nm_connection_set_scope (editor->connection, NM_CONNECTION_SCOPE_SYSTEM);
 	else
 		nm_connection_set_scope (editor->connection, NM_CONNECTION_SCOPE_USER);
-
-	g_slist_foreach (editor->pages, update_one_page, editor->connection);
 }
 
 static void

Modified: trunk/src/connection-editor/nm-connection-editor.h
==============================================================================
--- trunk/src/connection-editor/nm-connection-editor.h	(original)
+++ trunk/src/connection-editor/nm-connection-editor.h	Fri Jun 20 11:17:52 2008
@@ -25,9 +25,7 @@
 
 #include <glib-object.h>
 #include <glade/glade-xml.h>
-#include <gtk/gtksizegroup.h>
 #include <gtk/gtkspinbutton.h>
-#include <gconf/gconf-client.h>
 #include <nm-settings.h>
 
 #define NM_TYPE_CONNECTION_EDITOR    (nm_connection_editor_get_type ())
@@ -38,7 +36,6 @@
 	GObject parent;
 
 	/* private data */
-	NMExportedConnection *exported;
 	NMConnection *connection;
 
 	GSList *pages;
@@ -55,11 +52,11 @@
 } NMConnectionEditorClass;
 
 GType               nm_connection_editor_get_type (void);
-NMConnectionEditor *nm_connection_editor_new (NMExportedConnection *exported);
+NMConnectionEditor *nm_connection_editor_new (NMConnection *connection);
 
 void                nm_connection_editor_present (NMConnectionEditor *editor);
 void                nm_connection_editor_run (NMConnectionEditor *editor);
-NMExportedConnection *nm_connection_editor_get_connection (NMConnectionEditor *editor);
+NMConnection *nm_connection_editor_get_connection (NMConnectionEditor *editor);
 
 gint ce_spin_output_with_default (GtkSpinButton *spin, gpointer user_data);
 

Modified: trunk/src/connection-editor/nm-connection-list.c
==============================================================================
--- trunk/src/connection-editor/nm-connection-list.c	(original)
+++ trunk/src/connection-editor/nm-connection-list.c	Fri Jun 20 11:17:52 2008
@@ -83,23 +83,6 @@
 	GtkWidget *button;
 } ActionInfo;
 
-enum {
-	NM_MODIFY_CONNECTION_ADD,
-	NM_MODIFY_CONNECTION_REMOVE,
-	NM_MODIFY_CONNECTION_UPDATE
-};
-
-typedef void (*NMExportedConnectionChangedFn) (NMConnectionList *list,
-									  NMExportedConnection *exported,
-									  gboolean success,
-									  gpointer user_data);
-
-static void modify_connection (NMConnectionList *self,
-						 NMExportedConnection *exported,
-						 guint action,
-						 NMExportedConnectionChangedFn callback,
-						 gpointer user_data);
-
 static void
 show_error_dialog (const gchar *format, ...)
 {
@@ -294,25 +277,81 @@
 	g_free (last_used);
 }
 
+
+/**********************************************/
+/* PolKit helpers */
+
+static gboolean
+is_permission_denied_error (GError *error)
+{
+	return dbus_g_error_has_name (error, "org.freedesktop.NetworkManagerSettings.Connection.NotPrivileged") ||
+		dbus_g_error_has_name (error, "org.freedesktop.NetworkManagerSettings.System.NotPrivileged");
+}
+
+static gboolean
+obtain_auth (GError *pk_error,
+		   PolKitGnomeAuthCB callback,
+		   gpointer user_data)
+{
+	PolKitAction *pk_action;
+	char **tokens;
+	GError *error;
+	guint xid;
+	pid_t pid;
+	gboolean success = FALSE;
+
+	tokens = g_strsplit (pk_error->message, " ", 2);
+	if (g_strv_length (tokens) != 2) {
+		g_warning ("helper return string malformed");
+		g_strfreev (tokens);
+		return FALSE;
+	}
+
+	pk_action = polkit_action_new ();
+	polkit_action_set_action_id (pk_action, tokens[0]);
+	g_strfreev (tokens);
+
+	xid = 0;
+	pid = getpid ();
+
+	error = NULL;
+	success = polkit_gnome_auth_obtain (pk_action, xid, pid, callback, user_data, &error);
+	if (error) {
+		g_warning ("Could not grant permssion: %s", error->message);
+		g_error_free (error);
+	}
+
+	return success;
+}
+
+/**********************************************/
+/* Connection removing */
+
+typedef void (*ConnectionRemovedFn) (NMExportedConnection *exported,
+							  gboolean success,
+							  gpointer user_data);
+
 typedef struct {
-	NMConnectionList *list;
 	NMExportedConnection *exported;
-	guint action;
-	NMExportedConnectionChangedFn callback;
-	gpointer callback_data;
-} ModifyConnectionInfo;
+	ConnectionRemovedFn callback;
+	gpointer user_data;
+} ConnectionRemoveInfo;
+
+static void remove_connection (NMExportedConnection *exported,
+						 ConnectionRemovedFn callback,
+						 gpointer user_data);
 
 static void
-modify_connection_auth_cb (PolKitAction *action,
-					  gboolean gained_privilege,
-					  GError *error,
-					  gpointer user_data)
+remove_connection_cb (PolKitAction *action,
+				  gboolean gained_privilege,
+				  GError *error,
+				  gpointer user_data)
 {
-	ModifyConnectionInfo *info = (ModifyConnectionInfo *) user_data;
+	ConnectionRemoveInfo *info = (ConnectionRemoveInfo *) user_data;
 	gboolean done = TRUE;
 
 	if (gained_privilege) {
-		modify_connection (info->list, info->exported, info->action, info->callback, info->callback_data);
+		remove_connection (info->exported, info->callback, info->user_data);
 		done = FALSE;
 	} else if (error) {
 		show_error_dialog (_("Could not obtain required privileges: %s."), error->message);
@@ -321,122 +360,308 @@
 		show_error_dialog (_("Could not remove system connection: permission denied."));
 
 	if (done && info->callback)
-		info->callback (info->list, info->exported, FALSE, info->callback_data);
+		info->callback (info->exported, FALSE, info->user_data);
 
 	g_object_unref (info->exported);
-	g_free (info);
+	g_slice_free (ConnectionRemoveInfo, info);
 }
 
 static void
-modify_connection (NMConnectionList *self,
-			    NMExportedConnection *exported,
-			    guint action,
-			    NMExportedConnectionChangedFn callback,
+remove_connection (NMExportedConnection *exported,
+			    ConnectionRemovedFn callback,
 			    gpointer user_data)
 {
-	const char *error_str;
+	GError *error = NULL;
+	gboolean success;
+
+	success = nm_exported_connection_delete (exported, &error);
+
+	if (!success) {
+		gboolean auth_pending = FALSE;
+
+		if (is_permission_denied_error (error)) {
+			ConnectionRemoveInfo *info;
+
+			info = g_slice_new (ConnectionRemoveInfo);
+			info->exported = g_object_ref (exported);
+			info->callback = callback;
+			info->user_data = user_data;
+
+			auth_pending = obtain_auth (error, remove_connection_cb, info);
+
+			if (!auth_pending) {
+				g_object_unref (info->exported);
+				g_slice_free (ConnectionRemoveInfo, info);
+			}
+		} else
+			show_error_dialog (_("Removing connection failed: %s."), error->message);
+
+		g_error_free (error);
+
+		if (auth_pending)
+			return;
+	}
+
+	if (callback)
+		callback (exported, success, user_data);
+}
+
+/**********************************************/
+/* Connection adding */
+
+typedef void (*ConnectionAddedFn) (NMExportedConnection *exported,
+							gboolean success,
+							gpointer user_data);
+
+typedef struct {
+	NMConnectionList *list;
 	NMConnection *connection;
-	GHashTable *settings;
-	GError *err = NULL;
+	ConnectionAddedFn callback;
+	gpointer user_data;
+} ConnectionAddInfo;
+
+static void add_connection (NMConnectionList *self,
+					   NMConnection *connection,
+					   ConnectionAddedFn callback,
+					   gpointer user_data);
+
+static void
+add_connection_cb (PolKitAction *action,
+			    gboolean gained_privilege,
+			    GError *error,
+			    gpointer user_data)
+{
+	ConnectionAddInfo *info = (ConnectionAddInfo *) user_data;
+	gboolean done = TRUE;
+
+	if (gained_privilege) {
+		add_connection (info->list, info->connection, info->callback, info->user_data);
+		done = FALSE;
+	} else if (error) {
+		show_error_dialog (_("Could not obtain required privileges: %s."), error->message);
+		g_error_free (error);
+	} else
+		show_error_dialog (_("Could not add system connection: permission denied."));
+
+	if (done && info->callback)
+		info->callback (NULL, FALSE, info->user_data);
+
+	g_object_unref (info->connection);
+	g_slice_free (ConnectionAddInfo, info);
+}
+
+static void
+add_connection (NMConnectionList *self,
+			 NMConnection *connection,
+			 ConnectionAddedFn callback,
+			 gpointer user_data)
+{
+	NMExportedConnection *exported = NULL;
 	gboolean success;
-	gboolean done = FALSE;
 
-	switch (action) {
-	case NM_MODIFY_CONNECTION_ADD:
-		error_str = _("Adding connection failed");
+	if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) {
+		GError *error = NULL;
 
-		connection = nm_exported_connection_get_connection (exported);
-		if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM)
-			success = nm_dbus_settings_system_add_connection (self->system_settings, connection, &err);
-		else {
-			NMExportedConnection *new_connection;
-
-			new_connection = (NMExportedConnection *) nma_gconf_settings_add_connection (self->gconf_settings, connection);
-			if (new_connection) {
-				exported = new_connection;
-				success = TRUE;
+		success = nm_dbus_settings_system_add_connection (self->system_settings, connection, &error);
+		if (!success) {
+			gboolean pending_auth = FALSE;
+
+			if (is_permission_denied_error (error)) {
+				ConnectionAddInfo *info;
+
+				info = g_slice_new (ConnectionAddInfo);
+				info->list = self;
+				info->connection = g_object_ref (connection);
+				info->callback = callback;
+				info->user_data = user_data;
+
+				pending_auth = obtain_auth (error, add_connection_cb, info);
+
+				if (!pending_auth) {
+					g_object_unref (info->connection);
+					g_slice_free (ConnectionAddInfo, info);
+				}
 			} else
-				success = FALSE;
+				show_error_dialog (_("Adding connection failed: %s."), error->message);
+
+			g_error_free (error);
+
+			if (pending_auth)
+				return;
+
 		}
-		break;
-	case NM_MODIFY_CONNECTION_REMOVE:
-		error_str = _("Removing connection failed");
-		success = nm_exported_connection_delete (exported, &err);
-		break;
-	case NM_MODIFY_CONNECTION_UPDATE:
-		error_str = _("Updating connection failed");
-		settings = nm_connection_to_hash (nm_exported_connection_get_connection (exported));
-		success = nm_exported_connection_update (exported, settings, &err);
-		g_hash_table_destroy (settings);
-		break;
-	default:
-		g_warning ("Invalid action '%d' in %s", action, __func__);
-		return;
+	} else {
+		exported = (NMExportedConnection *) nma_gconf_settings_add_connection (self->gconf_settings, connection);
+		success = exported != NULL;
 	}
 
-	if (success)
-		done = TRUE;
+	if (callback)
+		callback (exported, success, user_data);
 
-	if (err && (dbus_g_error_has_name (err, "org.freedesktop.NetworkManagerSettings.Connection.NotPrivileged") ||
-			  dbus_g_error_has_name (err, "org.freedesktop.NetworkManagerSettings.System.NotPrivileged"))) {
+	if (exported)
+		g_object_unref (exported);
+}
 
-		ModifyConnectionInfo *info;
-		PolKitAction *pk_action;
-		char **tokens;
-		guint xid;
-		pid_t pid;
-
-		tokens = g_strsplit (err->message, " ", 2);
-		if (g_strv_length (tokens) != 2) {
-			g_warning ("helper return string malformed");
-			g_strfreev (tokens);
-			goto out;
-		}
+/**********************************************/
+/* Connection updating */
 
-		pk_action = polkit_action_new ();
-		polkit_action_set_action_id (pk_action, tokens[0]);
-		g_strfreev (tokens);
+typedef void (*ConnectionUpdatedFn) (NMConnectionList *list,
+							  gboolean success,
+							  gpointer user_data);
 
-		xid = 0;
-		pid = getpid ();
+typedef struct {
+	NMConnectionList *list;
+	NMExportedConnection *original;
+	NMConnection *modified;
+	ConnectionUpdatedFn callback;
+	gpointer user_data;
+
+	NMExportedConnection *added_connection;
+} ConnectionUpdateInfo;
+
+static void update_connection (NMConnectionList *list,
+						 NMExportedConnection *original,
+						 NMConnection *modified,
+						 ConnectionUpdatedFn callback,
+						 gpointer user_data);
 
-		g_error_free (err);
-		err = NULL;
 
-		info = g_new (ModifyConnectionInfo, 1);
-		info->list = self;
-		info->exported = g_object_ref (exported);
-		info->action = action;
-		info->callback = callback;
-		info->callback_data = user_data;
-
-		if (!polkit_gnome_auth_obtain (pk_action, xid, pid, modify_connection_auth_cb, info, &err)) {
-			g_object_unref (info->exported);
-			g_free (info);
-		}
+static void
+connection_update_done (ConnectionUpdateInfo *info, gboolean success)
+{
+	if (info->callback)
+		info->callback (info->list, success, info->user_data);
+
+	g_object_unref (info->original);
+	g_object_unref (info->modified);
+	if (info->added_connection)
+		g_object_unref (info->added_connection);
+
+	g_slice_free (ConnectionUpdateInfo, info);
+}
+
+static void
+connection_update_remove_done (NMExportedConnection *exported,
+						 gboolean success,
+						 gpointer user_data)
+{
+	ConnectionUpdateInfo *info = (ConnectionUpdateInfo *) user_data;
+
+	if (success)
+		connection_update_done (info, success);
+	else if (info->added_connection) {
+		/* Revert the scope of the original connection and remove the connection we just successfully added */
+		/* FIXME: loops forever on error */
+
+		remove_connection (info->added_connection,
+					    connection_update_remove_done, info);
 	}
+}
+
+static void
+connection_update_add_done (NMExportedConnection *exported,
+					   gboolean success,
+					   gpointer user_data)
+{
+	ConnectionUpdateInfo *info = (ConnectionUpdateInfo *) user_data;
 
- out:
-	if (err) {
-		show_error_dialog ("%s: %s.", error_str, err->message);
-		g_error_free (err);
+	if (success) {
+		/* Adding the connection with different scope succeeded, now try to remove the original */
+		info->added_connection = exported ? g_object_ref (exported) : NULL;
+
+		remove_connection (info->original,
+					    connection_update_remove_done,
+					    info);
+	} else
+		connection_update_done (info, success);
+}
+
+static void
+update_connection_cb (PolKitAction *action,
+				  gboolean gained_privilege,
+				  GError *error,
+				  gpointer user_data)
+{
+	ConnectionUpdateInfo *info = (ConnectionUpdateInfo *) user_data;
+	gboolean done = TRUE;
+
+	if (gained_privilege) {
+		update_connection (info->list, info->original, info->modified, info->callback, info->user_data);
+		done = FALSE;
+	} else if (error) {
+		show_error_dialog (_("Could not obtain required privileges: %s."), error->message);
+		g_error_free (error);
+	} else
+		show_error_dialog (_("Could not update system connection: permission denied."));
+
+	if (done)
+		connection_update_done (info, FALSE);
+	else {
+		g_object_unref (info->original);
+		g_object_unref (info->modified);
+		g_slice_free (ConnectionUpdateInfo, info);
 	}
+}
 
-	if (done && callback)
-		callback (self, exported, success, user_data);
+static void
+update_connection (NMConnectionList *list,
+			    NMExportedConnection *original,
+			    NMConnection *modified,
+			    ConnectionUpdatedFn callback,
+			    gpointer user_data)
+{
+	NMConnectionScope original_scope;
+	ConnectionUpdateInfo *info;
+
+	info = g_slice_new0 (ConnectionUpdateInfo);
+	info->list = list;
+	info->original = g_object_ref (original);
+	info->modified = g_object_ref (modified);
+	info->callback = callback;
+	info->user_data = user_data;
+
+	original_scope = nm_connection_get_scope (nm_exported_connection_get_connection (original));
+	if (nm_connection_get_scope (modified) == original_scope) {
+		/* The easy part: Connection is updated */
+		GHashTable *new_settings;
+		GError *error = NULL;
+		gboolean success;
+		gboolean pending_auth = FALSE;
+
+		new_settings = nm_connection_to_hash (modified);
+		success = nm_exported_connection_update (original, new_settings, &error);
+		g_hash_table_destroy (new_settings);
+
+		if (!success) {
+			if (is_permission_denied_error (error))
+				pending_auth = obtain_auth (error, update_connection_cb, info);
+			else
+				show_error_dialog (_("Updating connection failed: %s."), error->message);
+
+			g_error_free (error);
+		}
+
+		if (!pending_auth)
+			connection_update_done (info, success);
+	} else {
+		/* The hard part: Connection scope changed:
+		   Add the exported connection,
+		   if it succeeds, remove the old one. */
+		add_connection (list, modified, connection_update_add_done, info);
+	}
 }
 
 static void
 add_done_cb (NMConnectionEditor *editor, gint response, gpointer user_data)
 {
 	ActionInfo *info = (ActionInfo *) user_data;
-	NMExportedConnection *exported;
+	NMConnection *connection;
 
-	exported = nm_connection_editor_get_connection (editor);
+	connection = nm_connection_editor_get_connection (editor);
 	if (response == GTK_RESPONSE_OK)
-		modify_connection (info->list, exported, NM_MODIFY_CONNECTION_ADD, NULL, NULL);
+		add_connection (info->list, connection, NULL, NULL);
 
-	g_hash_table_remove (info->list->editors, exported);
+	g_hash_table_remove (info->list->editors, connection);
 }
 
 static void
@@ -637,12 +862,11 @@
 }
 
 static void
-add_connection_cb (GtkButton *button, gpointer user_data)
+add_connection_clicked (GtkButton *button, gpointer user_data)
 {
 	ActionInfo *info = (ActionInfo *) user_data;
 	const char *connection_type;
 	NMConnection *connection;
-	NMExportedConnection *exported;
 	NMConnectionEditor *editor;
 
 	connection_type = get_connection_type_from_treeview (info->list, info->treeview);
@@ -654,28 +878,22 @@
 		return;
 	}
 
-	exported = nm_exported_connection_new (connection);
-	g_object_unref (connection);
-
-	editor = nm_connection_editor_new (exported);
+	editor = nm_connection_editor_new (connection);
 	g_signal_connect (G_OBJECT (editor), "done", G_CALLBACK (add_done_cb), info);
-	g_hash_table_insert (info->list->editors, exported, editor);
+	g_hash_table_insert (info->list->editors, connection, editor);
 
 	nm_connection_editor_run (editor);
 }
 
 typedef struct {
 	NMConnectionList *list;
-	NMExportedConnection *new_connection;
-	NMExportedConnection *initial_connection;
-	NMConnectionScope initial_scope;
+	NMExportedConnection *original_connection;
 } EditConnectionInfo;
 
 static void
-connection_update_done (NMConnectionList *list,
-				    NMExportedConnection *exported,
-				    gboolean success,
-				    gpointer user_data)
+connection_updated_cb (NMConnectionList *list,
+				   gboolean success,
+				   gpointer user_data)
 {
 	EditConnectionInfo *info = (EditConnectionInfo *) user_data;
 
@@ -683,90 +901,39 @@
 		GtkListStore *store;
 		GtkTreeIter iter;
 
-		store = get_model_for_connection (list, info->initial_connection);
+		store = get_model_for_connection (list, info->original_connection);
 		g_assert (store);
-		if (get_iter_for_connection (GTK_TREE_MODEL (store), info->initial_connection, &iter))
-			update_connection_row (store, &iter, info->initial_connection);
+		if (get_iter_for_connection (GTK_TREE_MODEL (store), info->original_connection, &iter))
+			update_connection_row (store, &iter, info->original_connection);
 	}
 
-	g_object_unref (info->initial_connection);
+	g_object_unref (info->original_connection);
 	g_free (info);
 }
 
 static void
-connection_update_remove_done (NMConnectionList *list,
-						 NMExportedConnection *exported,
-						 gboolean success,
-						 gpointer user_data)
-{
-	EditConnectionInfo *info = (EditConnectionInfo *) user_data;
-
-	if (success)
-		connection_update_done (list, exported, success, info);
-	else {
-		/* Revert the scope of the original connection and remove the connection we just successfully added */
-		nm_connection_set_scope (nm_exported_connection_get_connection (info->initial_connection),
-							info->initial_scope);
-
-		modify_connection (list, info->new_connection,
-					    NM_MODIFY_CONNECTION_REMOVE,
-					    connection_update_remove_done, info);
-	}
-}
-
-static void
-connection_update_add_done (NMConnectionList *list,
-					   NMExportedConnection *exported,
-					   gboolean success,
-					   gpointer user_data)
-{
-	EditConnectionInfo *info = (EditConnectionInfo *) user_data;
-
-	if (success) {
-		info->new_connection = exported;
-		modify_connection (list, info->initial_connection,
-					    NM_MODIFY_CONNECTION_REMOVE,
-					    connection_update_remove_done, info);
-	} else {
-		/* Revert the scope and clean up */
-		nm_connection_set_scope (nm_exported_connection_get_connection (info->initial_connection),
-							info->initial_scope);
-
-		connection_update_done (list, exported, success, info);
-	}
-}
-
-static void
 edit_done_cb (NMConnectionEditor *editor, gint response, gpointer user_data)
 {
 	EditConnectionInfo *info = (EditConnectionInfo *) user_data;
 
-	g_hash_table_remove (info->list->editors, info->initial_connection);
+	g_hash_table_remove (info->list->editors, info->original_connection);
 
 	if (response == GTK_RESPONSE_OK) {
 		NMConnection *connection;
-		gboolean success;
 		GError *error = NULL;
+		gboolean success;
+
+		connection = nm_connection_editor_get_connection (editor);
 
-		connection = nm_exported_connection_get_connection (info->initial_connection);
 		utils_fill_connection_certs (connection);
 		success = nm_connection_verify (connection, &error);
 		utils_clear_filled_connection_certs (connection);
 
 		if (success) {
-			if (info->initial_scope == nm_connection_get_scope (connection)) {
-				/* The easy part: Connection is updated */
-				modify_connection (info->list, info->initial_connection,
-							    NM_MODIFY_CONNECTION_UPDATE,
-							    connection_update_done, info);
-			} else {
-				/* The hard part: Connection scope changed:
-				   Add the exported connection,
-				   if it succeeds, remove the old one. */
-				modify_connection (info->list, info->initial_connection,
-							    NM_MODIFY_CONNECTION_ADD,
-							    connection_update_add_done, info);
-			}
+			update_connection (info->list, info->original_connection,
+						    connection,
+						    connection_updated_cb,
+						    info);
 		} else {
 			g_warning ("%s: invalid connection after update: bug in the "
 			           "'%s' / '%s' invalid: %d",
@@ -774,6 +941,7 @@
 			           g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
 			           error->message, error->code);
 			g_error_free (error);
+			connection_updated_cb (info->list, FALSE, user_data);
 		}
 	}
 }
@@ -782,6 +950,7 @@
 do_edit (ActionInfo *info)
 {
 	NMExportedConnection *exported;
+	NMConnection *connection;
 	NMConnectionEditor *editor;
 	EditConnectionInfo *edit_info;
 
@@ -795,13 +964,13 @@
 		return;
 	}
 
-	editor = nm_connection_editor_new (exported);
+	connection = nm_connection_duplicate (nm_exported_connection_get_connection (exported));
+	editor = nm_connection_editor_new (connection);
+	g_object_unref (connection);
 
 	edit_info = g_new (EditConnectionInfo, 1);
 	edit_info->list = info->list;
-	edit_info->new_connection = NULL;
-	edit_info->initial_connection = g_object_ref (exported);
-	edit_info->initial_scope = nm_connection_get_scope (nm_exported_connection_get_connection (exported));
+	edit_info->original_connection = g_object_ref (exported);
 
 	g_signal_connect (editor, "done", G_CALLBACK (edit_done_cb), edit_info);
 	g_hash_table_insert (info->list->editors, exported, editor);
@@ -816,14 +985,16 @@
 }
 
 static void
-connection_remove_done (NMConnectionList *list,
-				    NMExportedConnection *exported,
+connection_remove_done (NMExportedConnection *exported,
 				    gboolean success,
 				    gpointer user_data)
 {
-	if (success)
+	if (success) {
+		NMConnectionList *list = (NMConnectionList *) user_data;
+
 		/* Close any open editor windows for this connection */
 		g_hash_table_remove (list->editors, exported);
+	}
 }
 
 static void
@@ -858,9 +1029,7 @@
 	gtk_widget_destroy (dialog);
 
 	if (result == GTK_RESPONSE_YES)
-		modify_connection (info->list, exported,
-					    NM_MODIFY_CONNECTION_REMOVE, 
-					    connection_remove_done, NULL);
+		remove_connection (exported, connection_remove_done, info->list);
 }
 
 static void
@@ -918,7 +1087,6 @@
 import_success_cb (NMConnection *connection, gpointer user_data)
 {
 	ActionInfo *info = (ActionInfo *) user_data;
-	NMExportedConnection *exported;
 	NMConnectionEditor *editor;
 	NMSettingConnection *s_con;
 	NMSettingVPN *s_vpn;
@@ -954,12 +1122,9 @@
 		return;
 	}
 
-	exported = nm_exported_connection_new (connection);
-	g_object_unref (connection);
-
-	editor = nm_connection_editor_new (exported);
+	editor = nm_connection_editor_new (connection);
 	g_signal_connect (G_OBJECT (editor), "done", G_CALLBACK (add_done_cb), info);
-	g_hash_table_insert (info->list->editors, exported, editor);
+	g_hash_table_insert (info->list->editors, connection, editor);
 
 	nm_connection_editor_run (editor);
 }
@@ -1158,7 +1323,7 @@
 	button = glade_xml_get_widget (self->gui, name);
 	g_free (name);
 	info = new_action_info (self, treeview, NULL);
-	g_signal_connect (button, "clicked", G_CALLBACK (add_connection_cb), info);
+	g_signal_connect (button, "clicked", G_CALLBACK (add_connection_clicked), info);
 	if (is_vpn) {
 		GHashTable *plugins;
 

Modified: trunk/src/connection-editor/page-dsl.c
==============================================================================
--- trunk/src/connection-editor/page-dsl.c	(original)
+++ trunk/src/connection-editor/page-dsl.c	Fri Jun 20 11:17:52 2008
@@ -39,7 +39,6 @@
 
 typedef struct {
 	NMSettingPPPOE *setting;
-	NMConnection *connection; /* ugh */
 
 	GtkEntry *username;
 	GtkEntry *password;
@@ -80,7 +79,7 @@
 		GValue *value;
 
 		secrets = nm_gconf_get_keyring_items (connection, connection_id,
-		                                      nm_setting_get_name (NM_SETTING (priv->setting)),
+		                                      nm_setting_get_name (NM_SETTING (setting)),
 		                                      FALSE,
 		                                      &error);
 		if (secrets) {
@@ -121,7 +120,6 @@
 	CEPageDsl *self;
 	CEPageDslPrivate *priv;
 	CEPage *parent;
-	NMSettingPPPOE *s_pppoe;
 
 	self = CE_PAGE_DSL (g_object_new (CE_TYPE_PAGE_DSL, NULL));
 	parent = CE_PAGE (self);
@@ -146,13 +144,11 @@
 	dsl_private_init (self);
 	priv = CE_PAGE_DSL_GET_PRIVATE (self);
 
-	s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
-	if (s_pppoe)
-		priv->setting = NM_SETTING_PPPOE (nm_setting_duplicate (NM_SETTING (s_pppoe)));
-	else
+	priv->setting = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
+	if (!priv->setting) {
 		priv->setting = NM_SETTING_PPPOE (nm_setting_pppoe_new ());
-
-	priv->connection = connection;
+		nm_connection_add_setting (connection, NM_SETTING (priv->setting));
+	}
 
 	populate_ui (self, connection);
 
@@ -194,7 +190,7 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageDsl *self = CE_PAGE_DSL (page);
 	CEPageDslPrivate *priv = CE_PAGE_DSL_GET_PRIVATE (self);
@@ -203,7 +199,7 @@
 
 	ui_to_setting (self);
 
-	foo = g_slist_append (NULL, nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_PPP));
+	foo = g_slist_append (NULL, nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP));
 	valid = nm_setting_verify (NM_SETTING (priv->setting), foo, error);
 	g_slist_free (foo);
 
@@ -211,36 +207,11 @@
 }
 
 static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPageDsl *self = CE_PAGE_DSL (page);
-	CEPageDslPrivate *priv = CE_PAGE_DSL_GET_PRIVATE (self);
-
-	ui_to_setting (self);
-	g_object_ref (priv->setting); /* Add setting steals the reference. */
-	nm_connection_add_setting (connection, NM_SETTING (priv->setting));
-}
-
-static void
 ce_page_dsl_init (CEPageDsl *self)
 {
 }
 
 static void
-dispose (GObject *object)
-{
-	CEPageDslPrivate *priv = CE_PAGE_DSL_GET_PRIVATE (object);
-
-	if (priv->disposed)
-		return;
-
-	priv->disposed = TRUE;
-	g_object_unref (priv->setting);
-
-	G_OBJECT_CLASS (ce_page_dsl_parent_class)->dispose (object);
-}
-
-static void
 ce_page_dsl_class_init (CEPageDslClass *dsl_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (dsl_class);
@@ -249,8 +220,5 @@
 	g_type_class_add_private (object_class, sizeof (CEPageDslPrivate));
 
 	/* virtual methods */
-	object_class->dispose = dispose;
-
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }

Modified: trunk/src/connection-editor/page-ip4.c
==============================================================================
--- trunk/src/connection-editor/page-ip4.c	(original)
+++ trunk/src/connection-editor/page-ip4.c	Fri Jun 20 11:17:52 2008
@@ -428,7 +428,6 @@
 	CEPageIP4 *self;
 	CEPageIP4Private *priv;
 	CEPage *parent;
-	NMSettingIP4Config *s_ip4;
 	GtkTreeSelection *selection;
 	gint offset;
 	GtkTreeViewColumn *column;
@@ -458,11 +457,11 @@
 	ip4_private_init (self);
 	priv = CE_PAGE_IP4_GET_PRIVATE (self);
 
-	s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-	if (s_ip4)
-		priv->setting = NM_SETTING_IP4_CONFIG (nm_setting_duplicate (NM_SETTING (s_ip4)));
-	else
+	priv->setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+	if (!priv->setting) {
 		priv->setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+		nm_connection_add_setting (connection, NM_SETTING (priv->setting));
+	}
 
 	populate_ui (self);
 
@@ -675,7 +674,7 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageIP4 *self = CE_PAGE_IP4 (page);
 	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
@@ -685,36 +684,11 @@
 }
 
 static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPageIP4 *self = CE_PAGE_IP4 (page);
-	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (page);
-
-	ui_to_setting (self);
-	g_object_ref (priv->setting); /* Add setting steals the reference. */
-	nm_connection_add_setting (connection, NM_SETTING (priv->setting));
-}
-
-static void
 ce_page_ip4_init (CEPageIP4 *self)
 {
 }
 
 static void
-dispose (GObject *object)
-{
-	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (object);
-
-	if (priv->disposed)
-		return;
-
-	priv->disposed = TRUE;
-	g_object_unref (priv->setting);
-
-	G_OBJECT_CLASS (ce_page_ip4_parent_class)->dispose (object);
-}
-
-static void
 ce_page_ip4_class_init (CEPageIP4Class *ip4_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (ip4_class);
@@ -723,8 +697,5 @@
 	g_type_class_add_private (object_class, sizeof (CEPageIP4Private));
 
 	/* virtual methods */
-	object_class->dispose = dispose;
-
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }

Modified: trunk/src/connection-editor/page-mobile.c
==============================================================================
--- trunk/src/connection-editor/page-mobile.c	(original)
+++ trunk/src/connection-editor/page-mobile.c	Fri Jun 20 11:17:52 2008
@@ -247,7 +247,6 @@
 	CEPageMobile *self;
 	CEPageMobilePrivate *priv;
 	CEPage *parent;
-	NMSetting *setting;
 
 	self = CE_PAGE_MOBILE (g_object_new (CE_TYPE_PAGE_MOBILE, NULL));
 	parent = CE_PAGE (self);
@@ -272,18 +271,17 @@
 	mobile_private_init (self);
 	priv = CE_PAGE_MOBILE_GET_PRIVATE (self);
 
-	setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
-	if (!setting)
-		setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
+	priv->setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
+	if (!priv->setting)
+		priv->setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
 
-	if (!setting) {
+	if (!priv->setting) {
 		/* FIXME: Support add. */
 		g_warning ("Adding mobile conneciton not supported yet.");
 		g_object_unref (self);
 		return NULL;
 	}
 
-	priv->setting = nm_setting_duplicate (setting);
 	populate_ui (self, connection);
 
 	g_signal_connect (priv->number, "changed", G_CALLBACK (stuff_changed), self);
@@ -376,7 +374,7 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageMobile *self = CE_PAGE_MOBILE (page);
 	CEPageMobilePrivate *priv = CE_PAGE_MOBILE_GET_PRIVATE (self);
@@ -386,36 +384,11 @@
 }
 
 static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPageMobile *self = CE_PAGE_MOBILE (page);
-	CEPageMobilePrivate *priv = CE_PAGE_MOBILE_GET_PRIVATE (self);
-
-	ui_to_setting (self);
-	g_object_ref (priv->setting); /* Add setting steals the reference. */
-	nm_connection_add_setting (connection, priv->setting);
-}
-
-static void
 ce_page_mobile_init (CEPageMobile *self)
 {
 }
 
 static void
-dispose (GObject *object)
-{
-	CEPageMobilePrivate *priv = CE_PAGE_MOBILE_GET_PRIVATE (object);
-
-	if (priv->disposed)
-		return;
-
-	priv->disposed = TRUE;
-	g_object_unref (priv->setting);
-
-	G_OBJECT_CLASS (ce_page_mobile_parent_class)->dispose (object);
-}
-
-static void
 ce_page_mobile_class_init (CEPageMobileClass *mobile_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (mobile_class);
@@ -424,8 +397,5 @@
 	g_type_class_add_private (object_class, sizeof (CEPageMobilePrivate));
 
 	/* virtual methods */
-	object_class->dispose = dispose;
-
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }

Modified: trunk/src/connection-editor/page-ppp.c
==============================================================================
--- trunk/src/connection-editor/page-ppp.c	(original)
+++ trunk/src/connection-editor/page-ppp.c	Fri Jun 20 11:17:52 2008
@@ -174,7 +174,6 @@
 	CEPagePpp *self;
 	CEPagePppPrivate *priv;
 	CEPage *parent;
-	NMSettingPPP *s_ppp;
 	GtkCellRenderer *renderer;
 	gint offset;
 	GtkTreeViewColumn *column;
@@ -202,11 +201,11 @@
 	ppp_private_init (self);
 	priv = CE_PAGE_PPP_GET_PRIVATE (self);
 
-	s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
-	if (s_ppp)
-		priv->setting = NM_SETTING_PPP (nm_setting_duplicate (NM_SETTING (s_ppp)));
-	else
+	priv->setting = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
+	if (!priv->setting) {
 		priv->setting = NM_SETTING_PPP (nm_setting_ppp_new ());
+		nm_connection_add_setting (connection, NM_SETTING (priv->setting));
+	}
 
 	populate_ui (self, connection);
 
@@ -326,7 +325,7 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPagePpp *self = CE_PAGE_PPP (page);
 	CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self);
@@ -336,36 +335,11 @@
 }
 
 static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPagePpp *self = CE_PAGE_PPP (page);
-	CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self);
-
-	ui_to_setting (self);
-	g_object_ref (priv->setting); /* Add setting steals the reference. */
-	nm_connection_add_setting (connection, NM_SETTING (priv->setting));
-}
-
-static void
 ce_page_ppp_init (CEPagePpp *self)
 {
 }
 
 static void
-dispose (GObject *object)
-{
-	CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (object);
-
-	if (priv->disposed)
-		return;
-
-	priv->disposed = TRUE;
-	g_object_unref (priv->setting);
-
-	G_OBJECT_CLASS (ce_page_ppp_parent_class)->dispose (object);
-}
-
-static void
 ce_page_ppp_class_init (CEPagePppClass *ppp_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (ppp_class);
@@ -374,8 +348,5 @@
 	g_type_class_add_private (object_class, sizeof (CEPagePppPrivate));
 
 	/* virtual methods */
-	object_class->dispose = dispose;
-
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }

Modified: trunk/src/connection-editor/page-vpn.c
==============================================================================
--- trunk/src/connection-editor/page-vpn.c	(original)
+++ trunk/src/connection-editor/page-vpn.c	Fri Jun 20 11:17:52 2008
@@ -42,7 +42,6 @@
 
 typedef struct {
 	NMSettingVPN *setting;
-	NMConnection *connection; /* ugh */
 
 	NMVpnPluginUiWidgetInterface *ui;
 	gboolean valid;
@@ -67,7 +66,6 @@
 	CEPageVpn *self;
 	CEPageVpnPrivate *priv;
 	CEPage *parent;
-	NMSettingVPN *s_vpn;
 	GError *error = NULL;
 	NMVpnPluginUiInterface *plugin;
 
@@ -77,17 +75,14 @@
 
 	parent->title = g_strdup (_("VPN"));
 
-	s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
-	g_assert (s_vpn);
-	g_assert (s_vpn->service_type);
+	priv->setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+	g_assert (priv->setting);
+	g_assert (priv->setting->service_type);
 
-	priv->setting = NM_SETTING_VPN (nm_setting_duplicate (NM_SETTING (s_vpn)));
-	priv->connection = connection;
-
-	plugin = vpn_get_plugin_by_service (s_vpn->service_type);
+	plugin = vpn_get_plugin_by_service (priv->setting->service_type);
 	if (!plugin) {
 		g_warning ("%s: couldn't find VPN plugin for service '%s'!",
-		           __func__, s_vpn->service_type);
+		           __func__, priv->setting->service_type);
 		g_object_unref (self);
 		return NULL;
 	}
@@ -95,7 +90,7 @@
 	priv->ui = nm_vpn_plugin_ui_interface_ui_factory (plugin, connection, &error);
 	if (!priv->ui) {
 		g_warning ("%s: couldn't create VPN UI for service '%s': %s",
-		           __func__, s_vpn->service_type, error->message);
+		           __func__, priv->setting->service_type, error->message);
 		g_error_free (error);
 		g_object_unref (self);
 		return NULL;
@@ -116,21 +111,14 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
-{
-	CEPageVpn *self = CE_PAGE_VPN (page);
-	CEPageVpnPrivate *priv = CE_PAGE_VPN_GET_PRIVATE (self);
-
-	return priv->valid;
-}
-
-static void
-update_connection (CEPage *page, NMConnection *connection)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageVpn *self = CE_PAGE_VPN (page);
 	CEPageVpnPrivate *priv = CE_PAGE_VPN_GET_PRIVATE (self);
 
 	nm_vpn_plugin_ui_widget_interface_update_connection (priv->ui, connection);
+
+	return priv->valid;
 }
 
 static void
@@ -147,7 +135,6 @@
 		return;
 
 	priv->disposed = TRUE;
-	g_object_unref (priv->setting);
 
 	if (priv->ui)
 		g_object_unref (priv->ui);
@@ -167,5 +154,4 @@
 	object_class->dispose = dispose;
 
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }

Modified: trunk/src/connection-editor/page-wired-security.c
==============================================================================
--- trunk/src/connection-editor/page-wired-security.c	(original)
+++ trunk/src/connection-editor/page-wired-security.c	Fri Jun 20 11:17:52 2008
@@ -106,41 +106,35 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageWiredSecurityPrivate *priv = CE_PAGE_WIRED_SECURITY_GET_PRIVATE (page);
 	gboolean valid = TRUE;
 
 	if (gtk_toggle_button_get_active (priv->enabled)) {
-		/* FIXME: get failed property and error out of wireless security objects */
-		valid = wireless_security_validate (priv->security, NULL);
-		if (!valid)
-			g_set_error (error, 0, 0, "Invalid 802.1x security");
-	}
-
-	return valid;
-}
-
-static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPageWiredSecurityPrivate *priv = CE_PAGE_WIRED_SECURITY_GET_PRIVATE (page);
-
-	if (gtk_toggle_button_get_active (priv->enabled)) {
 		NMConnection *tmp_connection;
 		NMSetting *s_8021x;
 
-		/* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */
-		tmp_connection = nm_connection_new ();
-		nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ());
-		ws_802_1x_fill_connection (priv->security, "wpa_eap_auth_combo", tmp_connection);
+		/* FIXME: get failed property and error out of wireless security objects */
+		valid = wireless_security_validate (priv->security, NULL);
+		if (valid) {
+			/* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */
+			tmp_connection = nm_connection_new ();
+			nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ());
+			ws_802_1x_fill_connection (priv->security, "wpa_eap_auth_combo", tmp_connection);
 
-		s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
-		nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x)));
+			s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
+			nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x)));
 
-		g_object_unref (tmp_connection);
-	} else
+			g_object_unref (tmp_connection);
+		} else
+			g_set_error (error, 0, 0, "Invalid 802.1x security");
+	} else {
+		valid = TRUE;
 		nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
+	}
+
+	return valid;
 }
 
 static void
@@ -174,5 +168,4 @@
 	object_class->dispose = dispose;
 
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }

Modified: trunk/src/connection-editor/page-wired.c
==============================================================================
--- trunk/src/connection-editor/page-wired.c	(original)
+++ trunk/src/connection-editor/page-wired.c	Fri Jun 20 11:17:52 2008
@@ -153,7 +153,6 @@
 	CEPageWired *self;
 	CEPageWiredPrivate *priv;
 	CEPage *parent;
-	NMSettingWired *s_wired;
 	GtkWidget *widget;
 
 	self = CE_PAGE_WIRED (g_object_new (CE_TYPE_PAGE_WIRED, NULL));
@@ -179,11 +178,11 @@
 	wired_private_init (self);
 	priv = CE_PAGE_WIRED_GET_PRIVATE (self);
 
-	s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
-	if (s_wired)
-		priv->setting = NM_SETTING_WIRED (nm_setting_duplicate (NM_SETTING (s_wired)));
-	else
+	priv->setting = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	if (!priv->setting) {
 		priv->setting = NM_SETTING_WIRED (nm_setting_wired_new ());
+		nm_connection_add_setting (connection, NM_SETTING (priv->setting));
+	}
 
 	populate_ui (self);
 
@@ -274,7 +273,7 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageWired *self = CE_PAGE_WIRED (page);
 	CEPageWiredPrivate *priv = CE_PAGE_WIRED_GET_PRIVATE (self);
@@ -290,36 +289,11 @@
 }
 
 static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPageWired *self = CE_PAGE_WIRED (page);
-	CEPageWiredPrivate *priv = CE_PAGE_WIRED_GET_PRIVATE (self);
-
-	ui_to_setting (self);
-	g_object_ref (priv->setting); /* Add setting steals the reference. */
-	nm_connection_add_setting (connection, NM_SETTING (priv->setting));
-}
-
-static void
 ce_page_wired_init (CEPageWired *self)
 {
 }
 
 static void
-dispose (GObject *object)
-{
-	CEPageWiredPrivate *priv = CE_PAGE_WIRED_GET_PRIVATE (object);
-
-	if (priv->disposed)
-		return;
-
-	priv->disposed = TRUE;
-	g_object_unref (priv->setting);
-
-	G_OBJECT_CLASS (ce_page_wired_parent_class)->dispose (object);
-}
-
-static void
 ce_page_wired_class_init (CEPageWiredClass *wired_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (wired_class);
@@ -328,8 +302,5 @@
 	g_type_class_add_private (object_class, sizeof (CEPageWiredPrivate));
 
 	/* virtual methods */
-	object_class->dispose = dispose;
-
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }

Modified: trunk/src/connection-editor/page-wireless-security.c
==============================================================================
--- trunk/src/connection-editor/page-wireless-security.c	(original)
+++ trunk/src/connection-editor/page-wireless-security.c	Fri Jun 20 11:17:52 2008
@@ -166,8 +166,7 @@
 }
 
 CEPageWirelessSecurity *
-ce_page_wireless_security_new (NMConnection *connection,
-                               CEPageWireless *wireless_page)
+ce_page_wireless_security_new (NMConnection *connection)
 {
 	CEPageWirelessSecurity *self;
 	CEPage *parent;
@@ -215,8 +214,6 @@
 
 	self->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
-	self->wireless_page = g_object_ref (wireless_page);
-
 	combo = GTK_COMBO_BOX (glade_xml_get_widget (parent->xml, "wireless_security_combo"));
 
 	dev_caps =   NM_WIFI_DEVICE_CAP_CIPHER_WEP40
@@ -370,55 +367,39 @@
 	if (self->group)
 		g_object_unref (self->group);
 
-	if (self->wireless_page)
-		g_object_unref (self->wireless_page);
-
 	G_OBJECT_CLASS (ce_page_wireless_security_parent_class)->dispose (object);
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageWirelessSecurity *self = CE_PAGE_WIRELESS_SECURITY (page);
-	GByteArray *ssid;
+	NMSettingWireless *s_wireless;
 	WirelessSecurity *sec;
 	gboolean valid = FALSE;
 
-	sec = wireless_security_combo_get_active (self);
-	if (!sec)
-		return TRUE; /* Unencrypted/open method doesn't have a WirelessSecurity */
-
-	ssid = ce_page_wireless_get_ssid (self->wireless_page);
-	if (ssid) {
-		/* FIXME: get failed property and error out of wireless security objects */
-		valid = wireless_security_validate (sec, ssid);
-		if (!valid)
-			g_set_error (error, 0, 0, "Invalid wireless security");
-		g_byte_array_free (ssid, TRUE);
-	} else
-		g_set_error (error, 0, 0, "Missing SSID");
-
-	return valid;
-}
-
-static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPageWirelessSecurity *self = CE_PAGE_WIRELESS_SECURITY (page);
-	WirelessSecurity *sec;
+	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	g_assert (s_wireless);
 
 	sec = wireless_security_combo_get_active (self);
-	if (sec)
-		wireless_security_fill_connection (sec, connection);
-	else {
-		NMSettingWireless *s_wireless;
-
+	if (sec) {
+		if (s_wireless->ssid) {
+			/* FIXME: get failed property and error out of wireless security objects */
+			valid = wireless_security_validate (sec, s_wireless->ssid);
+			if (valid)
+				wireless_security_fill_connection (sec, connection);
+			else
+				g_set_error (error, 0, 0, "Invalid wireless security");
+		} else
+			g_set_error (error, 0, 0, "Missing SSID");
+	} else {
 		/* No security, unencrypted */
-		s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
-		g_assert (s_wireless);
 		g_free (s_wireless->security);
 		s_wireless->security = NULL;
+		valid = TRUE;
 	}
+
+	return valid;
 }
 
 static void
@@ -431,6 +412,4 @@
 	object_class->dispose = dispose;
 
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }
-

Modified: trunk/src/connection-editor/page-wireless-security.h
==============================================================================
--- trunk/src/connection-editor/page-wireless-security.h	(original)
+++ trunk/src/connection-editor/page-wireless-security.h	Fri Jun 20 11:17:52 2008
@@ -46,7 +46,6 @@
 	gboolean disposed;
 	GtkSizeGroup *group;
 	GtkComboBox *security_combo;
-	CEPageWireless *wireless_page;
 } CEPageWirelessSecurity;
 
 typedef struct {
@@ -55,8 +54,7 @@
 
 GType ce_page_wireless_security_get_type (void);
 
-CEPageWirelessSecurity *ce_page_wireless_security_new (NMConnection *connection,
-                                                       CEPageWireless *wireless_page);
+CEPageWirelessSecurity *ce_page_wireless_security_new (NMConnection *connection);
 
 #endif  /* __PAGE_WIRELESS_SECURITY_H__ */
 

Modified: trunk/src/connection-editor/page-wireless.c
==============================================================================
--- trunk/src/connection-editor/page-wireless.c	(original)
+++ trunk/src/connection-editor/page-wireless.c	Fri Jun 20 11:17:52 2008
@@ -294,7 +294,6 @@
 	CEPageWireless *self;
 	CEPageWirelessPrivate *priv;
 	CEPage *parent;
-	NMSettingWireless *s_wireless;
 	GtkWidget *widget;
 
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
@@ -322,11 +321,11 @@
 	wireless_private_init (self);
 	priv = CE_PAGE_WIRELESS_GET_PRIVATE (self);
 
-	s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
-	if (s_wireless)
-		priv->setting = NM_SETTING_WIRELESS (nm_setting_duplicate (NM_SETTING (s_wireless)));
-	else
+	priv->setting = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+	if (!priv->setting) {
 		priv->setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
+		nm_connection_add_setting (connection, NM_SETTING (priv->setting));
+	}
 
 	populate_ui (self);
 
@@ -428,7 +427,7 @@
 }
 
 static gboolean
-validate (CEPage *page, GError **error)
+validate (CEPage *page, NMConnection *connection, GError **error)
 {
 	CEPageWireless *self = CE_PAGE_WIRELESS (page);
 	CEPageWirelessPrivate *priv = CE_PAGE_WIRELESS_GET_PRIVATE (self);
@@ -458,34 +457,11 @@
 }
 
 static void
-update_connection (CEPage *page, NMConnection *connection)
-{
-	CEPageWirelessPrivate *priv = CE_PAGE_WIRELESS_GET_PRIVATE (page);
-
-	g_object_ref (priv->setting); /* Add setting steals the reference. */
-	nm_connection_add_setting (connection, NM_SETTING (priv->setting));
-}
-
-static void
 ce_page_wireless_init (CEPageWireless *self)
 {
 }
 
 static void
-dispose (GObject *object)
-{
-	CEPageWirelessPrivate *priv = CE_PAGE_WIRELESS_GET_PRIVATE (object);
-
-	if (priv->disposed)
-		return;
-
-	priv->disposed = TRUE;
-	g_object_unref (priv->setting);
-
-	G_OBJECT_CLASS (ce_page_wireless_parent_class)->dispose (object);
-}
-
-static void
 ce_page_wireless_class_init (CEPageWirelessClass *wireless_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (wireless_class);
@@ -494,8 +470,5 @@
 	g_type_class_add_private (object_class, sizeof (CEPageWirelessPrivate));
 
 	/* virtual methods */
-	object_class->dispose = dispose;
-
 	parent_class->validate = validate;
-	parent_class->update_connection = update_connection;
 }



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