network: fix sensitivity of DNS and route configuration widgets

When the IP method is "disabled" or "shared" then everything else is
supposed to be insensitive. This currently fails if you toggle between
the two, because it's implemented using property bindings that are just
not smart enough to handle this task. Handle sensitivity only in
method_changed() to avoid this.

Additionally, not all of the widgets are being consistently
disabled/enabled when appropriate. E.g. when the method is "local" then
only the DNS entry, route entries, and default route checkboxes become
insensitive, leaving the other widgets, including notably the Automatic
switches, sensitive. They should all become insensitive, as when the
method is "disabled" or "shared." Fix this by organizing all the related
widgets into boxes and setting the sensitivity of the entire box. (Note
the strategy followed here does not exactly match nm-connection-editor,
which always allows editing addresses. We only allow that in Manual
mode. I'm not sure if this is advisable or not, so won't touch that.)

Finally, the Automatic DNS and Automatic Routes toggles should only be
sensitive when the method is "Automatic".
This commit is contained in:
Michael Catanzaro 2023-10-13 14:03:43 -05:00 committed by Felipe Borges
parent 0e8d8e7407
commit 88f9c7991c
4 changed files with 301 additions and 267 deletions

View file

@ -45,14 +45,17 @@ struct _CEPageIP4
GtkLabel *address_gateway_label;
GtkLabel *address_netmask_label;
GtkSizeGroup *address_sizegroup;
GtkLabel *auto_dns_label;
GtkSwitch *auto_dns_switch;
GtkLabel *auto_routes_label;
GtkSwitch *auto_routes_switch;
GtkBox *content_box;
GtkCheckButton *disabled_radio;
GtkBox *dns_box;
GtkEntry *dns_entry;
GtkGrid *main_box;
GtkCheckButton *never_default_check;
GtkBox *routes_box;
GtkBox *route_config_box;
GtkLabel *routes_address_label;
GtkLabel *routes_gateway_label;
GtkLabel *routes_netmask_label;
@ -62,7 +65,6 @@ struct _CEPageIP4
GtkSizeGroup *routes_netmask_sizegroup;
GtkSizeGroup *routes_metric_sizegroup;
GtkSizeGroup *routes_sizegroup;
GtkCheckButton *shared_radio;
NMSettingIPConfig *setting;
@ -110,6 +112,7 @@ method_changed (CEPageIP4 *self)
gboolean addr_enabled;
gboolean dns_enabled;
gboolean routes_enabled;
gboolean auto_enabled;
g_autoptr(GVariant) method_variant = NULL;
const gchar *method;
@ -121,16 +124,22 @@ method_changed (CEPageIP4 *self)
addr_enabled = FALSE;
dns_enabled = FALSE;
routes_enabled = FALSE;
auto_enabled = FALSE;
} else {
addr_enabled = g_str_equal (method, "manual");
routes_enabled = !g_str_equal (method, "local");
dns_enabled = !g_str_equal (method, "local");
routes_enabled = !g_str_equal (method, "local");
auto_enabled = g_str_equal (method, "automatic");
}
gtk_widget_set_visible (GTK_WIDGET (self->address_box), addr_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->dns_entry), dns_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->routes_list), routes_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->never_default_check), routes_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->dns_box), dns_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->routes_box), routes_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_dns_label), auto_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_dns_switch), auto_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_routes_label), auto_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_routes_switch), auto_enabled);
sync_dns_entry_warning (self);
@ -476,14 +485,14 @@ ensure_empty_routes_row (CEPageIP4 *self)
}
static void
add_routes_box (CEPageIP4 *self)
add_route_config_box (CEPageIP4 *self)
{
GtkWidget *list;
gint i;
self->routes_list = list = gtk_list_box_new ();
gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
gtk_box_append (GTK_BOX (self->routes_box), list);
gtk_box_append (GTK_BOX (self->route_config_box), list);
gtk_switch_set_active (self->auto_routes_switch, !nm_setting_ip_config_get_ignore_auto_routes (self->setting));
g_signal_connect_object (self->auto_routes_switch, "notify::active", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
@ -517,18 +526,9 @@ connect_ip4_page (CEPageIP4 *self)
add_address_box (self);
add_dns_section (self);
add_routes_box (self);
add_route_config_box (self);
str_method = nm_setting_ip_config_get_method (self->setting);
g_signal_connect_object (self->disabled_radio, "notify::active", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
g_object_bind_property (self->disabled_radio, "active",
self->content_box, "sensitive",
G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
g_signal_connect_object (self->shared_radio, "notify::active", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
g_object_bind_property (self->shared_radio, "active",
self->content_box, "sensitive",
G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
method = "automatic";
if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) {
@ -833,10 +833,12 @@ ce_page_ip4_class_init (CEPageIP4Class *klass)
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, address_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, address_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, auto_dns_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, auto_dns_switch);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, auto_routes_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, auto_routes_switch);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, content_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, disabled_radio);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, dns_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, dns_entry);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, main_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, never_default_check);
@ -844,6 +846,7 @@ ce_page_ip4_class_init (CEPageIP4Class *klass)
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, address_netmask_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, address_gateway_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, routes_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, route_config_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, routes_address_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, routes_netmask_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, routes_gateway_label);
@ -853,7 +856,6 @@ ce_page_ip4_class_init (CEPageIP4Class *klass)
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, routes_gateway_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, routes_metric_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, routes_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP4, shared_radio);
}
static void

