network: Use a table-like widget to edit routes
According to the latest mockups for the connection editor dialog [1], the IPv4 and IPv6 pages are supposed to use a table-like editor to manage the routes. This editor is not only easier to comprehend, but also improves the size of the dialog, requiring much less vertical space to present the routes. The current implementation, however, uses a vertical layout and a toolbar, which is inefficient in its usage of space. Fix that by implementing the table-like editor widget, both in IPv4 and IPv6 pages. [1] https://raw.githubusercontent.com/gnome-design-team/gnome-mockups/master/system-settings/network/aday2/network-wires.png https://bugzilla.gnome.org/show_bug.cgi?id=779841
This commit is contained in:
parent
2e570099f6
commit
08657fac44
4 changed files with 320 additions and 142 deletions
|
@ -34,6 +34,8 @@
|
|||
|
||||
#define RADIO_IS_ACTIVE(x) (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(CE_PAGE (page)->builder, x))))
|
||||
|
||||
static void ensure_empty_routes_row (CEPageIP4 *page);
|
||||
|
||||
G_DEFINE_TYPE (CEPageIP4, ce_page_ip4, CE_TYPE_PAGE)
|
||||
|
||||
enum {
|
||||
|
@ -88,7 +90,7 @@ static void
|
|||
update_row_sensitivity (CEPageIP4 *page, GtkWidget *list)
|
||||
{
|
||||
GList *children, *l;
|
||||
gint rows = 0;
|
||||
gint rows = 0, i = 0;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (list));
|
||||
for (l = children; l; l = l->next) {
|
||||
|
@ -105,7 +107,7 @@ update_row_sensitivity (CEPageIP4 *page, GtkWidget *list)
|
|||
|
||||
button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
|
||||
if (button != NULL)
|
||||
gtk_widget_set_sensitive (button, rows > 1);
|
||||
gtk_widget_set_sensitive (button, rows > 1 && ++i < rows);
|
||||
}
|
||||
g_list_free (children);
|
||||
}
|
||||
|
@ -152,6 +154,29 @@ remove_row (GtkButton *button, CEPageIP4 *page)
|
|||
update_row_gateway_visibility (page);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_row (GtkWidget *row)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GList *children, *l;
|
||||
gboolean valid;
|
||||
|
||||
valid = FALSE;
|
||||
box = gtk_bin_get_child (GTK_BIN (row));
|
||||
children = gtk_container_get_children (GTK_CONTAINER (box));
|
||||
|
||||
for (l = children; l != NULL; l = l->next) {
|
||||
if (!GTK_IS_ENTRY (l->data))
|
||||
continue;
|
||||
|
||||
valid = valid || gtk_entry_get_text_length (l->data) > 0;
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_first_last (gconstpointer a, gconstpointer b, gpointer data)
|
||||
{
|
||||
|
@ -235,6 +260,7 @@ add_address_row (CEPageIP4 *page,
|
|||
gtk_widget_set_no_show_all (widget, FALSE);
|
||||
|
||||
delete_button = gtk_button_new ();
|
||||
gtk_widget_set_sensitive (delete_button, FALSE);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button");
|
||||
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
|
||||
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
|
||||
|
@ -382,92 +408,76 @@ add_route_row (CEPageIP4 *page,
|
|||
const gchar *gateway,
|
||||
gint metric)
|
||||
{
|
||||
GtkSizeGroup *group;
|
||||
GtkWidget *row;
|
||||
GtkWidget *row_grid;
|
||||
GtkWidget *label;
|
||||
GtkWidget *row_box;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *delete_button;
|
||||
GtkWidget *image;
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
|
||||
row_grid = gtk_grid_new ();
|
||||
label = gtk_label_new (_("Address"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 1, 1, 1);
|
||||
row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked");
|
||||
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "address", widget);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), address);
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 1, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
label = gtk_label_new (_("Netmask"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 2, 1, 1);
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "netmask", widget);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), netmask);
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 2, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
label = gtk_label_new (_("Gateway"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 3, 1, 1);
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "gateway", widget);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), gateway);
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 3, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
/* Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking) */
|
||||
label = gtk_label_new (C_("network parameters", "Metric"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 4, 1, 1);
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "metric", widget);
|
||||
if (metric >= 0) {
|
||||
gchar *s = g_strdup_printf ("%d", metric);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), s);
|
||||
g_free (s);
|
||||
}
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 5);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 4, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_metric_sizegroup"));
|
||||
gtk_size_group_add_widget (group, widget);
|
||||
|
||||
delete_button = gtk_button_new ();
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button");
|
||||
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
|
||||
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
|
||||
image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU);
|
||||
atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route"));
|
||||
gtk_button_set_image (GTK_BUTTON (delete_button), image);
|
||||
gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), delete_button, 3, 1, 1, 4);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), delete_button);
|
||||
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
|
||||
|
||||
gtk_grid_set_row_spacing (GTK_GRID (row_grid), 10);
|
||||
gtk_widget_set_margin_start (row_grid, 10);
|
||||
gtk_widget_set_margin_end (row_grid, 10);
|
||||
gtk_widget_set_margin_top (row_grid, 10);
|
||||
gtk_widget_set_margin_bottom (row_grid, 10);
|
||||
gtk_widget_set_halign (row_grid, GTK_ALIGN_FILL);
|
||||
group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_sizegroup"));
|
||||
gtk_size_group_add_widget (group, delete_button);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (row), row_grid);
|
||||
gtk_container_add (GTK_CONTAINER (row), row_box);
|
||||
gtk_widget_show_all (row);
|
||||
gtk_container_add (GTK_CONTAINER (page->routes_list), row);
|
||||
|
||||
|
@ -475,33 +485,41 @@ add_route_row (CEPageIP4 *page,
|
|||
}
|
||||
|
||||
static void
|
||||
add_empty_route_row (CEPageIP4 *page)
|
||||
ensure_empty_routes_row (CEPageIP4 *page)
|
||||
{
|
||||
add_route_row (page, "", "", "", -1);
|
||||
GList *children, *l;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
|
||||
l = children;
|
||||
|
||||
while (l && l->next)
|
||||
l = l->next;
|
||||
|
||||
/* Add the last, stub row if needed*/
|
||||
if (!l || validate_row (l->data))
|
||||
add_route_row (page, "", "", "", -1);
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
static void
|
||||
add_routes_section (CEPageIP4 *page)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *list;
|
||||
gint i;
|
||||
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_container_add (GTK_CONTAINER (widget), frame);
|
||||
page->routes_list = list = gtk_list_box_new ();
|
||||
gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
|
||||
gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL);
|
||||
gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), list);
|
||||
gtk_container_add (GTK_CONTAINER (widget), list);
|
||||
page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
|
||||
gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting));
|
||||
g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page);
|
||||
|
||||
add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row));
|
||||
|
||||
for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) {
|
||||
NMIPRoute *route;
|
||||
|
@ -522,7 +540,7 @@ add_routes_section (CEPageIP4 *page)
|
|||
nm_ip_route_get_metric (route));
|
||||
}
|
||||
if (nm_setting_ip_config_get_num_routes (page->setting) == 0)
|
||||
add_empty_route_row (page);
|
||||
ensure_empty_routes_row (page);
|
||||
|
||||
gtk_widget_show_all (widget);
|
||||
}
|
||||
|
@ -842,6 +860,9 @@ ui_to_setting (CEPageIP4 *page)
|
|||
route = nm_ip_route_new (AF_INET, text_address, netmask, text_gateway, metric, NULL);
|
||||
if (route)
|
||||
g_ptr_array_add (routes, route);
|
||||
|
||||
if (!l || !l->next)
|
||||
ensure_empty_routes_row (page);
|
||||
}
|
||||
g_list_free (children);
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#define RADIO_IS_ACTIVE(x) (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(CE_PAGE (page)->builder, x))))
|
||||
|
||||
static void ensure_empty_routes_row (CEPageIP6 *page);
|
||||
|
||||
G_DEFINE_TYPE (CEPageIP6, ce_page_ip6, CE_TYPE_PAGE)
|
||||
|
||||
enum {
|
||||
|
@ -89,7 +91,7 @@ static void
|
|||
update_row_sensitivity (CEPageIP6 *page, GtkWidget *list)
|
||||
{
|
||||
GList *children, *l;
|
||||
gint rows = 0;
|
||||
gint rows = 0, i = 0;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (list));
|
||||
for (l = children; l; l = l->next) {
|
||||
|
@ -106,7 +108,7 @@ update_row_sensitivity (CEPageIP6 *page, GtkWidget *list)
|
|||
|
||||
button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
|
||||
if (button != NULL)
|
||||
gtk_widget_set_sensitive (button, rows > 1);
|
||||
gtk_widget_set_sensitive (button, rows > 1 && ++i < rows);
|
||||
}
|
||||
g_list_free (children);
|
||||
}
|
||||
|
@ -129,6 +131,29 @@ remove_row (GtkButton *button, CEPageIP6 *page)
|
|||
update_row_sensitivity (page, list);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_row (GtkWidget *row)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GList *children, *l;
|
||||
gboolean valid;
|
||||
|
||||
valid = FALSE;
|
||||
box = gtk_bin_get_child (GTK_BIN (row));
|
||||
children = gtk_container_get_children (GTK_CONTAINER (box));
|
||||
|
||||
for (l = children; l != NULL; l = l->next) {
|
||||
if (!GTK_IS_ENTRY (l->data))
|
||||
continue;
|
||||
|
||||
valid = valid || gtk_entry_get_text_length (l->data) > 0;
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_first_last (gconstpointer a, gconstpointer b, gpointer data)
|
||||
{
|
||||
|
@ -347,94 +372,96 @@ add_route_row (CEPageIP6 *page,
|
|||
const gchar *gateway,
|
||||
const gchar *metric)
|
||||
{
|
||||
GtkSizeGroup *group;
|
||||
GtkWidget *row;
|
||||
GtkWidget *row_grid;
|
||||
GtkWidget *label;
|
||||
GtkWidget *row_box;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *delete_button;
|
||||
GtkWidget *image;
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
|
||||
row_grid = gtk_grid_new ();
|
||||
label = gtk_label_new (_("Address"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 1, 1, 1);
|
||||
row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked");
|
||||
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "address", widget);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), address);
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 1, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
label = gtk_label_new (_("Prefix"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 2, 1, 1);
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "prefix", widget);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), prefix ? prefix : "");
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 2, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
label = gtk_label_new (_("Gateway"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 3, 1, 1);
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "gateway", widget);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), gateway);
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 3, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
/* Translators: Please see https://en.wikipedia.org/wiki/Metrics_(networking) */
|
||||
label = gtk_label_new (C_("network parameters", "Metric"));
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), label, 1, 4, 1, 1);
|
||||
widget = gtk_entry_new ();
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
|
||||
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
|
||||
g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
|
||||
g_object_set_data (G_OBJECT (row), "metric", widget);
|
||||
gtk_entry_set_text (GTK_ENTRY (widget), metric ? metric : "");
|
||||
gtk_widget_set_margin_start (widget, 10);
|
||||
gtk_widget_set_margin_end (widget, 10);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (widget), 5);
|
||||
gtk_widget_set_hexpand (widget, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), widget, 2, 4, 1, 1);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), widget);
|
||||
|
||||
group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_metric_sizegroup"));
|
||||
gtk_size_group_add_widget (group, widget);
|
||||
|
||||
delete_button = gtk_button_new ();
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button");
|
||||
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
|
||||
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
|
||||
image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU);
|
||||
atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route"));
|
||||
gtk_button_set_image (GTK_BUTTON (delete_button), image);
|
||||
gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER);
|
||||
gtk_grid_attach (GTK_GRID (row_grid), delete_button, 3, 1, 1, 4);
|
||||
gtk_container_add (GTK_CONTAINER (row_box), delete_button);
|
||||
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
|
||||
|
||||
gtk_grid_set_row_spacing (GTK_GRID (row_grid), 10);
|
||||
gtk_widget_set_margin_start (row_grid, 10);
|
||||
gtk_widget_set_margin_end (row_grid, 10);
|
||||
gtk_widget_set_margin_top (row_grid, 10);
|
||||
gtk_widget_set_margin_bottom (row_grid, 10);
|
||||
gtk_widget_set_halign (row_grid, GTK_ALIGN_FILL);
|
||||
group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_sizegroup"));
|
||||
gtk_size_group_add_widget (group, delete_button);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (row), row_grid);
|
||||
gtk_container_add (GTK_CONTAINER (row), row_box);
|
||||
gtk_widget_show_all (row);
|
||||
gtk_container_add (GTK_CONTAINER (page->routes_list), row);
|
||||
|
||||
update_row_sensitivity (page, page->routes_list);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_empty_routes_row (CEPageIP6 *page)
|
||||
{
|
||||
GList *children, *l;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
|
||||
l = children;
|
||||
|
||||
while (l && l->next)
|
||||
l = l->next;
|
||||
|
||||
/* Add the last, stub row if needed*/
|
||||
if (!l || validate_row (l->data))
|
||||
add_route_row (page, "", NULL, "", NULL);
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
static void
|
||||
add_empty_route_row (CEPageIP6 *page)
|
||||
{
|
||||
|
@ -445,25 +472,20 @@ static void
|
|||
add_routes_section (CEPageIP6 *page)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *list;
|
||||
gint i;
|
||||
|
||||
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_container_add (GTK_CONTAINER (widget), frame);
|
||||
page->routes_list = list = gtk_list_box_new ();
|
||||
gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
|
||||
gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL);
|
||||
gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), list);
|
||||
gtk_container_add (GTK_CONTAINER (widget), list);
|
||||
page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
|
||||
gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting));
|
||||
g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page);
|
||||
|
||||
add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row));
|
||||
|
||||
for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) {
|
||||
NMIPRoute *route;
|
||||
char *prefix, *metric;
|
||||
|
@ -778,6 +800,9 @@ ui_to_setting (CEPageIP6 *page)
|
|||
route = nm_ip_route_new (AF_INET6, text_address, prefix, text_gateway, metric, NULL);
|
||||
nm_setting_ip_config_add_route (page->setting, route);
|
||||
nm_ip_route_unref (route);
|
||||
|
||||
if (!l || !l->next)
|
||||
ensure_empty_routes_row (page);
|
||||
}
|
||||
g_list_free (children);
|
||||
|
||||
|
|
|
@ -182,62 +182,47 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box3">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">24</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="heading_routes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Routes</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Automatic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="auto_routes_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="auto_routes_switch-accessible">
|
||||
<property name="accessible-name" translatable="yes">Automatic Routes</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -247,7 +232,76 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="routes_address_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<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="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<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="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<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="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<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">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -284,4 +338,16 @@
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="routes_metric_sizegroup">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
<widget name="routes_metric_label" />
|
||||
</widgets>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="routes_sizegroup">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
<widget name="routes_stub_box" />
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
|
@ -196,62 +196,47 @@
|
|||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box3">
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">24</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="heading_routes">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Routes</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="label" translatable="yes">Automatic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="auto_routes_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="auto_routes_switch-accessible">
|
||||
<property name="accessible-name" translatable="yes">Automatic Routes</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -261,7 +246,76 @@
|
|||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="routes_address_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<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="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<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="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hexpand">True</property>
|
||||
<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="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<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">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
|
@ -298,4 +352,16 @@
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="routes_metric_sizegroup">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
<widget name="routes_metric_label" />
|
||||
</widgets>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="routes_sizegroup">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
<widget name="routes_stub_box" />
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue