[network-manager-applet/bond-editor: 2/4] connection-editor: add some handling for master/slave relationships



commit 6d1edce09f33bd6298e8a9905a6d471870f488d9
Author: Dan Winship <danw gnome org>
Date:   Fri Feb 24 10:14:26 2012 -0500

    connection-editor: add some handling for master/slave relationships
    
    Don't show slave connections in the main connection list (unless
    they're orphaned).
    
    Delete a connections's slaves when deleting that connection (or when
    cancelling the creation of a new connection).
    
    Don't add ip4/ip6 pages to slaves.

 src/connection-editor/nm-connection-editor.c |   62 +++++++++++++-------
 src/connection-editor/nm-connection-editor.h |    1 +
 src/connection-editor/nm-connection-list.c   |   79 ++++++++++++++++++++++++--
 3 files changed, 115 insertions(+), 27 deletions(-)
---
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index ed83fdf..d3c9f6a 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -463,6 +463,34 @@ nm_connection_editor_get (NMConnection *connection)
 	return g_hash_table_lookup (active_editors, connection);
 }
 
+/* Returns an editor for @slave's master, if any */
+NMConnectionEditor *
+nm_connection_editor_get_master (NMConnection *slave)
+{
+	GHashTableIter iter;
+	gpointer connection, editor;
+	NMSettingConnection *s_con;
+	const char *master;
+
+	if (!active_editors)
+		return NULL;
+
+	s_con = nm_connection_get_setting_connection (slave);
+	master = nm_setting_connection_get_master (s_con);
+	if (!master)
+		return NULL;
+
+	g_hash_table_iter_init (&iter, active_editors);
+	while (g_hash_table_iter_next (&iter, &connection, &editor)) {
+		if (!g_strcmp0 (master, nm_connection_get_uuid (connection)))
+			return editor;
+		if (!g_strcmp0 (master, nm_connection_get_virtual_iface_name (connection)))
+			return editor;
+	}
+
+	return NULL;
+}
+
 NMConnection *
 nm_connection_editor_get_connection (NMConnectionEditor *editor)
 {
@@ -767,6 +795,7 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor,
 	const char *connection_type;
 	gboolean success = FALSE;
 	GSList *iter, *copy;
+	gboolean add_ip4 = TRUE, add_ip6 = TRUE;
 
 	g_return_val_if_fail (NM_IS_CONNECTION_EDITOR (editor), FALSE);
 	g_return_val_if_fail (NM_IS_CONNECTION (orig_connection), FALSE);
@@ -789,24 +818,15 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor,
 			goto out;
 		if (!add_page (editor, ce_page_wired_security_new, editor->connection, error))
 			goto out;
-		if (!add_page (editor, ce_page_ip4_new, editor->connection, error))
-			goto out;
-		if (!add_page (editor, ce_page_ip6_new, editor->connection, error))
-			goto out;
 	} else if (!strcmp (connection_type, NM_SETTING_WIRELESS_SETTING_NAME)) {
 		if (!add_page (editor, ce_page_wireless_new, editor->connection, error))
 			goto out;
 		if (!add_page (editor, ce_page_wireless_security_new, editor->connection, error))
 			goto out;
-		if (!add_page (editor, ce_page_ip4_new, editor->connection, error))
-			goto out;
-		if (!add_page (editor, ce_page_ip6_new, editor->connection, error))
-			goto out;
 	} else if (!strcmp (connection_type, NM_SETTING_VPN_SETTING_NAME)) {
 		if (!add_page (editor, ce_page_vpn_new, editor->connection, error))
 			goto out;
-		if (!add_page (editor, ce_page_ip4_new, editor->connection, error))
-			goto out;
+		add_ip6 = FALSE;
 	} else if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
 		if (!add_page (editor, ce_page_dsl_new, editor->connection, error))
 			goto out;
@@ -814,34 +834,32 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor,
 			goto out;
 		if (!add_page (editor, ce_page_ppp_new, editor->connection, error))
 			goto out;
-		if (!add_page (editor, ce_page_ip4_new, editor->connection, error))
-			goto out;
+		add_ip6 = FALSE;
 	} else if (!strcmp (connection_type, NM_SETTING_GSM_SETTING_NAME) || 
 	           !strcmp (connection_type, NM_SETTING_CDMA_SETTING_NAME)) {
 		if (!add_page (editor, ce_page_mobile_new, editor->connection, error))
 			goto out;
 		if (!add_page (editor, ce_page_ppp_new, editor->connection, error))
 			goto out;
-		if (!add_page (editor, ce_page_ip4_new, editor->connection, error))
-			goto out;
+		add_ip6 = FALSE;
 	} else if (!strcmp (connection_type, NM_SETTING_WIMAX_SETTING_NAME)) {
 		if (!add_page (editor, ce_page_wimax_new, editor->connection, error))
 			goto out;
-		if (!add_page (editor, ce_page_ip4_new, editor->connection, error))
-			goto out;
-		if (!add_page (editor, ce_page_ip6_new, editor->connection, error))
-			goto out;
 	} else if (!strcmp (connection_type, NM_SETTING_INFINIBAND_SETTING_NAME)) {
 		if (!add_page (editor, ce_page_infiniband_new, editor->connection, error))
 			goto out;
-		if (!add_page (editor, ce_page_ip4_new, editor->connection, error))
-			goto out;
-		if (!add_page (editor, ce_page_ip6_new, editor->connection, error))
-			goto out;
 	} else {
 		g_warning ("Unhandled setting type '%s'", connection_type);
 	}
 
+	if (nm_setting_connection_get_master (s_con))
+		add_ip4 = add_ip6 = FALSE;
+
+	if (add_ip4 && !add_page (editor, ce_page_ip4_new, editor->connection, error))
+		goto out;
+	if (add_ip6 && !add_page (editor, ce_page_ip6_new, editor->connection, error))
+		goto out;
+
 	/* After all pages are created, then kick off secrets requests that any
 	 * the pages may need to make; if they don't need any secrets, then let
 	 * them finish initialization.  The list might get modified during the loop
diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h
index b759a31..43c7c3b 100644
--- a/src/connection-editor/nm-connection-editor.h
+++ b/src/connection-editor/nm-connection-editor.h
@@ -80,6 +80,7 @@ NMConnectionEditor *nm_connection_editor_new (GtkWindow *parent_window,
                                               NMClient *client,
                                               NMRemoteSettings *settings);
 NMConnectionEditor *nm_connection_editor_get (NMConnection *connection);
+NMConnectionEditor *nm_connection_editor_get_master (NMConnection *slave);
 
 void                nm_connection_editor_present (NMConnectionEditor *editor);
 void                nm_connection_editor_run (NMConnectionEditor *editor);
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index f0d32be..f34513a 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -237,6 +237,42 @@ update_connection_row (NMConnectionList *self,
 	gtk_tree_model_filter_refilter (self->filter);
 }
 
+static void
+delete_slaves_of_connection (NMConnectionList *list, NMConnection *connection)
+{
+	const char *uuid, *iface;
+	GtkTreeIter iter, types_iter;
+
+	if (!gtk_tree_model_get_iter_first (list->model, &types_iter))
+		return;
+
+	uuid = nm_connection_get_uuid (connection);
+	iface = nm_connection_get_virtual_iface_name (connection);
+
+	do {
+		if (!gtk_tree_model_iter_children (list->model, &iter, &types_iter))
+			continue;
+
+		do {
+			NMRemoteConnection *candidate = NULL;
+			NMSettingConnection *s_con;
+			const char *master;
+
+			gtk_tree_model_get (list->model, &iter,
+			                    COL_CONNECTION, &candidate,
+			                    -1);
+			s_con = nm_connection_get_setting_connection (NM_CONNECTION (candidate));
+			master = nm_setting_connection_get_master (s_con);
+			if (master) {
+				if (!g_strcmp0 (master, uuid) || !g_strcmp0 (master, iface))
+					nm_remote_connection_delete (candidate, NULL, NULL);
+			}
+
+			g_object_unref (candidate);
+		} while (gtk_tree_model_iter_next (list->model, &iter));
+	} while (gtk_tree_model_iter_next (list->model, &types_iter));
+}
+
 
 /**********************************************/
 /* dialog/UI handling stuff */
@@ -246,6 +282,9 @@ add_response_cb (NMConnectionEditor *editor, GtkResponseType response, gpointer
 {
 	NMConnectionList *list = user_data;
 
+	if (response == GTK_RESPONSE_CANCEL)
+		delete_slaves_of_connection (list, nm_connection_editor_get_connection (editor));
+
 	g_object_unref (editor);
 	g_signal_emit (list, list_signals[EDITING_DONE], 0, 0);
 }
@@ -331,6 +370,15 @@ do_edit (NMConnectionList *list)
 }
 
 static void
+delete_connection_cb (NMRemoteConnection *connection, gboolean deleted, gpointer user_data)
+{
+	NMConnectionList *list = user_data;
+
+	if (deleted)
+		delete_slaves_of_connection (list, NM_CONNECTION (connection));
+}
+
+static void
 delete_clicked (GtkButton *button, gpointer user_data)
 {
 	NMConnectionList *list = user_data;
@@ -339,7 +387,8 @@ delete_clicked (GtkButton *button, gpointer user_data)
 	connection = get_active_connection (list->connection_list);
 	g_return_if_fail (connection != NULL);
 
-	delete_connection (GTK_WINDOW (list->dialog), connection, NULL, NULL);
+	delete_connection (GTK_WINDOW (list->dialog), connection,
+	                   delete_connection_cb, list);
 }
 
 static void
@@ -536,16 +585,36 @@ tree_model_visible_func (GtkTreeModel *model,
                          GtkTreeIter *iter,
                          gpointer user_data)
 {
+	NMConnectionList *self = user_data;
 	NMConnection *connection;
+	NMSettingConnection *s_con;
+	const char *master;
 
 	gtk_tree_model_get (model, iter, COL_CONNECTION, &connection, -1);
-	if (connection) {
-		g_object_unref (connection);
-		return TRUE;
-	} else {
+	if (!connection) {
 		/* Top-level type nodes are visible iff they have children */
 		return gtk_tree_model_iter_has_child  (model, iter);
 	}
+
+	/* A connection node is visible unless it is a slave to another
+	 * known connection.
+	 */
+	s_con = nm_connection_get_setting_connection (connection);
+	g_object_unref (connection);
+	g_return_val_if_fail (s_con != NULL, FALSE);
+
+	master = nm_setting_connection_get_master (s_con);
+	if (!master)
+		return TRUE;
+
+	if (nm_remote_settings_get_connection_by_uuid (self->settings, master))
+		return FALSE;
+	if (nm_connection_editor_get_master (connection))
+		return FALSE;
+
+	/* FIXME: what if master is an interface name */
+
+	return TRUE;
 }
 
 static void



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