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), update_header, 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); 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_ip6_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_ip6_config_get_num_routes (page->setting); i++) { NMIP6Route *route; const struct in6_addr *tmp_addr; gchar address[INET6_ADDRSTRLEN + 1]; gchar gateway[INET6_ADDRSTRLEN + 1]; gint prefix, metric; route = nm_setting_ip6_config_get_route (page->setting, i); if (!route) continue; tmp_addr = nm_ip6_route_get_dest (route); (void) inet_ntop (AF_INET6, tmp_addr, &address[0], sizeof (address)); prefix = nm_ip6_route_get_prefix (route); tmp_addr = nm_ip6_route_get_next_hop (route); (void) inet_ntop (AF_INET6, tmp_addr, &gateway[0], sizeof (gateway)); metric = nm_ip6_route_get_metric (route); add_route_row (page, address, prefix, gateway, metric); } if (nm_setting_ip6_config_get_num_routes (page->setting) == 0) add_empty_route_row (page); gtk_widget_show_all (widget); }
void nm_ip6_config_hash (NMIP6Config *config, GChecksum *sum, gboolean dns_only) { guint32 i; const struct in6_addr *in6a; const char *s; g_return_if_fail (config != NULL); g_return_if_fail (sum != NULL); if (dns_only == FALSE) { for (i = 0; i < nm_ip6_config_get_num_addresses (config); i++) { NMIP6Address *a = nm_ip6_config_get_address (config, i); hash_in6addr (sum, nm_ip6_address_get_address (a)); hash_u32 (sum, nm_ip6_address_get_prefix (a)); hash_in6addr (sum, nm_ip6_address_get_gateway (a)); } for (i = 0; i < nm_ip6_config_get_num_routes (config); i++) { NMIP6Route *r = nm_ip6_config_get_route (config, i); hash_in6addr (sum, nm_ip6_route_get_dest (r)); hash_u32 (sum, nm_ip6_route_get_prefix (r)); hash_in6addr (sum, nm_ip6_route_get_next_hop (r)); hash_u32 (sum, nm_ip6_route_get_metric (r)); } in6a = nm_ip6_config_get_ptp_address (config); if (in6a) hash_in6addr (sum, in6a); } for (i = 0; i < nm_ip6_config_get_num_nameservers (config); i++) hash_in6addr (sum, nm_ip6_config_get_nameserver (config, i)); for (i = 0; i < nm_ip6_config_get_num_domains (config); i++) { s = nm_ip6_config_get_domain (config, i); g_checksum_update (sum, (const guint8 *) s, strlen (s)); } for (i = 0; i < nm_ip6_config_get_num_searches (config); i++) { s = nm_ip6_config_get_search (config, i); g_checksum_update (sum, (const guint8 *) s, strlen (s)); } }
gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix) { GSList *list, *iter; const GPtrArray *ptr_array; char **addr_arr = NULL; char **route_arr = NULL; char **dns_arr = NULL; char **domain_arr = NULL; int i = 0; guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0; guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0; guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0; if (cfg6 == NULL) return FALSE; nmc->allowed_fields = nmc_fields_ip6_config; nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_IP6_CONFIG_ALL, nmc->allowed_fields, NULL); print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ /* addresses */ list = (GSList *) nm_ip6_config_get_addresses (cfg6); addr_arr = g_new (char *, g_slist_length (list) + 1); for (iter = list; iter; iter = g_slist_next (iter)) { NMIP6Address *addr = (NMIP6Address *) iter->data; guint32 prefix; char *ip_str, *gw_str; ip_str = nmc_ip6_address_as_string (nm_ip6_address_get_address (addr), NULL); prefix = nm_ip6_address_get_prefix (addr); gw_str = nmc_ip6_address_as_string (nm_ip6_address_get_gateway (addr), NULL); addr_arr[i++] = g_strdup_printf ("ip = %s/%u, gw = %s", ip_str, prefix, gw_str); g_free (ip_str); g_free (gw_str); } addr_arr[i] = NULL; /* routes */ list = (GSList *) nm_ip6_config_get_routes (cfg6); route_arr = g_new (char *, g_slist_length (list) + 1); i = 0; for (iter = list; iter; iter = g_slist_next (iter)) { NMIP6Route *route = (NMIP6Route *) iter->data; guint32 prefix, metric; char *dest_str, *nexthop_str; dest_str = nmc_ip6_address_as_string (nm_ip6_route_get_dest (route), NULL); nexthop_str = nmc_ip6_address_as_string (nm_ip6_route_get_next_hop (route), NULL); prefix = nm_ip6_route_get_prefix (route); metric = nm_ip6_route_get_metric (route); route_arr[i++] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u", dest_str, prefix, nexthop_str, metric); g_free (dest_str); g_free (nexthop_str); } route_arr[i] = NULL; /* DNS */ list = (GSList *) nm_ip6_config_get_nameservers (cfg6); dns_arr = g_new (char *, g_slist_length (list) + 1); i = 0; for (iter = list; iter; iter = g_slist_next (iter)) dns_arr[i++] = nmc_ip6_address_as_string (iter->data, NULL); dns_arr[i] = NULL; /* domains */ ptr_array = nm_ip6_config_get_domains (cfg6); if (ptr_array) { domain_arr = g_new (char *, ptr_array->len + 1); for (i = 0; i < ptr_array->len; i++) domain_arr[i] = g_ptr_array_index (ptr_array, i); domain_arr[i] = NULL; } set_val_str (nmc->allowed_fields, 0, group_prefix); set_val_arr (nmc->allowed_fields, 1, (const char **) addr_arr); set_val_arr (nmc->allowed_fields, 2, (const char **) route_arr); set_val_arr (nmc->allowed_fields, 3, (const char **) dns_arr); set_val_arr (nmc->allowed_fields, 4, (const char **) domain_arr); nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX; print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ g_strfreev (addr_arr); g_strfreev (route_arr); g_strfreev (dns_arr); g_free (domain_arr); return TRUE; }
static GSList * construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix) { GSList *addresses = NULL, *routes = NULL, *dns = NULL, *iter; guint32 num; GString *tmp; GValue *val; if (ip6_config == NULL) return items; if (prefix == NULL) prefix = ""; /* IP addresses */ val = g_hash_table_lookup (ip6_config, "addresses"); if (val) addresses = nm_utils_ip6_addresses_from_gvalue (val); for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) { NMIP6Address *addr = (NMIP6Address *) iter->data; char str_addr[INET6_ADDRSTRLEN + 1]; char str_gw[INET6_ADDRSTRLEN + 1]; const struct in6_addr *tmp_addr; guint32 ip_prefix = nm_ip6_address_get_prefix (addr); char *addrtmp; memset (str_addr, 0, sizeof (str_addr)); tmp_addr = nm_ip6_address_get_address (addr); if (!inet_ntop (AF_INET6, &tmp_addr, str_addr, sizeof (str_addr))) continue; memset (str_gw, 0, sizeof (str_gw)); tmp_addr = nm_ip6_address_get_gateway (addr); inet_ntop (AF_INET6, &tmp_addr, str_gw, sizeof (str_gw)); addrtmp = g_strdup_printf ("%sIP6_ADDRESS_%d=%s/%d %s", prefix, num++, str_addr, ip_prefix, str_gw); items = g_slist_prepend (items, addrtmp); } if (num) items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ADDRESSES=%d", prefix, num)); if (addresses) { g_slist_foreach (addresses, (GFunc) nm_ip6_address_unref, NULL); g_slist_free (addresses); } /* DNS servers */ val = g_hash_table_lookup (ip6_config, "nameservers"); if (val) dns = nm_utils_ip6_dns_from_gvalue (val); if (g_slist_length (dns)) { tmp = g_string_new (NULL); g_string_append_printf (tmp, "%sIP6_NAMESERVERS=", prefix); for (iter = dns; iter; iter = g_slist_next (iter)) { const struct in6_addr *addr = iter->data; gboolean first = TRUE; char buf[INET6_ADDRSTRLEN + 1]; memset (buf, 0, sizeof (buf)); if (inet_ntop (AF_INET6, addr, buf, sizeof (buf))) { if (!first) g_string_append_c (tmp, ' '); g_string_append (tmp, buf); first = FALSE; } } items = g_slist_prepend (items, tmp->str); g_string_free (tmp, FALSE); } /* Search domains */ items = add_domains (items, ip6_config, prefix, '6'); /* Static routes */ val = g_hash_table_lookup (ip6_config, "routes"); if (val) routes = nm_utils_ip6_routes_from_gvalue (val); for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) { NMIP6Route *route = (NMIP6Route *) iter->data; char str_addr[INET6_ADDRSTRLEN + 1]; char str_nh[INET6_ADDRSTRLEN + 1]; const struct in6_addr *tmp_addr; guint32 ip_prefix = nm_ip6_route_get_prefix (route); guint32 metric = nm_ip6_route_get_metric (route); char *routetmp; memset (str_addr, 0, sizeof (str_addr)); tmp_addr = nm_ip6_route_get_dest (route); if (!inet_ntop (AF_INET6, &tmp_addr, str_addr, sizeof (str_addr))) continue; memset (str_nh, 0, sizeof (str_nh)); tmp_addr = nm_ip6_route_get_next_hop (route); inet_ntop (AF_INET6, &tmp_addr, str_nh, sizeof (str_nh)); routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_nh, metric); items = g_slist_prepend (items, routetmp); } if (num) items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ROUTES=%d", prefix, num)); if (routes) { g_slist_foreach (routes, (GFunc) nm_ip6_route_unref, NULL); g_slist_free (routes); } return items; }
/* This is exactly identical to nm_utils_merge_ip4_config, with s/4/6/, * except that we can't compare addresses with ==. */ void nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting) { int i, j; if (!setting) return; /* Defaults are just fine */ if (nm_setting_ip6_config_get_ignore_auto_dns (setting)) { nm_ip6_config_reset_nameservers (ip6_config); nm_ip6_config_reset_domains (ip6_config); nm_ip6_config_reset_searches (ip6_config); } if (nm_setting_ip6_config_get_ignore_auto_routes (setting)) nm_ip6_config_reset_routes (ip6_config); for (i = 0; i < nm_setting_ip6_config_get_num_dns (setting); i++) { const struct in6_addr *ns; gboolean found = FALSE; /* Avoid dupes */ ns = nm_setting_ip6_config_get_dns (setting, i); for (j = 0; j < nm_ip6_config_get_num_nameservers (ip6_config); j++) { if (ip6_addresses_equal (nm_ip6_config_get_nameserver (ip6_config, j), ns)) { found = TRUE; break; } } if (!found) nm_ip6_config_add_nameserver (ip6_config, ns); } /* DNS search domains */ for (i = 0; i < nm_setting_ip6_config_get_num_dns_searches (setting); i++) { const char *search = nm_setting_ip6_config_get_dns_search (setting, i); gboolean found = FALSE; /* Avoid dupes */ for (j = 0; j < nm_ip6_config_get_num_searches (ip6_config); j++) { if (!strcmp (search, nm_ip6_config_get_search (ip6_config, j))) { found = TRUE; break; } } if (!found) nm_ip6_config_add_search (ip6_config, search); } /* IPv6 addresses */ for (i = 0; i < nm_setting_ip6_config_get_num_addresses (setting); i++) { NMIP6Address *setting_addr = nm_setting_ip6_config_get_address (setting, i); guint32 num; num = nm_ip6_config_get_num_addresses (ip6_config); for (j = 0; j < num; j++) { NMIP6Address *cfg_addr = nm_ip6_config_get_address (ip6_config, j); /* Dupe, override with user-specified address */ if (ip6_addresses_equal (nm_ip6_address_get_address (cfg_addr), nm_ip6_address_get_address (setting_addr))) { nm_ip6_config_replace_address (ip6_config, j, setting_addr); break; } } if (j == num) nm_ip6_config_add_address (ip6_config, setting_addr); } /* IPv6 routes */ for (i = 0; i < nm_setting_ip6_config_get_num_routes (setting); i++) { NMIP6Route *setting_route = nm_setting_ip6_config_get_route (setting, i); guint32 num; num = nm_ip6_config_get_num_routes (ip6_config); for (j = 0; j < num; j++) { NMIP6Route *cfg_route = nm_ip6_config_get_route (ip6_config, j); /* Dupe, override with user-specified route */ if ( ip6_addresses_equal (nm_ip6_route_get_dest (cfg_route), nm_ip6_route_get_dest (setting_route)) && (nm_ip6_route_get_prefix (cfg_route) == nm_ip6_route_get_prefix (setting_route)) && ip6_addresses_equal (nm_ip6_route_get_next_hop (cfg_route), nm_ip6_route_get_next_hop (setting_route))) { nm_ip6_config_replace_route (ip6_config, j, setting_route); break; } } if (j == num) nm_ip6_config_add_route (ip6_config, setting_route); } if (nm_setting_ip6_config_get_never_default (setting)) nm_ip6_config_set_never_default (ip6_config, TRUE); }
gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_prefix, const char *one_field) { GSList *list, *iter; const GPtrArray *ptr_array; char **addr_arr = NULL; char **route_arr = NULL; char **dns_arr = NULL; char **domain_arr = NULL; int i = 0; NmcOutputField *tmpl, *arr; size_t tmpl_len; if (cfg6 == NULL) return FALSE; tmpl = nmc_fields_ip6_config; tmpl_len = sizeof (nmc_fields_ip6_config); nmc->print_fields.indices = parse_output_fields (one_field ? one_field : NMC_FIELDS_IP6_CONFIG_ALL, tmpl, FALSE, NULL, NULL); arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_FIELD_NAMES); g_ptr_array_add (nmc->output_data, arr); /* addresses */ list = (GSList *) nm_ip6_config_get_addresses (cfg6); addr_arr = g_new (char *, g_slist_length (list) + 1); for (iter = list; iter; iter = g_slist_next (iter)) { NMIP6Address *addr = (NMIP6Address *) iter->data; guint32 prefix; char *ip_str, *gw_str; ip_str = nmc_ip6_address_as_string (nm_ip6_address_get_address (addr), NULL); prefix = nm_ip6_address_get_prefix (addr); gw_str = nmc_ip6_address_as_string (nm_ip6_address_get_gateway (addr), NULL); addr_arr[i++] = g_strdup_printf ("ip = %s/%u, gw = %s", ip_str, prefix, gw_str); g_free (ip_str); g_free (gw_str); } addr_arr[i] = NULL; /* routes */ list = (GSList *) nm_ip6_config_get_routes (cfg6); route_arr = g_new (char *, g_slist_length (list) + 1); i = 0; for (iter = list; iter; iter = g_slist_next (iter)) { NMIP6Route *route = (NMIP6Route *) iter->data; guint32 prefix, metric; char *dest_str, *nexthop_str; dest_str = nmc_ip6_address_as_string (nm_ip6_route_get_dest (route), NULL); nexthop_str = nmc_ip6_address_as_string (nm_ip6_route_get_next_hop (route), NULL); prefix = nm_ip6_route_get_prefix (route); metric = nm_ip6_route_get_metric (route); route_arr[i++] = g_strdup_printf ("dst = %s/%u, nh = %s, mt = %u", dest_str, prefix, nexthop_str, metric); g_free (dest_str); g_free (nexthop_str); } route_arr[i] = NULL; /* DNS */ list = (GSList *) nm_ip6_config_get_nameservers (cfg6); dns_arr = g_new (char *, g_slist_length (list) + 1); i = 0; for (iter = list; iter; iter = g_slist_next (iter)) dns_arr[i++] = nmc_ip6_address_as_string (iter->data, NULL); dns_arr[i] = NULL; /* domains */ ptr_array = nm_ip6_config_get_domains (cfg6); if (ptr_array) { domain_arr = g_new (char *, ptr_array->len + 1); for (i = 0; i < ptr_array->len; i++) domain_arr[i] = g_strdup (g_ptr_array_index (ptr_array, i)); domain_arr[i] = NULL; } arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX); set_val_strc (arr, 0, group_prefix); set_val_arr (arr, 1, addr_arr); set_val_arr (arr, 2, route_arr); set_val_arr (arr, 3, dns_arr); set_val_arr (arr, 4, domain_arr); g_ptr_array_add (nmc->output_data, arr); print_data (nmc); /* Print all data */ /* Remove any previous data */ nmc_empty_output_fields (nmc); return TRUE; }
GtkWidget * ip6_routes_dialog_new (NMSettingIP6Config *s_ip6, gboolean automatic) { GtkBuilder *builder; GtkWidget *dialog, *widget, *ok_button; GtkListStore *store; GtkTreeIter model_iter; GtkTreeSelection *selection; gint offset; GtkTreeViewColumn *column; GtkCellRenderer *renderer; int i; GSList *renderers = NULL; GError* error = NULL; /* Initialize temporary storage vars */ g_free (last_edited); last_edited = NULL; last_path = NULL; g_free (last_path); last_column = -1; builder = gtk_builder_new (); if (!gtk_builder_add_from_file (builder, UIDIR "/ce-ip6-routes.ui", &error)) { g_warning ("Couldn't load builder file: %s", error->message); g_error_free (error); return NULL; } dialog = GTK_WIDGET (gtk_builder_get_object (builder, "ip6_routes_dialog")); if (!dialog) { g_warning ("%s: Couldn't load ip6 routes dialog from .ui file.", __func__); g_object_unref (builder); return NULL; } gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); g_object_set_data_full (G_OBJECT (dialog), "builder", builder, (GDestroyNotify) g_object_unref); ok_button = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button")); store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); /* Add existing routes */ for (i = 0; i < nm_setting_ip6_config_get_num_routes (s_ip6); i++) { NMIP6Route *route = nm_setting_ip6_config_get_route (s_ip6, i); const struct in6_addr *tmp_addr; char ip_string[INET6_ADDRSTRLEN]; char *tmp; if (!route) { g_warning ("%s: empty IP6 route structure!", __func__); continue; } gtk_list_store_append (store, &model_iter); tmp_addr = nm_ip6_route_get_dest (route); if (inet_ntop (AF_INET6, tmp_addr, ip_string, sizeof (ip_string))) gtk_list_store_set (store, &model_iter, COL_ADDRESS, ip_string, -1); tmp = g_strdup_printf ("%u", nm_ip6_route_get_prefix (route)); gtk_list_store_set (store, &model_iter, COL_PREFIX, tmp, -1); g_free (tmp); tmp_addr = nm_ip6_route_get_next_hop (route); if (tmp_addr && !IN6_IS_ADDR_UNSPECIFIED (tmp_addr) && inet_ntop (AF_INET6, tmp_addr, ip_string, sizeof (ip_string))) gtk_list_store_set (store, &model_iter, COL_NEXT_HOP, ip_string, -1); if (nm_ip6_route_get_metric (route)) { tmp = g_strdup_printf ("%u", nm_ip6_route_get_metric (route)); gtk_list_store_set (store, &model_iter, COL_METRIC, tmp, -1); g_free (tmp); } } widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip6_routes")); gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (store)); g_object_unref (store); /* IP Address column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_ADDRESS)); g_signal_connect (renderer, "editing-started", G_CALLBACK (ip6_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Address"), renderer, "text", COL_ADDRESS, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); /* Prefix column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_PREFIX)); g_signal_connect (renderer, "editing-started", G_CALLBACK (uint_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Prefix"), renderer, "text", COL_PREFIX, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); /* Gateway column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_NEXT_HOP)); g_signal_connect (renderer, "editing-started", G_CALLBACK (ip6_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Gateway"), renderer, "text", COL_NEXT_HOP, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); /* Metric column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_METRIC)); g_signal_connect (renderer, "editing-started", G_CALLBACK (uint_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Metric"), renderer, "text", COL_METRIC, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); g_object_set_data_full (G_OBJECT (dialog), "renderers", renderers, (GDestroyNotify) g_slist_free); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); g_signal_connect (selection, "changed", G_CALLBACK (list_selection_changed), GTK_WIDGET (gtk_builder_get_object (builder, "ip6_route_delete_button"))); g_signal_connect (widget, "button-press-event", G_CALLBACK (tree_view_button_pressed_cb), builder); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip6_route_add_button")); gtk_widget_set_sensitive (widget, TRUE); g_signal_connect (widget, "clicked", G_CALLBACK (route_add_clicked), builder); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip6_route_delete_button")); gtk_widget_set_sensitive (widget, FALSE); g_signal_connect (widget, "clicked", G_CALLBACK (route_delete_clicked), builder); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip6_ignore_auto_routes")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_ip6_config_get_ignore_auto_routes (s_ip6)); gtk_widget_set_sensitive (widget, automatic); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip6_never_default")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_ip6_config_get_never_default (s_ip6)); /* Update initial validity */ validate (dialog); return dialog; }