View file

@ -45,14 +45,18 @@ struct _CEPageIP6
GtkLabel *address_prefix_label;
GtkLabel *address_gateway_label;
GtkSizeGroup *address_sizegroup;
GtkLabel *auto_dns_label;
GtkSwitch *auto_dns_switch;
GtkLabel *auto_routes_label;
GtkSwitch *auto_routes_switch;
GtkBox *content_box;
GtkCheckButton *disabled_radio;
GtkBox *dns_box;
GtkEntry *dns_entry;
GtkGrid *main_box;
GtkCheckButton *never_default_check;
GtkBox *routes_box;
GtkBox *route_config_box;
GtkLabel *routes_address_label;
GtkLabel *routes_prefix_label;
GtkLabel *routes_gateway_label;
@ -110,6 +114,8 @@ method_changed (CEPageIP6 *self)
gboolean addr_enabled;
gboolean dns_enabled;
gboolean routes_enabled;
gboolean auto_dns_enabled;
gboolean auto_routes_enabled;
g_autoptr(GVariant) method_variant = NULL;
const gchar *method;
@ -121,16 +127,24 @@ method_changed (CEPageIP6 *self)
addr_enabled = FALSE;
dns_enabled = FALSE;
routes_enabled = FALSE;
auto_dns_enabled = FALSE;
auto_routes_enabled = FALSE;
} else {
addr_enabled = g_str_equal (method, "manual");
routes_enabled = !g_str_equal (method, "local");
dns_enabled = !g_str_equal (method, "local");
routes_enabled = !g_str_equal (method, "local");
auto_dns_enabled = g_str_equal (method, "automatic") || g_str_equal (method, "dhcp");
auto_routes_enabled = g_str_equal (method, "automatic");
}
gtk_widget_set_visible (GTK_WIDGET (self->address_box), addr_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->dns_entry), dns_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->routes_list), routes_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->never_default_check), routes_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->dns_box), dns_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->routes_box), routes_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_dns_label), auto_dns_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_dns_switch), auto_dns_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_routes_label), auto_routes_enabled);
gtk_widget_set_sensitive (GTK_WIDGET (self->auto_routes_switch), auto_routes_enabled);
sync_dns_entry_warning (self);
@ -449,14 +463,14 @@ add_empty_route_row (CEPageIP6 *self)
}
static void
add_routes_box (CEPageIP6 *self)
add_route_config_box (CEPageIP6 *self)
{
GtkWidget *list;
gint i;
self->routes_list = list = gtk_list_box_new ();
gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
gtk_box_append (self->routes_box, list);
gtk_box_append (self->route_config_box, list);
gtk_switch_set_active (self->auto_routes_switch, !nm_setting_ip_config_get_ignore_auto_routes (self->setting));
g_signal_connect_object (self->auto_routes_switch, "notify::active", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
@ -485,18 +499,9 @@ connect_ip6_page (CEPageIP6 *self)
add_address_box (self);
add_dns_section (self);
add_routes_box (self);
add_route_config_box (self);
str_method = nm_setting_ip_config_get_method (self->setting);
g_signal_connect_object (self->disabled_radio, "notify::active", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
g_object_bind_property (self->disabled_radio, "active",
self->content_box, "sensitive",
G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
g_signal_connect_object (self->shared_radio, "notify::active", G_CALLBACK (ce_page_changed), self, G_CONNECT_SWAPPED);
g_object_bind_property (self->shared_radio, "active",
self->content_box, "sensitive",
G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
method = "automatic";
if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
@ -800,14 +805,17 @@ ce_page_ip6_class_init (CEPageIP6Class *klass)
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, address_prefix_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, address_gateway_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, address_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, auto_dns_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, auto_dns_switch);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, auto_routes_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, auto_routes_switch);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, content_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, disabled_radio);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, dns_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, dns_entry);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, main_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, never_default_check);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, routes_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, route_config_box);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, routes_address_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, routes_address_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, routes_prefix_label);
@ -817,7 +825,6 @@ ce_page_ip6_class_init (CEPageIP6Class *klass)
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, routes_metric_label);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, routes_metric_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, routes_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CEPageIP6, shared_radio);
}
static void

View file

@ -161,155 +161,167 @@
</object>
</child>
<child>
<object class="GtkBox">
<property name="margin_top">24</property>
<object class="GtkBox" id="dns_box">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="dns4_label">
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">DNS</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
<object class="GtkBox">
<property name="margin_top">24</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="dns4_label">
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">DNS</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="auto_dns_label">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="auto_dns_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<accessibility>
<property name="label" translatable="yes">Automatic DNS</property>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="auto_dns_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<object class="GtkEntry" id="dns_entry">
<accessibility>
<property name="label" translatable="yes">Automatic DNS</property>
<property name="label" translatable="yes">DNS server address(es)</property>
<relation name="described-by">dns_multiple_help</relation>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkEntry" id="dns_entry">
<accessibility>
<property name="label" translatable="yes">DNS server address(es)</property>
<relation name="described-by">dns_multiple_help</relation>
</accessibility>
</object>
</child>
<child>
<object class="GtkLabel" id="dns_multiple_help">
<property name="xalign">0</property>
<property name="label" translatable="yes">Separate IP addresses with commas</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkBox">
<property name="margin_top">24</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="dns_multiple_help">
<property name="xalign">0</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Routes</property>
<property name="label" translatable="yes">Separate IP addresses with commas</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="auto_routes_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<accessibility>
<property name="label" translatable="yes">Automatic Routes</property>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="routes_box">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="margin_top">24</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="routes_address_label">
<property name="label" translatable="yes">Address</property>
<style>
<class name="dim-label" />
</style>
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Routes</property>
<attributes>
<attribute name="scale" value="0.8"/>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_netmask_label">
<property name="label" translatable="yes">Netmask</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
<object class="GtkLabel" id="auto_routes_label">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_gateway_label">
<property name="label" translatable="yes">Gateway</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_metric_label">
<property name="label" translatable="yes" comments="Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking)">Metric</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<!-- This invisible box is used to add some width in the
end of the header row, assuming the space used by the
delete button in the rows -->
<child>
<object class="GtkBox" id="routes_stub_box">
<object class="GtkSwitch" id="auto_routes_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<accessibility>
<property name="label" translatable="yes">Automatic Routes</property>
</accessibility>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkCheckButton" id="never_default_check">
<property name="label" translatable="yes">Use this connection _only for resources on its network</property>
<property name="use_underline">True</property>
<child>
<object class="GtkBox" id="route_config_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel" id="routes_address_label">
<property name="label" translatable="yes">Address</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_netmask_label">
<property name="label" translatable="yes">Netmask</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_gateway_label">
<property name="label" translatable="yes">Gateway</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_metric_label">
<property name="label" translatable="yes" comments="Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking)">Metric</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<!-- This invisible box is used to add some width in the
end of the header row, assuming the space used by the
delete button in the rows -->
<child>
<object class="GtkBox" id="routes_stub_box">
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkCheckButton" id="never_default_check">
<property name="label" translatable="yes">Use this connection _only for resources on its network</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>
@ -358,3 +370,4 @@
</widgets>
</object>
</interface>

