[network-manager-applet/bg/cloned-mac] editor: improve the cloned MAC address selection



commit 3fd590ad47a3b5419511b9f2e02690f877cf4a9d
Author: Beniamino Galvani <bgalvani redhat com>
Date:   Fri Nov 11 10:21:42 2016 +0100

    editor: improve the cloned MAC address selection
    
    Add a combo box with text entry that accepts a MAC address and also
    the selection of one of the predefined special values.

 src/connection-editor/ce-page-ethernet.ui |   12 ++++-
 src/connection-editor/ce-page-vlan.ui     |   13 ++++--
 src/connection-editor/ce-page-wifi.ui     |   12 ++++-
 src/connection-editor/ce-page.c           |   74 +++++++++++++++++++++++++++++
 src/connection-editor/ce-page.h           |    3 +
 src/connection-editor/page-ethernet.c     |   11 ++--
 src/connection-editor/page-vlan.c         |   15 +++---
 src/connection-editor/page-wifi.c         |   11 ++--
 8 files changed, 122 insertions(+), 29 deletions(-)
---
diff --git a/src/connection-editor/ce-page-ethernet.ui b/src/connection-editor/ce-page-ethernet.ui
index 6b20a07..5d19756 100644
--- a/src/connection-editor/ce-page-ethernet.ui
+++ b/src/connection-editor/ce-page-ethernet.ui
@@ -210,10 +210,16 @@
       </packing>
     </child>
     <child>
-      <object class="GtkEntry" id="ethernet_cloned_mac">
+      <object class="GtkComboBoxText" id="ethernet_cloned_mac">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="tooltip_text" translatable="yes">The MAC address entered here will be used as 
hardware address for the network device this connection is activated on. This feature is known as MAC cloning 
or spoofing. Example: 00:11:22:33:44:55</property>
+        <property name="can_focus">False</property>
+        <property name="has_entry">True</property>
+        <property name="active_id">0</property>
+        <child internal-child="entry">
+          <object class="GtkEntry">
+            <property name="can_focus">True</property>
+          </object>
+        </child>
       </object>
       <packing>
         <property name="left_attach">1</property>
diff --git a/src/connection-editor/ce-page-vlan.ui b/src/connection-editor/ce-page-vlan.ui
index 9027353..86799cd 100644
--- a/src/connection-editor/ce-page-vlan.ui
+++ b/src/connection-editor/ce-page-vlan.ui
@@ -65,11 +65,16 @@
       </packing>
     </child>
     <child>
-      <object class="GtkEntry" id="vlan_cloned_mac_entry">
+      <object class="GtkComboBoxText" id="vlan_cloned_mac_entry">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="invisible_char">●</property>
-        <property name="invisible_char_set">True</property>
+        <property name="can_focus">False</property>
+        <property name="has_entry">True</property>
+        <property name="active_id">0</property>
+        <child internal-child="entry">
+          <object class="GtkEntry">
+            <property name="can_focus">True</property>
+          </object>
+        </child>
       </object>
       <packing>
         <property name="left_attach">1</property>
diff --git a/src/connection-editor/ce-page-wifi.ui b/src/connection-editor/ce-page-wifi.ui
index f91e1f0..4116c21 100644
--- a/src/connection-editor/ce-page-wifi.ui
+++ b/src/connection-editor/ce-page-wifi.ui
@@ -152,10 +152,16 @@
       </packing>
     </child>
     <child>
-      <object class="GtkEntry" id="wifi_cloned_mac">
+      <object class="GtkComboBoxText" id="wifi_cloned_mac">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="tooltip_text" translatable="yes">The MAC address entered here will be used as 
hardware address for the network device this connection is activated on. This feature is known as MAC cloning 
or spoofing. Example: 00:11:22:33:44:55</property>
+        <property name="can_focus">False</property>
+        <property name="has_entry">True</property>
+        <property name="active_id">0</property>
+        <child internal-child="entry">
+          <object class="GtkEntry">
+            <property name="can_focus">True</property>
+          </object>
+        </child>
       </object>
       <packing>
         <property name="left_attach">1</property>
diff --git a/src/connection-editor/ce-page.c b/src/connection-editor/ce-page.c
index 4b17fde..76699f3 100644
--- a/src/connection-editor/ce-page.c
+++ b/src/connection-editor/ce-page.c
@@ -287,6 +287,80 @@ ce_page_setup_mac_combo (CEPage *self, GtkComboBox *combo,
        _set_active_combo_item (combo, mac, active_mac, active_idx);
 }
 
