mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-26 16:40:32 +01:00
nmtui: use select button to select available devices
Since it is error prone to manually type in interface names to match existing ones, we introduce a select button that allows a user to chose from a list of devices. - Show "Select..." button for physical devices to choose from available devices in a popup dialog. - devices are sorted in alphabetical order. - Only for physical devices (ethernet, infiniband, wifi, etc) Resolves: https://issues.redhat.com/browse/RHEL-129186
This commit is contained in:
parent
574411b8a5
commit
e10fac49bb
8 changed files with 183 additions and 24 deletions
3
NEWS
3
NEWS
|
|
@ -37,6 +37,9 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
|||
* The "band" property of Wi-fi connections now accepts the "6GHz"
|
||||
value.
|
||||
* Show the Wi-Fi band of APs in the scan results from nmcli.
|
||||
* New <Select...> button in nmtui that allows users to chose from list of
|
||||
available devices when creating connection profiles for physical interfaces
|
||||
(Ethernet, Wi-Fi, etc.).
|
||||
|
||||
=============================================
|
||||
NetworkManager-1.56
|
||||
|
|
|
|||
|
|
@ -14,11 +14,6 @@
|
|||
* the entry recognizes the interface name or mac address typed in as
|
||||
* matching a known #NMDevice, then it will also display the other
|
||||
* property in parentheses.
|
||||
*
|
||||
* FIXME: #NmtDeviceEntry is currently an #NmtEditorGrid object, so that
|
||||
* we can possibly eventually add a button to its "extra" field, that
|
||||
* would pop up a form for selecting a device. But if we're not going
|
||||
* to implement that then we should make it just an #NmtNewtEntry.
|
||||
*/
|
||||
|
||||
#include "libnm-client-aux-extern/nm-default-client.h"
|
||||
|
|
@ -49,6 +44,7 @@ typedef struct {
|
|||
NmtNewtWidget *button;
|
||||
|
||||
gboolean updating;
|
||||
gboolean show_select_button;
|
||||
} NmtDeviceEntryPrivate;
|
||||
|
||||
enum {
|
||||
|
|
@ -58,6 +54,7 @@ enum {
|
|||
PROP_HARDWARE_TYPE,
|
||||
PROP_INTERFACE_NAME,
|
||||
PROP_MAC_ADDRESS,
|
||||
PROP_SHOW_SELECT_BUTTON,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -68,16 +65,18 @@ enum {
|
|||
* @width: the width of the entry
|
||||
* @hardware_type: the type of #NMDevice to be selected, or
|
||||
* %G_TYPE_NONE if this is for a virtual device type.
|
||||
* @show_select_button: whether to show select button or not.
|
||||
*
|
||||
* Creates a new #NmtDeviceEntry, for identifying a device of type
|
||||
* @hardware_type. If @hardware_type is %G_TYPE_NONE (and you do not
|
||||
* set a #NmtDeviceEntryDeviceFilter), then this will only allow
|
||||
* specifying an interface name, not a hardware address.
|
||||
* specifying an interface name, not a hardware address. @show_select_button
|
||||
* will allow the user to select from a list of available devices of type @hardware_type.
|
||||
*
|
||||
* Returns: a new #NmtDeviceEntry.
|
||||
*/
|
||||
NmtNewtWidget *
|
||||
nmt_device_entry_new(const char *label, int width, GType hardware_type)
|
||||
nmt_device_entry_new(const char *label, int width, GType hardware_type, gboolean show_select_button)
|
||||
{
|
||||
return g_object_new(NMT_TYPE_DEVICE_ENTRY,
|
||||
"label",
|
||||
|
|
@ -86,6 +85,8 @@ nmt_device_entry_new(const char *label, int width, GType hardware_type)
|
|||
width,
|
||||
"hardware-type",
|
||||
hardware_type,
|
||||
"show-select-button",
|
||||
show_select_button,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +334,133 @@ entry_text_changed(GObject *object, GParamSpec *pspec, gpointer deventry)
|
|||
g_free(mac);
|
||||
}
|
||||
|
||||
static void
|
||||
device_selected(NmtNewtWidget *listbox, gpointer user_data)
|
||||
{
|
||||
NMDevice *candidate = nmt_newt_listbox_get_active_key(NMT_NEWT_LISTBOX(listbox));
|
||||
NmtDeviceEntry *deventry = NMT_DEVICE_ENTRY(user_data);
|
||||
const char *ifname;
|
||||
|
||||
if (!candidate)
|
||||
return;
|
||||
|
||||
ifname = nm_device_get_iface(candidate);
|
||||
if (!ifname)
|
||||
return;
|
||||
|
||||
if (nmt_device_entry_set_interface_name(deventry, ifname))
|
||||
update_entry(deventry);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_devices_by_name(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
NMDevice **dev_a = (NMDevice **) a;
|
||||
NMDevice **dev_b = (NMDevice **) b;
|
||||
|
||||
return nm_strcmp0(nm_device_get_iface(*dev_a), nm_device_get_iface(*dev_b));
|
||||
}
|
||||
|
||||
static void
|
||||
do_select_dialog(NmtNewtWidget *button, gpointer user_data)
|
||||
{
|
||||
NmtDeviceEntry *deventry;
|
||||
NmtDeviceEntryPrivate *priv;
|
||||
gs_unref_object NmtNewtForm *popup_form = NULL;
|
||||
NmtNewtWidget *listbox_widget;
|
||||
NmtNewtForm *parent_form;
|
||||
const GPtrArray *devices;
|
||||
gs_unref_ptrarray GPtrArray *matching_devices = NULL;
|
||||
const char *ifname, *driver;
|
||||
int i;
|
||||
int entry_x, entry_y;
|
||||
int window_x, window_y;
|
||||
int popup_x, popup_y;
|
||||
int list_w, list_h;
|
||||
newtComponent entry_component;
|
||||
|
||||
deventry = NMT_DEVICE_ENTRY(user_data);
|
||||
priv = NMT_DEVICE_ENTRY_GET_PRIVATE(deventry);
|
||||
parent_form = nmt_newt_widget_get_form(NMT_NEWT_WIDGET(deventry));
|
||||
if (!parent_form)
|
||||
return;
|
||||
|
||||
matching_devices = g_ptr_array_new();
|
||||
|
||||
entry_component = nmt_newt_component_get_component(NMT_NEWT_COMPONENT(priv->entry));
|
||||
newtComponentGetPosition(entry_component, &entry_x, &entry_y);
|
||||
g_object_get(parent_form, "x", &window_x, "y", &window_y, NULL);
|
||||
|
||||
listbox_widget = nmt_newt_listbox_new(5, NMT_NEWT_LISTBOX_SCROLL);
|
||||
nmt_newt_widget_set_exit_on_activate(listbox_widget, TRUE);
|
||||
|
||||
nmt_newt_widget_set_padding(listbox_widget, 1, 0, 1, 0);
|
||||
|
||||
devices = nm_client_get_devices(nm_client);
|
||||
for (i = 0; i < devices->len; i++) {
|
||||
NMDevice *candidate = devices->pdata[i];
|
||||
|
||||
if (!G_TYPE_CHECK_INSTANCE_TYPE(candidate, priv->hardware_type))
|
||||
continue;
|
||||
|
||||
if (priv->device_filter
|
||||
&& !priv->device_filter(deventry, candidate, priv->device_filter_data))
|
||||
continue;
|
||||
|
||||
ifname = nm_device_get_iface(candidate);
|
||||
if (!ifname)
|
||||
continue;
|
||||
|
||||
g_ptr_array_add(matching_devices, candidate);
|
||||
}
|
||||
|
||||
if (matching_devices->len == 0) {
|
||||
nmt_newt_message_dialog(_("No devices available"));
|
||||
return;
|
||||
}
|
||||
|
||||
g_ptr_array_sort(matching_devices, compare_devices_by_name);
|
||||
|
||||
for (i = 0; i < matching_devices->len; i++) {
|
||||
gs_free char *display_text = NULL;
|
||||
NMDevice *candidate = matching_devices->pdata[i];
|
||||
|
||||
ifname = nm_device_get_iface(candidate);
|
||||
|
||||
driver = nm_device_get_driver(candidate);
|
||||
|
||||
if (driver && driver[0] != '\0') {
|
||||
display_text = g_strdup_printf("%s (%s)", ifname, driver);
|
||||
} else {
|
||||
display_text = g_strdup(ifname);
|
||||
}
|
||||
|
||||
nmt_newt_listbox_append(NMT_NEWT_LISTBOX(listbox_widget), display_text, candidate);
|
||||
}
|
||||
|
||||
g_signal_connect(listbox_widget, "activated", G_CALLBACK(device_selected), deventry);
|
||||
|
||||
nmt_newt_widget_size_request(listbox_widget, &list_w, &list_h);
|
||||
popup_x = window_x + entry_x + 1;
|
||||
popup_y = window_y + entry_y + 1;
|
||||
|
||||
popup_form = g_object_new(NMT_TYPE_NEWT_FORM,
|
||||
"x",
|
||||
popup_x,
|
||||
"y",
|
||||
popup_y,
|
||||
"width",
|
||||
list_w,
|
||||
"height",
|
||||
list_h,
|
||||
"padding",
|
||||
0,
|
||||
NULL);
|
||||
|
||||
nmt_newt_form_set_content(popup_form, listbox_widget);
|
||||
nmt_newt_form_show(popup_form);
|
||||
}
|
||||
|
||||
static void
|
||||
nmt_device_entry_init(NmtDeviceEntry *deventry)
|
||||
{
|
||||
|
|
@ -346,11 +474,9 @@ nmt_device_entry_init(NmtDeviceEntry *deventry)
|
|||
nmt_newt_entry_set_validator(priv->entry, device_entry_validate, deventry);
|
||||
g_signal_connect(priv->entry, "notify::text", G_CALLBACK(entry_text_changed), deventry);
|
||||
|
||||
#if 0
|
||||
priv->button = nmt_newt_button_new (_("Select..."));
|
||||
g_signal_connect (priv->button, "clicked",
|
||||
G_CALLBACK (do_select_dialog), deventry);
|
||||
#endif
|
||||
priv->button = nmt_newt_button_new(_("Select..."));
|
||||
nmt_newt_widget_set_visible(priv->button, FALSE);
|
||||
g_signal_connect(priv->button, "clicked", G_CALLBACK(do_select_dialog), deventry);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -361,7 +487,7 @@ nmt_device_entry_constructed(GObject *object)
|
|||
nmt_editor_grid_append(NMT_EDITOR_GRID(object),
|
||||
priv->label,
|
||||
NMT_NEWT_WIDGET(priv->entry),
|
||||
NULL);
|
||||
priv->button);
|
||||
|
||||
G_OBJECT_CLASS(nmt_device_entry_parent_class)->constructed(object);
|
||||
}
|
||||
|
|
@ -446,6 +572,10 @@ nmt_device_entry_set_property(GObject *object,
|
|||
if (nmt_device_entry_set_mac_address(deventry, mac_address))
|
||||
update_entry(deventry);
|
||||
break;
|
||||
case PROP_SHOW_SELECT_BUTTON:
|
||||
priv->show_select_button = g_value_get_boolean(value);
|
||||
nmt_newt_widget_set_visible(priv->button, priv->show_select_button);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -473,6 +603,9 @@ nmt_device_entry_get_property(GObject *object, guint prop_id, GValue *value, GPa
|
|||
case PROP_MAC_ADDRESS:
|
||||
g_value_set_string(value, priv->mac_address);
|
||||
break;
|
||||
case PROP_SHOW_SELECT_BUTTON:
|
||||
g_value_set_boolean(value, priv->show_select_button);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -554,4 +687,18 @@ nmt_device_entry_class_init(NmtDeviceEntryClass *deventry_class)
|
|||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NmtDeviceEntry:show-select-button:
|
||||
*
|
||||
* Display select button to select device from available devices.
|
||||
*/
|
||||
g_object_class_install_property(
|
||||
object_class,
|
||||
PROP_SHOW_SELECT_BUTTON,
|
||||
g_param_spec_boolean("show-select-button",
|
||||
"",
|
||||
"",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,10 @@ typedef struct {
|
|||
|
||||
GType nmt_device_entry_get_type(void);
|
||||
|
||||
NmtNewtWidget *nmt_device_entry_new(const char *label, int width, GType hardware_type);
|
||||
NmtNewtWidget *nmt_device_entry_new(const char *label,
|
||||
int width,
|
||||
GType hardware_type,
|
||||
gboolean show_select_button);
|
||||
|
||||
typedef gboolean (*NmtDeviceEntryDeviceFilter)(NmtDeviceEntry *deventry,
|
||||
NMDevice *device,
|
||||
|
|
|
|||
|
|
@ -244,8 +244,10 @@ nmt_editor_grid_get_components(NmtNewtWidget *widget)
|
|||
|
||||
if (rows[i].extra) {
|
||||
child_cos = nmt_newt_widget_get_components(rows[i].extra);
|
||||
for (c = 0; child_cos[c]; c++)
|
||||
g_ptr_array_add(cos, child_cos[c]);
|
||||
if (child_cos) {
|
||||
for (c = 0; child_cos[c]; c++)
|
||||
g_ptr_array_add(cos, child_cos[c]);
|
||||
}
|
||||
g_free(child_cos);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@ nmt_editor_constructed(GObject *object)
|
|||
GType hardware_type;
|
||||
const char *port_type;
|
||||
NmtEditorPage *page;
|
||||
gboolean show_select_button;
|
||||
|
||||
if (G_OBJECT_CLASS(nmt_editor_parent_class)->constructed)
|
||||
G_OBJECT_CLASS(nmt_editor_parent_class)->constructed(object);
|
||||
|
|
@ -333,10 +334,13 @@ nmt_editor_constructed(GObject *object)
|
|||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
nmt_editor_grid_append(grid, _("Profile name"), widget, NULL);
|
||||
|
||||
if (priv->type_data->virtual)
|
||||
hardware_type = G_TYPE_NONE;
|
||||
else
|
||||
hardware_type = priv->type_data->device_type;
|
||||
if (priv->type_data->virtual) {
|
||||
hardware_type = G_TYPE_NONE;
|
||||
show_select_button = FALSE;
|
||||
} else {
|
||||
hardware_type = priv->type_data->device_type;
|
||||
show_select_button = TRUE;
|
||||
}
|
||||
|
||||
if (nm_connection_is_type(priv->edit_connection, NM_SETTING_LOOPBACK_SETTING_NAME)) {
|
||||
g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "lo", NULL);
|
||||
|
|
@ -349,7 +353,7 @@ nmt_editor_constructed(GObject *object)
|
|||
else
|
||||
deventry_label = _("Device");
|
||||
|
||||
widget = nmt_device_entry_new(deventry_label, 40, hardware_type);
|
||||
widget = nmt_device_entry_new(deventry_label, 40, hardware_type, show_select_button);
|
||||
nmt_editor_grid_append(grid, NULL, widget, NULL);
|
||||
deventry = NMT_DEVICE_ENTRY(widget);
|
||||
g_object_bind_property(s_con,
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ nmt_page_ip_tunnel_constructed(GObject *object)
|
|||
w2s);
|
||||
nmt_editor_grid_append(grid, _("Mode"), widget, NULL);
|
||||
|
||||
widget = parent = nmt_device_entry_new(_("Parent"), 40, G_TYPE_NONE);
|
||||
widget = parent = nmt_device_entry_new(_("Parent"), 40, G_TYPE_NONE, FALSE);
|
||||
g_object_bind_property(s_ip_tunnel,
|
||||
NM_SETTING_IP_TUNNEL_PARENT,
|
||||
widget,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ nmt_page_macsec_constructed(GObject *object)
|
|||
section = nmt_editor_section_new(_("MACsec"), NULL, TRUE);
|
||||
grid = nmt_editor_section_get_body(section);
|
||||
|
||||
widget = nmt_device_entry_new(_("Parent device"), 40, G_TYPE_NONE);
|
||||
widget = nmt_device_entry_new(_("Parent device"), 40, G_TYPE_NONE, FALSE);
|
||||
g_object_bind_property(s_macsec,
|
||||
NM_SETTING_MACSEC_PARENT,
|
||||
widget,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ nmt_page_vlan_constructed(GObject *object)
|
|||
|
||||
nm_editor_bind_vlan_name(s_vlan, nm_connection_get_setting_connection(conn));
|
||||
|
||||
widget = parent = nmt_device_entry_new(_("Parent"), 40, G_TYPE_NONE);
|
||||
widget = parent = nmt_device_entry_new(_("Parent"), 40, G_TYPE_NONE, FALSE);
|
||||
nmt_device_entry_set_device_filter(NMT_DEVICE_ENTRY(widget), vlan_device_filter, vlan);
|
||||
g_object_bind_property(s_vlan,
|
||||
NM_SETTING_VLAN_PARENT,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue