[PATCH] editor: change "Device MAC address" to combo box with an entry



The attached pached changes "Device MAC address" input entry in wired and 
wireless connections in nm-connection editor to a combo-box with entry.

The combo-box list is pre-filled with available devices' MAC for the connection 
type. Thus it is easier to restrict connections just to a particular interface 
- by selecting a value in the combo. The possibility for inserting others MACs 
is still preserved via manually typing the MAC in the entry.

Jirka
From 470587643bdb7408f601998bb3f22b3b93782e80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes redhat com>
Date: Mon, 18 Jul 2011 22:33:09 +0200
Subject: [PATCH] editor: change "Device MAC address" to combo box with an
 entry
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The combo box list is pre-filled with available MAC addresses. It makes the
input more easy. The entry still allows inserting arbitrary MAC address.

Signed-off-by: Jiří Klimeš <jklimes redhat com>
---
 src/connection-editor/ce-page-wired.ui       |    4 +-
 src/connection-editor/ce-page-wireless.ui    |    4 +-
 src/connection-editor/ce-page.h              |    2 +
 src/connection-editor/nm-connection-editor.c |   44 ++++++++++++++++++++
 src/connection-editor/page-wired.c           |   56 ++++++++++++++++++++------
 src/connection-editor/page-wireless.c        |   52 +++++++++++++++++++-----
 6 files changed, 138 insertions(+), 24 deletions(-)

diff --git a/src/connection-editor/ce-page-wired.ui b/src/connection-editor/ce-page-wired.ui
index c7ac20e..e644d40 100644
--- a/src/connection-editor/ce-page-wired.ui
+++ b/src/connection-editor/ce-page-wired.ui
@@ -175,8 +175,10 @@
           </packing>
         </child>
         <child>
-          <object class="GtkEntry" id="wired_device_mac">
+          <object class="GtkComboBoxText" id="wired_device_mac">
             <property name="visible">True</property>
+            <property name="has_entry">True</property>
+            <property name="entry_text_column">0</property>
             <property name="can_focus">True</property>
             <property name="tooltip_text" translatable="yes">This option locks this connection to the network device specified by its permanent MAC address entered here.  Example: 00:11:22:33:44:55</property>
           </object>
diff --git a/src/connection-editor/ce-page-wireless.ui b/src/connection-editor/ce-page-wireless.ui
index f7a4768..1d00bd4 100644
--- a/src/connection-editor/ce-page-wireless.ui
+++ b/src/connection-editor/ce-page-wireless.ui
@@ -117,8 +117,10 @@
           </packing>
         </child>
         <child>
-          <object class="GtkEntry" id="wireless_device_mac">
+          <object class="GtkComboBoxText" id="wireless_device_mac">
             <property name="visible">True</property>
+            <property name="has_entry">True</property>
+            <property name="entry_text_column">0</property>
             <property name="can_focus">True</property>
             <property name="tooltip_text" translatable="yes">This option locks this connection to the network device specified by its permanent MAC address entered here.  Example: 00:11:22:33:44:55</property>
           </object>
diff --git a/src/connection-editor/ce-page.h b/src/connection-editor/ce-page.h
index 5ce79c9..3e39fc3 100644
--- a/src/connection-editor/ce-page.h
+++ b/src/connection-editor/ce-page.h
@@ -54,6 +54,8 @@ typedef void (*PageNewConnectionFunc) (GtkWindow *parent,
 #define CE_PAGE_INITIALIZED   "initialized"
 #define CE_PAGE_PARENT_WINDOW "parent-window"
 
+#define CE_PAGE_MAC_LIST_TAG "mac-list"
+
 typedef struct {
 	GObject parent;
 
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 6132330..c2af773 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -45,6 +45,9 @@
 #include <nm-setting-ppp.h>
 #include <nm-setting-gsm.h>
 #include <nm-setting-cdma.h>
+#include <nm-device.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-wifi.h>
 #include <nm-utils.h>
 
 #include <nm-remote-connection.h>
@@ -671,6 +674,42 @@ get_secrets_for_page (NMConnectionEditor *self,
 	}
 }
 
+static void
+mac_list_data_to_page (CEPage *page, NMConnectionEditor *editor, gboolean wired)
+{
+	const GPtrArray *devices;
+	const char *mac, *iface;
+	GString *mac_str;
+	char **mac_list;
+	int i;
+
+	mac_str = g_string_new (NULL);
+	devices = nm_client_get_devices (editor->client);
+	for (i = 0; devices && (i < devices->len); i++) {
+		NMDevice *dev = g_ptr_array_index (devices, i);
+
+		if (!NM_IS_DEVICE_ETHERNET (dev) && !NM_IS_DEVICE_WIFI (dev))
+			continue;
+
+		if (wired && NM_IS_DEVICE_ETHERNET (dev))
+			mac = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (dev));
+		else if (!wired && NM_IS_DEVICE_WIFI (dev))
+			mac = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (dev));
+		else
+			mac = NULL;
+
+		if (mac) {
+			iface = nm_device_get_iface (NM_DEVICE (dev));
+			g_string_append_printf (mac_str, "%s (%s),", mac, iface);
+		}
+	}
+	g_string_truncate (mac_str, mac_str->len-1);
+
+	mac_list = g_strsplit (mac_str->str, ",", 0);
+	g_object_set_data_full (G_OBJECT (page), CE_PAGE_MAC_LIST_TAG, mac_list, (GDestroyNotify) g_strfreev);
+	g_string_free (mac_str, TRUE);
+}
+
 #define SECRETS_TAG "secrets-setting-name"
 
 static gboolean
@@ -693,6 +732,11 @@ add_page (NMConnectionEditor *editor,
 		                        g_strdup (secrets_setting_name),
 		                        g_free);
 
+		if (func == ce_page_wired_new)
+			mac_list_data_to_page (page, editor, TRUE);
+		if (func == ce_page_wireless_new)
+			mac_list_data_to_page (page, editor, FALSE);
+
 		editor->initializing_pages = g_slist_append (editor->initializing_pages, page);
 		g_signal_connect (page, "changed", G_CALLBACK (page_changed), editor);
 		g_signal_connect (page, "initialized", G_CALLBACK (page_initialized), editor);
diff --git a/src/connection-editor/page-wired.c b/src/connection-editor/page-wired.c
index a225ee1..4e88d77 100644
--- a/src/connection-editor/page-wired.c
+++ b/src/connection-editor/page-wired.c
@@ -17,7 +17,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2008 - 2010 Red Hat, Inc.
+ * (C) Copyright 2008 - 2011 Red Hat, Inc.
  */
 
 #include "config.h"
@@ -40,8 +40,8 @@ G_DEFINE_TYPE (CEPageWired, ce_page_wired, CE_TYPE_PAGE)
 typedef struct {
 	NMSettingWired *setting;
 
-	GtkEntry *device_mac;  /* Permanent MAC of the device */
-	GtkEntry *cloned_mac;  /* Cloned MAC - used for MAC spoofing */
+	GtkComboBoxText *device_mac;  /* Permanent MAC of the device */
+	GtkEntry *cloned_mac;         /* Cloned MAC - used for MAC spoofing */
 	GtkComboBox *port;
 	GtkComboBox *speed;
 	GtkToggleButton *duplex;
@@ -71,7 +71,7 @@ wired_private_init (CEPageWired *self)
 
 	builder = CE_PAGE (self)->builder;
 
-	priv->device_mac = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wired_device_mac")));
+	priv->device_mac = GTK_COMBO_BOX_TEXT (GTK_WIDGET (gtk_builder_get_object (builder, "wired_device_mac")));
 	priv->cloned_mac = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wired_cloned_mac")));
 	priv->port = GTK_COMBO_BOX (GTK_WIDGET (gtk_builder_get_object (builder, "wired_port")));
 	priv->speed = GTK_COMBO_BOX (GTK_WIDGET (gtk_builder_get_object (builder, "wired_speed")));
@@ -96,6 +96,11 @@ populate_ui (CEPageWired *self)
 	int port_idx = PORT_DEFAULT;
 	int speed_idx;
 	int mtu_def;
+	char **mac_list, **iter;
+	const GByteArray *s_mac;
+	char *s_mac_str;
+	char *active_mac = NULL;
+	GtkWidget *entry;
 
 	/* Port */
 	port = nm_setting_wired_get_port (setting);
@@ -143,7 +148,27 @@ populate_ui (CEPageWired *self)
 	                              nm_setting_wired_get_auto_negotiate (setting));
 
 	/* Device MAC address */
-	ce_page_mac_to_entry (nm_setting_wired_get_mac_address (setting), priv->device_mac);
+	mac_list = g_object_get_data (G_OBJECT (self), CE_PAGE_MAC_LIST_TAG);
+	s_mac = nm_setting_wired_get_mac_address (setting);
+	s_mac_str = s_mac ? g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+	                                     s_mac->data[0], s_mac->data[1], s_mac->data[2],
+	                                     s_mac->data[3], s_mac->data[4], s_mac->data[5]):
+	                    NULL;
+
+	for (iter = mac_list; iter && *iter; iter++) {
+		gtk_combo_box_text_append_text (priv->device_mac, *iter);
+		if (s_mac_str && g_ascii_strncasecmp (*iter, s_mac_str, 17) == 0)
+			active_mac = *iter;
+	}
+
+	if (s_mac_str) {
+		if (!active_mac)
+			gtk_combo_box_text_prepend_text (priv->device_mac, s_mac_str);
+
+		entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
+		if (entry)
+			gtk_entry_set_text (GTK_ENTRY (entry), active_mac ? active_mac : s_mac_str);
+	}
 	g_signal_connect (priv->device_mac, "changed", G_CALLBACK (stuff_changed), self);
 
 	/* Cloned MAC address */
@@ -236,6 +261,7 @@ ui_to_setting (CEPageWired *self)
 	guint32 speed;
 	GByteArray *device_mac = NULL;
 	GByteArray *cloned_mac = NULL;
+	GtkWidget *entry;
 
 	/* Port */
 	switch (gtk_combo_box_get_active (priv->port)) {
@@ -275,7 +301,9 @@ ui_to_setting (CEPageWired *self)
 		break;
 	}
 
-	device_mac = ce_page_entry_to_mac (priv->device_mac, NULL);
+	entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
+	if (entry)
+		device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), NULL);
 	cloned_mac = ce_page_entry_to_mac (priv->cloned_mac, NULL);
 
 	g_object_set (priv->setting,
@@ -302,12 +330,16 @@ validate (CEPage *page, NMConnection *connection, GError **error)
 	CEPageWiredPrivate *priv = CE_PAGE_WIRED_GET_PRIVATE (self);
 	gboolean invalid = FALSE;
 	GByteArray *ignore;
-
-	ignore = ce_page_entry_to_mac (priv->device_mac, &invalid);
-	if (invalid)
-		return FALSE;
-	if (ignore)
-		g_byte_array_free (ignore, TRUE);
+	GtkWidget *entry;
+
+	entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
+	if (entry) {
+		ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), &invalid);
+		if (invalid)
+			return FALSE;
+		if (ignore)
+			g_byte_array_free (ignore, TRUE);
+	}
 
 	ignore = ce_page_entry_to_mac (priv->cloned_mac, &invalid);
 	if (invalid)