+void
+ce_page_init_cloned_mac_combo (GtkComboBoxText *combo, const char *current)
+{
+       GtkWidget *entry;
+       static const char *entries[][2] = { { "preserve",  N_("Preserve") },
+                                           { "permanent", N_("Permanent") },
+                                           { "random",    N_("Random") },
+                                           { "stable",    N_("Stable") } };
+       int i, active = -1;
+
+       gtk_widget_set_tooltip_text (GTK_WIDGET (combo),
+               _("The MAC address entered here will be used as hardware address for "
+                 "the network device this connection is activated on. This feature is "
+                 "known as MAC cloning or spoofing. Example: 00:11:22:33:44:55"));
+
+       gtk_combo_box_text_remove_all (combo);
+
+       for (i = 0; i < G_N_ELEMENTS (entries); i++) {
+               gtk_combo_box_text_append (combo, entries[i][0], _(entries[i][1]));
+               if (nm_streq0 (current, entries[i][0]))
+                       active = i;
+       }
+
+       if (active != -1) {
+               gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
+       } else if (current && current[0]) {
+               entry = gtk_bin_get_child (GTK_BIN (combo));
+               g_assert (entry);
+               gtk_entry_set_text (GTK_ENTRY (entry), current);
+       }
+}
+
+const char *
+ce_page_cloned_mac_get (GtkComboBoxText *combo)
+{
+       const char *id;
+
+       id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo));
+       if (id)
+               return id;
+
+       return gtk_combo_box_text_get_active_text (combo);
+}
+
+gboolean
+ce_page_cloned_mac_combo_valid (GtkComboBoxText *combo, int type, const char *property_name, GError **error)
+{
+       const char *mac;
+
+       if (gtk_combo_box_get_active (GTK_COMBO_BOX (combo)) != -1)
+               return TRUE;
+
+       mac = gtk_combo_box_text_get_active_text (combo);
+       if (mac && *mac) {
+               if (!nm_utils_hwaddr_valid (mac, nm_utils_hwaddr_len (type))) {
+                       const char *addr_type;
+
+                       addr_type = type == ARPHRD_ETHER ? _("MAC address") : _("HW address");
+                       if (property_name) {
+                               g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC,
+                                            _("invalid %s for %s (%s)"),
+                                            addr_type, property_name, mac);
+                       } else {
+                               g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC,
+                                            _("invalid %s (%s)"),
+                                            addr_type, mac);
+                       }
+                       return FALSE;
+               }
+       }
+
+       return TRUE;
+}
+
 gboolean
 ce_page_mac_entry_valid (GtkEntry *entry, int type, const char *property_name, GError **error)
 {
diff --git a/src/connection-editor/ce-page.h b/src/connection-editor/ce-page.h
index f375ed4..2d635a9 100644
--- a/src/connection-editor/ce-page.h
+++ b/src/connection-editor/ce-page.h
@@ -128,6 +128,7 @@ void ce_page_setup_mac_combo (CEPage *self, GtkComboBox *combo,
                               const char *mac, char **mac_list);
 void ce_page_setup_data_combo (CEPage *self, GtkComboBox *combo,
                                const char *data, char **list);
+void ce_page_init_cloned_mac_combo (GtkComboBoxText *combo, const char *current);
 void ce_page_setup_device_combo (CEPage *self,
                                  GtkComboBox *combo,
                                  GType device_type,
@@ -142,6 +143,8 @@ gboolean ce_page_device_entry_get (GtkEntry *entry, int type,
                                    char **ifname, char **mac,
                                    const char *device_name,
                                    GError **error);
+const char *ce_page_cloned_mac_get (GtkComboBoxText *combo);
+gboolean ce_page_cloned_mac_combo_valid (GtkComboBoxText *combo, int type, const char *property_name, GError 
**error);
 
 void ce_page_changed (CEPage *self);
 
diff --git a/src/connection-editor/page-ethernet.c b/src/connection-editor/page-ethernet.c
index 54b0353..0031e40 100644
--- a/src/connection-editor/page-ethernet.c
+++ b/src/connection-editor/page-ethernet.c
@@ -35,7 +35,7 @@ typedef struct {
        NMSettingWired *setting;
 
        GtkComboBoxText *device_combo; /* Device identification (ifname and/or MAC) */
-       GtkEntry *cloned_mac;          /* Cloned MAC - used for MAC spoofing */
+       GtkComboBoxText *cloned_mac;          /* Cloned MAC - used for MAC spoofing */
        GtkComboBox *port;
        GtkComboBox *speed;
        GtkToggleButton *duplex;
@@ -84,7 +84,7 @@ ethernet_private_init (CEPageEthernet *self)
        label = GTK_LABEL (gtk_builder_get_object (builder, "ethernet_device_label"));
        gtk_label_set_mnemonic_widget (label, GTK_WIDGET (priv->device_combo));
 
-       priv->cloned_mac = GTK_ENTRY (gtk_builder_get_object (builder, "ethernet_cloned_mac"));
+       priv->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "ethernet_cloned_mac"));
        priv->port = GTK_COMBO_BOX (gtk_builder_get_object (builder, "ethernet_port"));
        priv->speed = GTK_COMBO_BOX (gtk_builder_get_object (builder, "ethernet_speed"));
        priv->duplex = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ethernet_duplex"));
@@ -218,8 +218,7 @@ populate_ui (CEPageEthernet *self)
 
        /* Cloned MAC address */
        s_mac = nm_setting_wired_get_cloned_mac_address (setting);
-       if (s_mac)
-               gtk_entry_set_text (priv->cloned_mac, s_mac);
+       ce_page_init_cloned_mac_combo (priv->cloned_mac, s_mac);
        g_signal_connect (priv->cloned_mac, "changed", G_CALLBACK (stuff_changed), self);
 
        /* MTU */
@@ -399,7 +398,7 @@ ui_to_setting (CEPageEthernet *self)
        entry = gtk_bin_get_child (GTK_BIN (priv->device_combo));
        if (entry)
                ce_page_device_entry_get (GTK_ENTRY (entry), ARPHRD_ETHER, TRUE, &ifname, &device_mac, NULL, 
NULL);
-       cloned_mac = gtk_entry_get_text (priv->cloned_mac);
+       cloned_mac = ce_page_cloned_mac_get (priv->cloned_mac);
 
        /* Wake-on-LAN */
        if (gtk_toggle_button_get_active (priv->wol_default))
@@ -456,7 +455,7 @@ ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
                        return FALSE;
        }
 
