[network-manager-applet/jk/editor-interface-name-rh1139536: 2/2] editor: let users edit connection.interface-name property (rh #1139536)



commit 929ac8f3eef77c7748ac1908748bc3d835b631ad
Author: Jiří Klimeš <jklimes redhat com>
Date:   Mon Mar 16 12:23:52 2015 +0100

    editor: let users edit connection.interface-name property (rh #1139536)
    
    Let user lock connection to an interface name for Ethernet, Wi-Fi, WiMAX,
    PPPoE, InfiniBand and mobile broadband connections. It is more convenient
    than MAC address now that interface names are stable.
    For virtual connections, interface name entry is already on a corresponding
    page (like bond, bridge, etc.) because it is mandatory.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1139536

 src/connection-editor/ce-page-general.ui |   40 ++++++++++++++++++-
 src/connection-editor/ce-page.c          |   41 ++++++++++++++-----
 src/connection-editor/ce-page.h          |    3 +-
 src/connection-editor/page-general.c     |   64 ++++++++++++++++++++++++++++++
 4 files changed, 135 insertions(+), 13 deletions(-)
---
diff --git a/src/connection-editor/ce-page-general.ui b/src/connection-editor/ce-page-general.ui
index 1053ec5..96477f3 100644
--- a/src/connection-editor/ce-page-general.ui
+++ b/src/connection-editor/ce-page-general.ui
@@ -89,7 +89,6 @@
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="valign">start</property>
-        <property name="vexpand">True</property>
         <property name="spacing">6</property>
         <child>
           <object class="GtkLabel" id="firewall_zone_label">
@@ -123,5 +122,44 @@
         <property name="top_attach">4</property>
       </packing>
     </child>
+    <child>
+      <object class="GtkBox" id="box3">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="valign">start</property>
+        <property name="margin_top">12</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkLabel" id="interface_name_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">0</property>
+            <property name="label" translatable="yes">_Interface name:</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkAlignment" id="interface_name_alignment">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">5</property>
+      </packing>
+    </child>
   </object>
 </interface>
diff --git a/src/connection-editor/ce-page.c b/src/connection-editor/ce-page.c
index 51adee6..1a2911f 100644
--- a/src/connection-editor/ce-page.c
+++ b/src/connection-editor/ce-page.c
@@ -134,11 +134,13 @@ ce_page_validate (CEPage *self, NMConnection *connection, GError **error)
        return TRUE;
 }
 
-char **
-ce_page_get_mac_list (CEPage *self, GType device_type, const char *mac_property)
+static char **
+ce_page_get_interfaces (CEPage *self,
+                        GType device_type,
+                        const char *property)
 {
        const GPtrArray *devices;
-       GPtrArray *macs;
+       GPtrArray *interfaces;
        int i;
 
        g_return_val_if_fail (CE_IS_PAGE (self), NULL);
@@ -146,25 +148,42 @@ ce_page_get_mac_list (CEPage *self, GType device_type, const char *mac_property)
        if (!self->client)
                return NULL;
 
-       macs = g_ptr_array_new ();
+       interfaces = g_ptr_array_new ();
        devices = nm_client_get_devices (self->client);
        for (i = 0; i < devices->len; i++) {
                NMDevice *dev = g_ptr_array_index (devices, i);
                const char *iface;
-               char *mac, *item;
+               char *item;
 
                if (!G_TYPE_CHECK_INSTANCE_TYPE (dev, device_type))
                        continue;
 
-               g_object_get (G_OBJECT (dev), mac_property, &mac, NULL);
                iface = nm_device_get_iface (NM_DEVICE (dev));
-               item = g_strdup_printf ("%s (%s)", mac, iface);
-               g_free (mac);
-               g_ptr_array_add (macs, item);
+               if (!property)
+                       item = g_strdup (iface);
+               else {
+                       char *mac;
+                       g_object_get (G_OBJECT (dev), property, &mac, NULL);
+                       item = g_strdup_printf ("%s (%s)", mac, iface);
+                       g_free (mac);
+               }
+               g_ptr_array_add (interfaces, item);
        }
 
-       g_ptr_array_add (macs, NULL);
-       return (char **)g_ptr_array_free (macs, FALSE);
+       g_ptr_array_add (interfaces, NULL);
+       return (char **)g_ptr_array_free (interfaces, FALSE);
+}
+
+char **
+ce_page_get_mac_list (CEPage *self, GType device_type, const char *mac_property)
+{
+       return ce_page_get_interfaces (self, device_type, mac_property);
+}
+
+char **
+ce_page_get_ifname_list (CEPage *self, GType device_type)
+{
+       return ce_page_get_interfaces (self, device_type, NULL);
 }
 
 void
diff --git a/src/connection-editor/ce-page.h b/src/connection-editor/ce-page.h
index 66e317d..d49b874 100644
--- a/src/connection-editor/ce-page.h
+++ b/src/connection-editor/ce-page.h
@@ -101,7 +101,8 @@ const char * ce_page_get_title (CEPage *self);
 
 gboolean ce_page_validate (CEPage *self, NMConnection *connection, GError **error);
 
-char **ce_page_get_mac_list (CEPage *self, GType device_type, const char *mac_property);
+char **ce_page_get_mac_list    (CEPage *self, GType device_type, const char *mac_property);
+char **ce_page_get_ifname_list (CEPage *self, GType device_type);
 void ce_page_setup_mac_combo (CEPage *self, GtkComboBox *combo,
                               const char *current_mac, char **mac_list);
 
diff --git a/src/connection-editor/page-general.c b/src/connection-editor/page-general.c
index e0ad470..f1d79be 100644
--- a/src/connection-editor/page-general.c
+++ b/src/connection-editor/page-general.c
@@ -48,6 +48,8 @@ typedef struct {
        GtkWidget *autoconnect;
        GtkWidget *all_checkbutton;
 
+       GtkComboBoxText *ifname;
+
        gboolean setup_finished;
 } CEPageGeneralPrivate;
 
@@ -170,6 +172,19 @@ general_private_init (CEPageGeneral *self)
 
        priv->autoconnect = GTK_WIDGET (gtk_builder_get_object (builder, "connection_autoconnect"));
        priv->all_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "system_checkbutton"));