View file

@ -172,155 +172,167 @@
</object>
</child>
<child>
<object class="GtkBox">
<property name="margin_top">24</property>
<object class="GtkBox" id="dns_box">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="dns6_label">
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">DNS</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
<object class="GtkBox">
<property name="margin_top">24</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="dns6_label">
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">DNS</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="auto_dns_label">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="auto_dns_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<accessibility>
<property name="label" translatable="yes">Automatic DNS</property>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="auto_dns_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<accessibility>
<property name="label" translatable="yes">Automatic DNS</property>
<object class="GtkEntry" id="dns_entry">
<accessibility>
<property name="label" translatable="yes">DNS server address(es)</property>
<relation name="described-by">dns_multiple_help</relation>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkEntry" id="dns_entry">
<accessibility>
<property name="label" translatable="yes">DNS server address(es)</property>
<relation name="described-by">dns_multiple_help</relation>
</accessibility>
</object>
</child>
<child>
<object class="GtkLabel" id="dns_multiple_help">
<property name="xalign">0</property>
<property name="label" translatable="yes">Separate IP addresses with commas</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkBox">
<property name="margin_top">24</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<object class="GtkLabel" id="dns_multiple_help">
<property name="xalign">0</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Routes</property>
<property name="label" translatable="yes">Separate IP addresses with commas</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="auto_routes_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<accessibility>
<property name="label" translatable="yes">Automatic Routes</property>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="routes_box">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="margin_top">24</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="routes_address_label">
<property name="label" translatable="yes">Address</property>
<style>
<class name="dim-label" />
</style>
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Routes</property>
<attributes>
<attribute name="scale" value="0.8"/>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_prefix_label">
<property name="label" translatable="yes">Prefix</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
<object class="GtkLabel" id="auto_routes_label">
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic</property>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_gateway_label">
<property name="label" translatable="yes">Gateway</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_metric_label">
<property name="label" translatable="yes" comments="Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking)">Metric</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<!-- This invisible box is used to add some width in the
end of the header row, assuming the space used by the
delete button in the rows -->
<child>
<object class="GtkBox" id="routes_stub_box">
<object class="GtkSwitch" id="auto_routes_switch">
<property name="halign">end</property>
<property name="valign">center</property>
<accessibility>
<property name="label" translatable="yes">Automatic Routes</property>
</accessibility>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkCheckButton" id="never_default_check">
<property name="label" translatable="yes">Use this connection _only for resources on its network</property>
<property name="use_underline">True</property>
<child>
<object class="GtkBox" id="route_config_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel" id="routes_address_label">
<property name="label" translatable="yes">Address</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_prefix_label">
<property name="label" translatable="yes">Prefix</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_gateway_label">
<property name="label" translatable="yes">Gateway</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel" id="routes_metric_label">
<property name="label" translatable="yes" comments="Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking)">Metric</property>
<style>
<class name="dim-label" />
</style>
<attributes>
<attribute name="scale" value="0.8"/>
</attributes>
</object>
</child>
<!-- This invisible box is used to add some width in the
end of the header row, assuming the space used by the
delete button in the rows -->
<child>
<object class="GtkBox" id="routes_stub_box">
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkCheckButton" id="never_default_check">
<property name="label" translatable="yes">Use this connection _only for resources on its network</property>
<property name="use_underline">True</property>
</object>
</child>
</object>
</child>
</object>