-       if (!ce_page_mac_entry_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
+       if (!ce_page_cloned_mac_combo_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
                return FALSE;
 
        if (gtk_widget_get_sensitive (GTK_WIDGET (priv->wol_passwd))) {
diff --git a/src/connection-editor/page-vlan.c b/src/connection-editor/page-vlan.c
index ef39a7d..b7a8f36 100644
--- a/src/connection-editor/page-vlan.c
+++ b/src/connection-editor/page-vlan.c
@@ -52,7 +52,7 @@ typedef struct {
        GtkEntry *parent_entry;
        GtkSpinButton *id_entry;
        GtkEntry *name_entry;
-       GtkEntry *cloned_mac;
+       GtkComboBoxText *cloned_mac;
        GtkSpinButton *mtu;
        GtkToggleButton *flag_reorder_hdr, *flag_gvrp, *flag_loose_binding, *flag_mvrp;
 
@@ -84,7 +84,7 @@ vlan_private_init (CEPageVlan *self)
 
        priv->id_entry = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "vlan_id_entry"));
        priv->name_entry = GTK_ENTRY (gtk_builder_get_object (builder, "vlan_name_entry"));
-       priv->cloned_mac = GTK_ENTRY (gtk_builder_get_object (builder, "vlan_cloned_mac_entry"));
+       priv->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "vlan_cloned_mac_entry"));
        priv->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "vlan_mtu"));
        priv->flag_reorder_hdr = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "reorder_hdr_flag"));
        priv->flag_gvrp = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "gvrp_flag"));
@@ -284,7 +284,7 @@ parent_changed (GtkWidget *widget, gpointer user_data)
                gtk_widget_set_sensitive (GTK_WIDGET (priv->mtu), TRUE);
        } else {
                gtk_widget_set_sensitive (GTK_WIDGET (priv->cloned_mac), FALSE);
-               gtk_entry_set_text (priv->cloned_mac, "");
+               ce_page_init_cloned_mac_combo (priv->cloned_mac, NULL);
                gtk_widget_set_sensitive (GTK_WIDGET (priv->mtu), FALSE);
                gtk_spin_button_set_value (priv->mtu, 1500);
        }
@@ -531,8 +531,9 @@ populate_ui (CEPageVlan *self)
        /* Cloned MAC address */
        if (NM_IS_SETTING_WIRED (priv->s_hw)) {
                const char *mac = nm_setting_wired_get_cloned_mac_address (NM_SETTING_WIRED (priv->s_hw));
-               if (mac)
-                       gtk_entry_set_text (priv->cloned_mac, mac);
+               ce_page_init_cloned_mac_combo (priv->cloned_mac, mac);
+       } else {
+               ce_page_init_cloned_mac_combo (priv->cloned_mac, NULL);
        }
        g_signal_connect (priv->cloned_mac, "changed", G_CALLBACK (stuff_changed), self);
 
@@ -692,7 +693,7 @@ ui_to_setting (CEPageVlan *self)
                      NULL);
 
        if (hwtype != G_TYPE_NONE) {
-               cloned_mac = gtk_entry_get_text (priv->cloned_mac);
+               cloned_mac = ce_page_cloned_mac_get (priv->cloned_mac);
                if (cloned_mac && !*cloned_mac)
                        cloned_mac = NULL;
                mtu_set = g_ascii_isdigit (*gtk_entry_get_text (GTK_ENTRY (priv->mtu)));
@@ -736,7 +737,7 @@ ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
                g_free (parent_iface);
        }
 
-       if (!ce_page_mac_entry_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
+       if (!ce_page_cloned_mac_combo_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
                return FALSE;
 
        ui_to_setting (self);
diff --git a/src/connection-editor/page-wifi.c b/src/connection-editor/page-wifi.c
index 8f7c6c1..d188786 100644
--- a/src/connection-editor/page-wifi.c
+++ b/src/connection-editor/page-wifi.c
@@ -38,7 +38,7 @@ typedef struct {
        GtkEntry *ssid;
        GtkComboBoxText *bssid;
        GtkComboBoxText *device_combo; /* Device identification (ifname and/or MAC) */
-       GtkEntry *cloned_mac;          /* Cloned MAC - used for MAC spoofing */
+       GtkComboBoxText *cloned_mac;          /* Cloned MAC - used for MAC spoofing */
        GtkComboBox *mode;
        GtkComboBox *band;
        GtkSpinButton *channel;
@@ -65,7 +65,7 @@ wifi_private_init (CEPageWifi *self)
        priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
        priv->ssid     = GTK_ENTRY (gtk_builder_get_object (builder, "wifi_ssid"));
-       priv->cloned_mac = GTK_ENTRY (gtk_builder_get_object (builder, "wifi_cloned_mac"));
+       priv->cloned_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "wifi_cloned_mac"));
        priv->mode     = GTK_COMBO_BOX (gtk_builder_get_object (builder, "wifi_mode"));
        priv->band     = GTK_COMBO_BOX (gtk_builder_get_object (builder, "wifi_band"));
        priv->channel  = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "wifi_channel"));
@@ -387,8 +387,7 @@ populate_ui (CEPageWifi *self)
 
        /* Cloned MAC address */
        s_mac = nm_setting_wireless_get_cloned_mac_address (setting);
-       if (s_mac)
-               gtk_entry_set_text (priv->cloned_mac, s_mac);
+       ce_page_init_cloned_mac_combo (priv->cloned_mac, s_mac);
        g_signal_connect_swapped (priv->cloned_mac, "changed", G_CALLBACK (ce_page_changed), self);
 
        gtk_spin_button_set_value (priv->rate, (gdouble) nm_setting_wireless_get_rate (setting));
@@ -528,7 +527,7 @@ ui_to_setting (CEPageWifi *self)
        entry = gtk_bin_get_child (GTK_BIN (priv->device_combo));
        if (entry)
                ce_page_device_entry_get (GTK_ENTRY (entry), ARPHRD_ETHER, TRUE, &ifname, &device_mac, NULL, 
NULL);
-       cloned_mac = gtk_entry_get_text (priv->cloned_mac);
+       cloned_mac = ce_page_cloned_mac_get (priv->cloned_mac);
 
        g_object_set (s_con,
                      NM_SETTING_CONNECTION_INTERFACE_NAME, ifname,
@@ -571,7 +570,7 @@ ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
                        return FALSE;
        }
 
-       if (!ce_page_mac_entry_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
+       if (!ce_page_cloned_mac_combo_valid (priv->cloned_mac, ARPHRD_ETHER, _("cloned MAC"), error))
                return FALSE;
 
        ui_to_setting (self);


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