+
+       /* Interface name */
+       priv->ifname = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new_with_entry ());
+       gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (priv->ifname), 0);
+       gtk_widget_set_tooltip_text (GTK_WIDGET (priv->ifname),
+                                    _("Interface name locks this connection to the network device."));
+
+       align = GTK_WIDGET (gtk_builder_get_object (builder, "interface_name_alignment"));
+       gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (priv->ifname));
+       gtk_widget_show_all (GTK_WIDGET (priv->ifname));
+
+       label = GTK_LABEL (gtk_builder_get_object (builder, "interface_name_label"));
+       gtk_label_set_mnemonic_widget (label, GTK_WIDGET (priv->ifname));
 }
 
 static void
@@ -242,6 +257,30 @@ populate_firewall_zones_ui (CEPageGeneral *self)
        stuff_changed (NULL, self);
 }
 
+static GType
+get_device_type (CEPageGeneral *self)
+{
+       const char *ctype;
+       GType type = G_TYPE_INVALID;
+
+       ctype = nm_connection_get_connection_type (CE_PAGE (self)->connection);
+
+       if (   strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME) == 0
+           || strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME) == 0)
+               type = NM_TYPE_DEVICE_ETHERNET;
+       else if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) == 0)
+               type = NM_TYPE_DEVICE_WIFI;
+       else if (strcmp (ctype, NM_SETTING_WIMAX_SETTING_NAME) == 0)
+               type = NM_TYPE_DEVICE_WIMAX;
+       else if (strcmp (ctype, NM_SETTING_INFINIBAND_SETTING_NAME) == 0)
+               type = NM_TYPE_DEVICE_INFINIBAND;
+       else if (   strcmp (ctype, NM_SETTING_GSM_SETTING_NAME) == 0
+                || strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME) == 0)
+               type = NM_TYPE_DEVICE_MODEM;
+
+       return type;
+}
+
 static void
 populate_ui (CEPageGeneral *self)
 {
@@ -253,6 +292,8 @@ populate_ui (CEPageGeneral *self)
        int i;
        GtkTreeIter iter;
        gboolean global_connection = TRUE;
+       char **ifname_list;
+       const char *s_ifname_str;
 
        /* Zones are filled when got them from firewalld */
        if (priv->got_zones)
@@ -302,6 +343,21 @@ populate_ui (CEPageGeneral *self)
                global_connection = FALSE;
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->all_checkbutton), global_connection);
 
+       /* Interface name */
+       if (get_device_type (self) != G_TYPE_INVALID) {
+               ifname_list = ce_page_get_ifname_list (CE_PAGE (self), get_device_type (self));
+               s_ifname_str = nm_setting_connection_get_interface_name (setting);
+               ce_page_setup_mac_combo (CE_PAGE (self), GTK_COMBO_BOX (priv->ifname),
+                                        s_ifname_str, ifname_list);
+               g_strfreev (ifname_list);
+               g_signal_connect (priv->ifname, "changed", G_CALLBACK (stuff_changed), self);
+       } else {
+               GtkWidget *label;
+               label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (self)->builder, "interface_name_label"));
+               gtk_widget_hide (label);
+               gtk_widget_hide (GTK_WIDGET (priv->ifname));
+       }
+
        stuff_changed (NULL, self);
 }
 
@@ -377,6 +433,8 @@ ui_to_setting (CEPageGeneral *self)
        char *uuid = NULL;
        GtkTreeIter iter;
        gboolean autoconnect = FALSE, everyone = FALSE;
+       GtkWidget *entry;
+       const char *ifname = NULL;
 
        /* We can't take and save zone until the combo was properly initialized. Zones
         * are received from FirewallD asynchronously; got_zones indicates we are ready.
@@ -411,6 +469,12 @@ ui_to_setting (CEPageGeneral *self)
                /* Only visible to this user */
                nm_setting_connection_add_permission (priv->setting, "user", g_get_user_name (), NULL);
        }
+
+       entry = gtk_bin_get_child (GTK_BIN (priv->ifname));
+       if (entry)
+               ifname = gtk_entry_get_text (GTK_ENTRY (entry));
+       g_object_set (G_OBJECT (priv->setting), NM_SETTING_CONNECTION_INTERFACE_NAME,
+                     ifname && *ifname ? ifname : NULL, NULL);
 }
 
 static gboolean


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