diff --git a/src/connection-editor/page-wireless.c b/src/connection-editor/page-wireless.c
index d9c39a8..ffe62ed 100644
--- a/src/connection-editor/page-wireless.c
+++ b/src/connection-editor/page-wireless.c
@@ -43,8 +43,8 @@ typedef struct {
 
 	GtkEntry *ssid;
 	GtkEntry *bssid;
-	GtkEntry *device_mac;    /* Permanent MAC of the device */
-	GtkEntry *cloned_mac;    /* Cloned MAC - used for MAC spoofing */
+	GtkComboBoxText *device_mac;  /* Permanent MAC of the device */
+	GtkEntry *cloned_mac;         /* Cloned MAC - used for MAC spoofing */
 	GtkComboBox *mode;
 	GtkComboBox *band;
 	GtkSpinButton *channel;
@@ -71,7 +71,7 @@ wireless_private_init (CEPageWireless *self)
 
 	priv->ssid     = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wireless_ssid")));
 	priv->bssid    = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wireless_bssid")));
-	priv->device_mac = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wireless_device_mac")));
+	priv->device_mac = GTK_COMBO_BOX_TEXT (GTK_WIDGET (gtk_builder_get_object (builder, "wireless_device_mac")));
 	priv->cloned_mac = GTK_ENTRY (GTK_WIDGET (gtk_builder_get_object (builder, "wireless_cloned_mac")));
 	priv->mode     = GTK_COMBO_BOX (GTK_WIDGET (gtk_builder_get_object (builder, "wireless_mode")));
 	priv->band     = GTK_COMBO_BOX (GTK_WIDGET (gtk_builder_get_object (builder, "wireless_band")));
@@ -269,6 +269,11 @@ populate_ui (CEPageWireless *self)
 	int tx_power_def;
 	int mtu_def;
 	char *utf8_ssid;
+	char **mac_list, **iter;
+	const GByteArray *s_mac;
+	char *s_mac_str;
+	char *active_mac = NULL;
+	GtkWidget *entry;
 
 	rate_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRELESS_RATE);
 	g_signal_connect (priv->rate, "output",
@@ -343,7 +348,27 @@ populate_ui (CEPageWireless *self)
 	g_signal_connect_swapped (priv->bssid, "changed", G_CALLBACK (ce_page_changed), self);
 
 	/* Device MAC address */
-	ce_page_mac_to_entry (nm_setting_wireless_get_mac_address (setting), priv->device_mac);
+	mac_list = g_object_get_data (G_OBJECT (self), CE_PAGE_MAC_LIST_TAG);
+	s_mac = nm_setting_wireless_get_mac_address (setting);
+	s_mac_str = s_mac ? g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+	                                     s_mac->data[0], s_mac->data[1], s_mac->data[2],
+	                                     s_mac->data[3], s_mac->data[4], s_mac->data[5]):
+	                    NULL;
+
+	for (iter = mac_list; iter && *iter; iter++) {
+		gtk_combo_box_text_append_text (priv->device_mac, *iter);
+		if (s_mac_str && g_ascii_strncasecmp (*iter, s_mac_str, 17) == 0)
+			active_mac = *iter;
+	}
+
+	if (s_mac_str) {
+		if (!active_mac)
+			gtk_combo_box_text_prepend_text (priv->device_mac, s_mac_str);
+
+		entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
+		if (entry)
+			gtk_entry_set_text (GTK_ENTRY (entry), active_mac ? active_mac : s_mac_str);
+	}
 	g_signal_connect_swapped (priv->device_mac, "changed", G_CALLBACK (ce_page_changed), self);
 
 	/* Cloned MAC address */
@@ -443,6 +468,7 @@ ui_to_setting (CEPageWireless *self)
 	GByteArray *cloned_mac = NULL;
 	const char *mode;
 	const char *band;
+	GtkWidget *entry;
 
 	ssid = ce_page_wireless_get_ssid (self);
 
@@ -465,7 +491,9 @@ ui_to_setting (CEPageWireless *self)
 	}
 
 	bssid = ce_page_entry_to_mac (priv->bssid, NULL);
-	device_mac = ce_page_entry_to_mac (priv->device_mac, NULL);
+	entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
+	if (entry)
+		device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), NULL);
 	cloned_mac = ce_page_entry_to_mac (priv->cloned_mac, NULL);
 
 	g_object_set (priv->setting,
@@ -500,6 +528,7 @@ validate (CEPage *page, NMConnection *connection, GError **error)
 	gboolean success;
 	gboolean invalid = FALSE;
 	GByteArray *ignore;
+	GtkWidget *entry;
 
 	ignore = ce_page_entry_to_mac (priv->bssid, &invalid);
 	if (invalid)
@@ -507,11 +536,14 @@ validate (CEPage *page, NMConnection *connection, GError **error)
 	if (ignore)
 		g_byte_array_free (ignore, TRUE);
 
-	ignore = ce_page_entry_to_mac (priv->device_mac, &invalid);
-	if (invalid)
-		return FALSE;
-	if (ignore)
-		g_byte_array_free (ignore, TRUE);
+	entry = gtk_bin_get_child (GTK_BIN (priv->device_mac));
+	if (entry) {
+		ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), &invalid);
+		if (invalid)
+			return FALSE;
+		if (ignore)
+			g_byte_array_free (ignore, TRUE);
+	}
 
 	ignore = ce_page_entry_to_mac (priv->cloned_mac, &invalid);
 	if (invalid)
-- 
1.7.6



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