diff options
author | Matthias Clasen <mclasen@redhat.com> | 2012-12-17 14:17:42 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2012-12-21 21:57:31 -0500 |
commit | aee2cc08f711453b835b33f72b7c610daf8bb2cd (patch) | |
tree | 77a985aba974365394cd39a161af3282ff71d916 | |
parent | ea55585aa28abb3e1ef65d80585f81c953460098 (diff) | |
download | gnome-control-center-wip/network.tar.gz |
network: Implement the new design for wiredwip/network
This expands the connection editor to cover ethernet,
and adds support for multiple wired profiles.
19 files changed, 2050 insertions, 220 deletions
diff --git a/panels/network/Makefile.am b/panels/network/Makefile.am index dee5a004a..6785f6158 100644 --- a/panels/network/Makefile.am +++ b/panels/network/Makefile.am @@ -56,6 +56,7 @@ dist_ui_DATA = \ network-wifi.ui \ network-simple.ui \ network-mobile.ui \ + network-ethernet.ui \ network.ui @INTLTOOL_DESKTOP_RULE@ diff --git a/panels/network/connection-editor/Makefile.am b/panels/network/connection-editor/Makefile.am index 06e83f9fa..1755203ae 100644 --- a/panels/network/connection-editor/Makefile.am +++ b/panels/network/connection-editor/Makefile.am @@ -16,7 +16,11 @@ libconnection_editor_la_SOURCES = \ ce-page-security.h \ ce-page-security.c \ ce-page-reset.h \ - ce-page-reset.c + ce-page-reset.c \ + ce-page-ethernet.h \ + ce-page-ethernet.c \ + ce-page-8021x-security.h \ + ce-page-8021x-security.c libconnection_editor_la_CPPFLAGS = \ -I$(srcdir)/../wireless-security \ @@ -37,7 +41,8 @@ ui_DATA = \ ip4-page.ui \ ip6-page.ui \ reset-page.ui \ - security-page.ui + security-page.ui \ + ethernet-page.ui EXTRA_DIST = \ $(ui_DATA) diff --git a/panels/network/connection-editor/ce-page-8021x-security.c b/panels/network/connection-editor/ce-page-8021x-security.c new file mode 100644 index 000000000..ed716c8b4 --- /dev/null +++ b/panels/network/connection-editor/ce-page-8021x-security.c @@ -0,0 +1,188 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Dan Williams <dcbw@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include <string.h> + +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include <NetworkManager.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-8021x.h> +#include <nm-setting-wireless.h> +#include <nm-utils.h> + +#include "wireless-security.h" +#include "ce-page-ethernet.h" +#include "ce-page-8021x-security.h" + +G_DEFINE_TYPE (CEPage8021xSecurity, ce_page_8021x_security, CE_TYPE_PAGE) + +static void +enable_toggled (GtkToggleButton *button, gpointer user_data) +{ + CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (user_data); + + gtk_widget_set_sensitive (page->security_widget, gtk_toggle_button_get_active (page->enabled)); + ce_page_changed (CE_PAGE (page)); +} + +static void +stuff_changed (WirelessSecurity *sec, gpointer user_data) +{ + ce_page_changed (CE_PAGE (user_data)); +} + +static void +finish_setup (CEPage8021xSecurity *self, gpointer unused, GError *error, gpointer user_data) +{ + GtkWidget *parent; + + if (error) + return; + + self->security = (WirelessSecurity *) ws_wpa_eap_new (CE_PAGE (self)->connection, TRUE, FALSE); + if (!self->security) { + g_warning ("Could not load 802.1x user interface."); + return; + } + + wireless_security_set_changed_notify (self->security, stuff_changed, self); + self->security_widget = wireless_security_get_widget (self->security); + parent = gtk_widget_get_parent (self->security_widget); + if (parent) + gtk_container_remove (GTK_CONTAINER (parent), self->security_widget); + + gtk_toggle_button_set_active (self->enabled, self->initial_have_8021x); + g_signal_connect (self->enabled, "toggled", G_CALLBACK (enable_toggled), self); + gtk_widget_set_sensitive (self->security_widget, self->initial_have_8021x); + + gtk_box_pack_start (GTK_BOX (CE_PAGE (self)->page), GTK_WIDGET (self->enabled), FALSE, TRUE, 12); + gtk_box_pack_start (GTK_BOX (CE_PAGE (self)->page), self->security_widget, TRUE, TRUE, 0); + gtk_widget_show_all (CE_PAGE (self)->page); +} + +CEPage * +ce_page_8021x_security_new (NMConnection *connection, + NMClient *client, + NMRemoteSettings *settings) +{ + CEPage8021xSecurity *self; + + self = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY, + connection, + client, + settings, + NULL, + _("Security"))); + + CE_PAGE (self)->page = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + + g_object_ref_sink (G_OBJECT (CE_PAGE (self)->page)); + gtk_container_set_border_width (GTK_CONTAINER (CE_PAGE (self)->page), 6); + + if (nm_connection_get_setting_802_1x (connection)) + self->initial_have_8021x = TRUE; + + self->enabled = GTK_TOGGLE_BUTTON (gtk_check_button_new_with_mnemonic (_("Use 802.1_X security for this connection"))); + + g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL); + + if (self->initial_have_8021x) + CE_PAGE (self)->security_setting = NM_SETTING_802_1X_SETTING_NAME; + + return CE_PAGE (self); +} + +static gboolean +validate (CEPage *page, NMConnection *connection, GError **error) +{ + CEPage8021xSecurity *self = CE_PAGE_8021X_SECURITY (page); + gboolean valid = TRUE; + + if (gtk_toggle_button_get_active (self->enabled)) { + NMConnection *tmp_connection; + NMSetting *s_8021x; + + /* FIXME: get failed property and error out of wireless security objects */ + valid = wireless_security_validate (self->security, NULL); + if (valid) { + NMSetting *s_con; + + /* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */ + tmp_connection = nm_connection_new (); + nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ()); + + /* temp connection needs a 'connection' setting too, since most of + * the EAP methods need the UUID for CA cert ignore stuff. + */ + s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + nm_connection_add_setting (tmp_connection, nm_setting_duplicate (s_con)); + + ws_802_1x_fill_connection (self->security, "wpa_eap_auth_combo", tmp_connection); + + s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X); + nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x))); + + g_object_unref (tmp_connection); + } else + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Invalid 802.1x security"); + } else { + nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X); + valid = TRUE; + } + + return valid; +} + +static void +ce_page_8021x_security_init (CEPage8021xSecurity *self) +{ +} + +static void +dispose (GObject *object) +{ + CEPage8021xSecurity *self = CE_PAGE_8021X_SECURITY (object); + + if (self->security) { + wireless_security_unref (self->security); + self->security = NULL; + } + + G_OBJECT_CLASS (ce_page_8021x_security_parent_class)->dispose (object); +} + +static void +ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (security_class); + CEPageClass *parent_class = CE_PAGE_CLASS (security_class); + + /* virtual methods */ + object_class->dispose = dispose; + + parent_class->validate = validate; +} diff --git a/panels/network/connection-editor/ce-page-8021x-security.h b/panels/network/connection-editor/ce-page-8021x-security.h new file mode 100644 index 000000000..1432b0e10 --- /dev/null +++ b/panels/network/connection-editor/ce-page-8021x-security.h @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Dan Williams <dcbw@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2012 Red Hat, Inc. + */ + +#ifndef __CE_PAGE_8021X_SECURITY_H +#define __CE_PAGE_8021X_SECURITY_H + +#include <nm-connection.h> +#include "wireless-security.h" + +#include <glib.h> +#include <glib-object.h> + +#include "ce-page.h" + +#define CE_TYPE_PAGE_8021X_SECURITY (ce_page_8021x_security_get_type ()) +#define CE_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurity)) +#define CE_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass)) +#define CE_IS_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_8021X_SECURITY)) +#define CE_IS_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_8021X_SECURITY)) +#define CE_PAGE_8021X_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass)) + +typedef struct CEPage8021xSecurity CEPage8021xSecurity; +typedef struct CEPage8021xSecurityClass CEPage8021xSecurityClass; + +struct CEPage8021xSecurity { + CEPage parent; + + GtkToggleButton *enabled; + GtkWidget *security_widget; + WirelessSecurity *security; + + gboolean initial_have_8021x; +}; + +struct CEPage8021xSecurityClass { + CEPageClass parent; +}; + +GType ce_page_8021x_security_get_type (void); + +CEPage *ce_page_8021x_security_new (NMConnection *connection, + NMClient *client, + NMRemoteSettings *settings); + +#endif /* __CE_PAGE_8021X_SECURITY_H */ diff --git a/panels/network/connection-editor/ce-page-details.c b/panels/network/connection-editor/ce-page-details.c index 0beb55ff8..ff8edb4df 100644 --- a/panels/network/connection-editor/ce-page-details.c +++ b/panels/network/connection-editor/ce-page-details.c @@ -26,6 +26,7 @@ #include <nm-utils.h> #include <nm-device-wifi.h> +#include <nm-device-ethernet.h> #include "../panel-common.h" #include "ce-page-details.h" @@ -136,6 +137,7 @@ connect_details_page (CEPageDetails *page) NMDeviceState state; NMAccessPoint *active_ap; const gchar *str; + gboolean device_is_active; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_connect_switch")); @@ -150,12 +152,33 @@ connect_details_page (CEPageDetails *page) g_signal_connect (widget, "notify::active", G_CALLBACK (all_user_changed), page); - active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (page->device)); + if (NM_IS_DEVICE_WIFI (page->device)) + active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (page->device)); + else + active_ap = NULL; + state = nm_device_get_state (page->device); + device_is_active = FALSE; speed = 0; - if (page->ap == active_ap && state != NM_DEVICE_STATE_UNAVAILABLE) { - speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000; + if (active_ap && page->ap == active_ap && state != NM_DEVICE_STATE_UNAVAILABLE) { + device_is_active = TRUE; + if (NM_IS_DEVICE_WIFI (page->device)) + speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000; + } else { + NMActiveConnection *ac; + const gchar *p1, *p2; + + ac = nm_device_get_active_connection (page->device); + p1 = ac ? nm_active_connection_get_connection (ac) : NULL; + p2 = nm_connection_get_path (CE_PAGE (page)->connection); + if (g_strcmp0 (p1, p2) == 0) { + device_is_active = TRUE; + if (NM_IS_DEVICE_WIFI (page->device)) + speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000; + else if (NM_IS_DEVICE_ETHERNET (page->device)) + speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (page->device)); + } } if (speed > 0) str = g_strdup_printf (_("%d Mb/s"), speed); @@ -163,11 +186,15 @@ connect_details_page (CEPageDetails *page) str = NULL; panel_set_device_widget_details (CE_PAGE (page)->builder, "speed", str); - str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (page->device)); + if (NM_IS_DEVICE_WIFI (page->device)) + str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (page->device)); + else if (NM_IS_DEVICE_ETHERNET (page->device)) + str = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (page->device)); + panel_set_device_widget_details (CE_PAGE (page)->builder, "mac", str); str = NULL; - if (page->ap == active_ap) + if (device_is_active && active_ap) str = get_ap_security_string (active_ap); panel_set_device_widget_details (CE_PAGE (page)->builder, "security", str); @@ -190,12 +217,12 @@ connect_details_page (CEPageDetails *page) panel_set_device_widget_details (CE_PAGE (page)->builder, "strength", str); /* set IP entries */ - if (page->ap != active_ap) - panel_unset_device_widgets (CE_PAGE (page)->builder); - else + if (device_is_active) panel_set_device_widgets (CE_PAGE (page)->builder, page->device); + else + panel_unset_device_widgets (CE_PAGE (page)->builder); - if (page->ap != active_ap && CE_PAGE (page)->connection) + if (!device_is_active && CE_PAGE (page)->connection) update_last_used (page, CE_PAGE (page)->connection); else panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", NULL); diff --git a/panels/network/connection-editor/ce-page-ethernet.c b/panels/network/connection-editor/ce-page-ethernet.c new file mode 100644 index 000000000..d11b7cbe1 --- /dev/null +++ b/panels/network/connection-editor/ce-page-ethernet.c @@ -0,0 +1,304 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <glib-object.h> +#include <glib/gi18n.h> + +#include <nm-utils.h> +#include <nm-device-ethernet.h> + +#include <net/if_arp.h> + +#include "ce-page-ethernet.h" + +G_DEFINE_TYPE (CEPageEthernet, ce_page_ethernet, CE_TYPE_PAGE) + +enum { + PORT_DEFAULT, + PORT_TP, + PORT_AUI, + PORT_BNC, + PORT_MII +}; + +enum { + SPEED_DEFAULT, + SPEED_10, + SPEED_100, + SPEED_1000, + SPEED_10000 +}; + +static void +connect_ethernet_page (CEPageEthernet *page) +{ + NMSettingWired *setting = page->setting_wired; + const char *port; + const char *duplex; + int port_idx = PORT_DEFAULT; + int speed_idx; + int mtu_def; + char **mac_list; + const GByteArray *s_mac; + char *s_mac_str; + GtkWidget *widget; + const gchar *name; + + name = nm_setting_connection_get_id (page->setting_connection); + gtk_entry_set_text (page->name, name); + + /* Port */ + port = nm_setting_wired_get_port (setting); + if (port) { + if (!strcmp (port, "tp")) + port_idx = PORT_TP; + else if (!strcmp (port, "aui")) + port_idx = PORT_AUI; + else if (!strcmp (port, "bnc")) + port_idx = PORT_BNC; + else if (!strcmp (port, "mii")) + port_idx = PORT_MII; + } + gtk_combo_box_set_active (page->port, port_idx); + + /* Speed */ + switch (nm_setting_wired_get_speed (setting)) { + case 10: + speed_idx = SPEED_10; + break; + case 100: + speed_idx = SPEED_100; + break; + case 1000: + speed_idx = SPEED_1000; + break; + case 10000: + speed_idx = SPEED_10000; + break; + default: + speed_idx = SPEED_DEFAULT; + break; + } + gtk_combo_box_set_active (page->speed, speed_idx); + /* Duplex */ + duplex = nm_setting_wired_get_duplex (setting); + if (duplex && !strcmp (duplex, "half")) + gtk_toggle_button_set_active (page->duplex, FALSE); + else + gtk_toggle_button_set_active (page->duplex, TRUE); + + /* Autonegotiate */ + gtk_toggle_button_set_active (page->autonegotiate, + nm_setting_wired_get_auto_negotiate (setting)); + + /* Device MAC address */ + mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_ETHERNET, + NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS); + s_mac = nm_setting_wired_get_mac_address (setting); + s_mac_str = s_mac ? nm_utils_hwaddr_ntoa (s_mac->data, ARPHRD_ETHER) : NULL; + ce_page_setup_mac_combo (page->device_mac, s_mac_str, mac_list); + g_free (s_mac_str); + g_strfreev (mac_list); + g_signal_connect_swapped (page->device_mac, "changed", G_CALLBACK (ce_page_changed), page); + + /* Cloned MAC address */ + ce_page_mac_to_entry (nm_setting_wired_get_cloned_mac_address (setting), + ARPHRD_ETHER, page->cloned_mac); + g_signal_connect_swapped (page->cloned_mac, "changed", G_CALLBACK (ce_page_changed), page); + + /* MTU */ + mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRED_MTU); + g_signal_connect (page->mtu, "output", + G_CALLBACK (ce_spin_output_with_default), + GINT_TO_POINTER (mtu_def)); + + gtk_spin_button_set_value (page->mtu, (gdouble) nm_setting_wired_get_mtu (setting)); + + g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (page->port, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (page->speed, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (page->duplex, "toggled", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (page->autonegotiate, "toggled", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (page->mtu, "value-changed", G_CALLBACK (ce_page_changed), page); + + /* Hide widgets we don't yet support */ + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_port")); + gtk_widget_hide (widget); + gtk_widget_hide (GTK_WIDGET (page->port)); + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_speed")); + gtk_widget_hide (widget); + gtk_widget_hide (GTK_WIDGET (page->speed)); + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "check_duplex")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "check_renegotiate")); + gtk_widget_hide (widget); +} + +static void +ui_to_setting (CEPageEthernet *page) +{ + const char *port; + guint32 speed; + GByteArray *device_mac = NULL; + GByteArray *cloned_mac = NULL; + GtkWidget *entry; + + /* Port */ + switch (gtk_combo_box_get_active (page->port)) { + case PORT_TP: + port = "tp"; + break; + case PORT_AUI: + port = "aui"; + break; + case PORT_BNC: + port = "bnc"; + break; + case PORT_MII: + port = "mii"; + break; + default: + port = NULL; + break; + } + + /* Speed */ + switch (gtk_combo_box_get_active (page->speed)) { + case SPEED_10: + speed = 10; + break; + case SPEED_100: + speed = 100; + break; + case SPEED_1000: + speed = 1000; + break; + case SPEED_10000: + speed = 10000; + break; + default: + speed = 0; + break; + } + + entry = gtk_bin_get_child (GTK_BIN (page->device_mac)); + if (entry) + device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL); + cloned_mac = ce_page_entry_to_mac (page->cloned_mac, ARPHRD_ETHER, NULL); + + g_object_set (page->setting_wired, + NM_SETTING_WIRED_MAC_ADDRESS, device_mac, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac, + NM_SETTING_WIRED_PORT, port, + NM_SETTING_WIRED_SPEED, speed, + NM_SETTING_WIRED_DUPLEX, gtk_toggle_button_get_active (page->duplex) ? "full" : "half", + NM_SETTING_WIRED_AUTO_NEGOTIATE, gtk_toggle_button_get_active (page->autonegotiate), + NM_SETTING_WIRED_MTU, (guint32) gtk_spin_button_get_value_as_int (page->mtu), + NULL); + + if (device_mac) + g_byte_array_free (device_mac, TRUE); + if (cloned_mac) + g_byte_array_free (cloned_mac, TRUE); + + g_object_set (page->setting_connection, + NM_SETTING_CONNECTION_ID, gtk_entry_get_text (page->name), + NULL); +} + +static gboolean +validate (CEPage *page, + NMConnection *connection, + GError **error) +{ + CEPageEthernet *self = CE_PAGE_ETHERNET (page); + gboolean invalid = FALSE; + GByteArray *ignore; + GtkWidget *entry; + + entry = gtk_bin_get_child (GTK_BIN (self->device_mac)); + if (entry) { + ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid); + if (invalid) + return FALSE; + if (ignore) + g_byte_array_free (ignore, TRUE); + } + + ignore = ce_page_entry_to_mac (self->cloned_mac, ARPHRD_ETHER, &invalid); + if (invalid) + return FALSE; + if (ignore) + g_byte_array_free (ignore, TRUE); + + ui_to_setting (self); + + return nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error) && + nm_setting_verify (NM_SETTING (self->setting_wired), NULL, error); +} + +static void +ce_page_ethernet_init (CEPageEthernet *page) +{ +} + +static void +ce_page_ethernet_class_init (CEPageEthernetClass *class) +{ + CEPageClass *page_class= CE_PAGE_CLASS (class); + + page_class->validate = validate; +} + +CEPage * +ce_page_ethernet_new (NMConnection *connection, + NMClient *client, + NMRemoteSettings *settings) +{ + CEPageEthernet *page; + + page = CE_PAGE_ETHERNET (ce_page_new (CE_TYPE_PAGE_ETHERNET, + connection, + client, + settings, + GNOMECC_UI_DIR "/ethernet-page.ui", + _("Identity"))); + + page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name")); + page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")); + page->cloned_mac = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); + page->port = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_port")); + page->speed = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_speed")); + page->duplex = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "check_duplex")); + page->autonegotiate = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "check_renegotiate")); + page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu")); + + page->setting_connection = nm_connection_get_setting_connection (connection); + page->setting_wired = nm_connection_get_setting_wired (connection); + + connect_ethernet_page (page); + + return CE_PAGE (page); +} diff --git a/panels/network/connection-editor/ce-page-ethernet.h b/panels/network/connection-editor/ce-page-ethernet.h new file mode 100644 index 000000000..3f0942e43 --- /dev/null +++ b/panels/network/connection-editor/ce-page-ethernet.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more ethernet. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_ETHERNET_H +#define __CE_PAGE_ETHERNET_H + +#include <glib-object.h> + +#include <nm-setting-wired.h> + +#include <gtk/gtk.h> +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_ETHERNET (ce_page_ethernet_get_type ()) +#define CE_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernet)) +#define CE_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass)) +#define CE_IS_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_ETHERNET)) +#define CE_IS_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_ETHERNET)) +#define CE_PAGE_ETHERNET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass)) + +typedef struct _CEPageEthernet CEPageEthernet; +typedef struct _CEPageEthernetClass CEPageEthernetClass; + +struct _CEPageEthernet +{ + CEPage parent; + + NMSettingConnection *setting_connection; + NMSettingWired *setting_wired; + + GtkEntry *name; + GtkComboBoxText *device_mac; + GtkEntry *cloned_mac; + GtkComboBox *port; + GtkComboBox *speed; + GtkToggleButton *duplex; + GtkToggleButton *autonegotiate; + GtkSpinButton *mtu; +}; + +struct _CEPageEthernetClass +{ + CEPageClass parent_class; +}; + +GType ce_page_ethernet_get_type (void); + +CEPage *ce_page_ethernet_new (NMConnection *connection, + NMClient *client, + NMRemoteSettings *settings); + +G_END_DECLS + +#endif /* __CE_PAGE_ETHERNET_H */ + diff --git a/panels/network/connection-editor/ce-page-ip4.c b/panels/network/connection-editor/ce-page-ip4.c index 7a7e862eb..5cdb08040 100644 --- a/panels/network/connection-editor/ce-page-ip4.c +++ b/panels/network/connection-editor/ce-page-ip4.c @@ -894,6 +894,10 @@ ce_page_ip4_new (NMConnection *connection, _("IPv4"))); page->setting = nm_connection_get_setting_ip4_config (connection); + if (!page->setting) { + page->setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + nm_connection_add_setting (connection, NM_SETTING (page->setting)); + } connect_ip4_page (page); diff --git a/panels/network/connection-editor/ce-page-ip6.c b/panels/network/connection-editor/ce-page-ip6.c index 06c0214cf..099d2071b 100644 --- a/panels/network/connection-editor/ce-page-ip6.c +++ b/panels/network/connection-editor/ce-page-ip6.c @@ -855,6 +855,10 @@ ce_page_ip6_new (NMConnection *connection, _("IPv6"))); page->setting = nm_connection_get_setting_ip6_config (connection); + if (!page->setting) { + page->setting = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + nm_connection_add_setting (connection, NM_SETTING (page->setting)); + } connect_ip6_page (page); diff --git a/panels/network/connection-editor/ce-page.c b/panels/network/connection-editor/ce-page.c index 4794a5fda..f6c1f4013 100644 --- a/panels/network/connection-editor/ce-page.c +++ b/panels/network/connection-editor/ce-page.c @@ -28,6 +28,8 @@ #include <nm-utils.h> +#include <glib/gi18n.h> + #include "ce-page.h" @@ -224,20 +226,23 @@ ce_page_new (GType type, page->title = g_strdup (title); page->client = client; page->settings= settings; - if (!gtk_builder_add_from_file (page->builder, ui_file, &error)) { - g_warning ("Couldn't load builder file: %s", error->message); - g_error_free (error); - g_object_unref (page); - return NULL; - } - page->page = GTK_WIDGET (gtk_builder_get_object (page->builder, "page")); - if (!page->page) { - g_warning ("Couldn't load page widget from %s", ui_file); - g_object_unref (page); - return NULL; - } - g_object_ref_sink (page->page); + if (ui_file) { + if (!gtk_builder_add_from_file (page->builder, ui_file, &error)) { + g_warning ("Couldn't load builder file: %s", error->message); + g_error_free (error); + g_object_unref (page); + return NULL; + } + page->page = GTK_WIDGET (gtk_builder_get_object (page->builder, "page")); + if (!page->page) { + g_warning ("Couldn't load page widget from %s", ui_file); + g_object_unref (page); + return NULL; + } + + g_object_ref_sink (page->page); + } return page; } @@ -452,3 +457,92 @@ ce_page_get_security_setting (CEPage *page) { return page->security_setting; } + +gint +ce_get_property_default (NMSetting *setting, const gchar *property_name) +{ + GParamSpec *spec; + GValue value = { 0, }; + + spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); + g_return_val_if_fail (spec != NULL, -1); + + g_value_init (&value, spec->value_type); + g_param_value_set_default (spec, &value); + + if (G_VALUE_HOLDS_CHAR (&value)) + return (int) g_value_get_schar (&value); + else if (G_VALUE_HOLDS_INT (&value)) + return g_value_get_int (&value); + else if (G_VALUE_HOLDS_INT64 (&value)) + return (int) g_value_get_int64 (&value); + else if (G_VALUE_HOLDS_LONG (&value)) + return (int) g_value_get_long (&value); + else if (G_VALUE_HOLDS_UINT (&value)) + return (int) g_value_get_uint (&value); + else if (G_VALUE_HOLDS_UINT64 (&value)) + return (int) g_value_get_uint64 (&value); + else if (G_VALUE_HOLDS_ULONG (&value)) + return (int) g_value_get_ulong (&value); + else if (G_VALUE_HOLDS_UCHAR (&value)) + return (int) g_value_get_uchar (&value); + g_return_val_if_fail (FALSE, 0); + return 0; +} + +gint +ce_spin_output_with_default (GtkSpinButton *spin, gpointer user_data) +{ + gint defvalue = GPOINTER_TO_INT (user_data); + gint val; + gchar *buf = NULL; + + val = gtk_spin_button_get_value_as_int (spin); + if (val == defvalue) + buf = g_strdup (_("automatic")); + else + buf = g_strdup_printf ("%d", val); + + if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin)))) + gtk_entry_set_text (GTK_ENTRY (spin), buf); + + g_free (buf); + return TRUE; +} + +gchar * +ce_page_get_next_available_name (GSList *connections, const gchar *format) +{ + GSList *names = NULL, *l; + gchar *cname = NULL; + gint i = 0; + + for (l = connections; l; l = l->next) { + const gchar *id; + + id = nm_connection_get_id (NM_CONNECTION (l->data)); + g_assert (id); + names = g_slist_append (names, (gpointer) id); + } + + /* Find the next available unique connection name */ + while (!cname && (i++ < 10000)) { + gchar *temp; + gboolean found = FALSE; + + temp = g_strdup_printf (format, i); + for (l = names; l; l = l->next) { + if (!strcmp (l->data, temp)) { + found = TRUE; + break; + } + } + if (!found) + cname = temp; + else + g_free (temp); + } + g_slist_free (names); + + return cname; +} diff --git a/panels/network/connection-editor/ce-page.h b/panels/network/connection-editor/ce-page.h index 2de2adafd..58cd41d9b 100644 --- a/panels/network/connection-editor/ce-page.h +++ b/panels/network/connection-editor/ce-page.h @@ -99,6 +99,14 @@ void ce_page_mac_to_entry (const GByteArray *mac, GByteArray *ce_page_entry_to_mac (GtkEntry *entry, gint type, gboolean *invalid); +gint ce_get_property_default (NMSetting *setting, + const gchar *property_name); +gint ce_spin_output_with_default (GtkSpinButton *spin, + gpointer user_data); + +gchar * ce_page_get_next_available_name (GSList *connections, const gchar *format); + + G_END_DECLS diff --git a/panels/network/connection-editor/ethernet-page.ui b/panels/network/connection-editor/ethernet-page.ui new file mode 100644 index 000000000..477b0ad1e --- /dev/null +++ b/panels/network/connection-editor/ethernet-page.ui @@ -0,0 +1,315 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <!-- interface-requires gtk+ 3.0 --> + <object class="GtkAdjustment" id="adjustment1"> + <property name="upper">10000</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkListStore" id="model1"> + <columns> + <!-- column-name gchararray1 --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Automatic</col> + </row> + <row> + <col id="0" translatable="yes">Twisted Pair (TP)</col> + </row> + <row> + <col id="0" translatable="yes">Attachment Unit Interface (AUI)</col> + </row> + <row> + <col id="0" translatable="yes">BNC</col> + </row> + <row> + <col id="0" translatable="yes">Media Independent Interface (MII)</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model2"> + <columns> + <!-- column-name < --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes">Automatic</col> + </row> + <row> + <col id="0" translatable="yes">10 Mb/s</col> + </row> + <row> + <col id="0" translatable="yes">100 Mb/s</col> + </row> + <row> + <col id="0" translatable="yes">1 Gb/s</col> + </row> + <row> + <col id="0" translatable="yes">10 Gb/s</col> + </row> + </data> + </object> + <object class="GtkGrid" id="page"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">50</property> + <property name="margin_right">50</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="row_spacing">10</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkLabel" id="heading_mtu"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_MTU</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">spin_mtu</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">7</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkSpinButton" id="spin_mtu"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">ā</property> + <property name="adjustment">adjustment1</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_mtu"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">bytes</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">7</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_cloned_mac"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">_Cloned MAC Address</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_cloned_mac</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">6</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_mac"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_MAC Address</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">combo_mac</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">5</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_cloned_mac"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="invisible_char">ā</property> + <property name="invisible_char_set">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">6</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkComboBoxText" id="combo_mac"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="has_entry">True</property> + <property name="entry_text_column">0</property> + <property name="id_column">1</property> + <child internal-child="entry"> + <object class="GtkEntry" id="comboboxtext-entry2"> + <property name="can_focus">False</property> + <property name="invisible_char">ā</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">5</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_port"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Port</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">combo_port</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_speed"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Speed</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">combo_speed</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check_duplex"> + <property name="label" translatable="yes">_Full duplex</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check_renegotiate"> + <property name="label" translatable="yes">_Automatic renegotiation</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combo_port"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">model1</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combo_speed"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">model2</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_name"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Name</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_name</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_name"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="invisible_char">ā</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> +</interface> diff --git a/panels/network/connection-editor/net-connection-editor.c b/panels/network/connection-editor/net-connection-editor.c index b3d067239..b4b50346c 100644 --- a/panels/network/connection-editor/net-connection-editor.c +++ b/panels/network/connection-editor/net-connection-editor.c @@ -34,6 +34,8 @@ #include "ce-page-ip6.h" #include "ce-page-security.h" #include "ce-page-reset.h" +#include "ce-page-ethernet.h" +#include "ce-page-8021x-security.h" #include "egg-list-box/egg-list-box.h" @@ -87,7 +89,9 @@ update_complete (NetConnectionEditor *editor, GError *error) } static void -updated_connection_cb (NMRemoteConnection *connection, GError *error, gpointer data) +updated_connection_cb (NMRemoteConnection *connection, + GError *error, + gpointer data) { NetConnectionEditor *editor = data; @@ -97,11 +101,36 @@ updated_connection_cb (NMRemoteConnection *connection, GError *error, gpointer d } static void +added_connection_cb (NMRemoteSettings *settings, + NMRemoteConnection *connection, + GError *error, + gpointer data) +{ + NetConnectionEditor *editor = data; + + if (error) { + g_warning ("Failed to add connection: %s", error->message); + /* Leave the editor open */ + return; + } + + update_complete (editor, error); +} + +static void apply_edits (NetConnectionEditor *editor) { update_connection (editor); - nm_remote_connection_commit_changes (NM_REMOTE_CONNECTION (editor->orig_connection), - updated_connection_cb, editor); + + if (!nm_remote_settings_get_connection_by_uuid (editor->settings, nm_connection_get_uuid (editor->orig_connection))) + nm_remote_settings_add_connection (editor->settings, + editor->orig_connection, + added_connection_cb, + editor); + else { + nm_remote_connection_commit_changes (NM_REMOTE_CONNECTION (editor->orig_connection), + updated_connection_cb, editor); + } } static void @@ -191,8 +220,12 @@ net_connection_editor_update_title (NetConnectionEditor *editor) gchar *id; sw = nm_connection_get_setting_wireless (editor->connection); - ssid = nm_setting_wireless_get_ssid (sw); - id = nm_utils_ssid_to_utf8 (ssid); + if (sw) { + ssid = nm_setting_wireless_get_ssid (sw); + id = nm_utils_ssid_to_utf8 (ssid); + } else { + id = g_strdup (nm_connection_get_id (editor->connection)); + } gtk_window_set_title (GTK_WINDOW (editor->window), id); g_free (id); } @@ -385,17 +418,31 @@ net_connection_editor_set_connection (NetConnectionEditor *editor, NMConnection *connection) { GSList *pages, *l; + NMSettingConnection *sc; + const gchar *type; editor->connection = nm_connection_duplicate (connection); editor->orig_connection = g_object_ref (connection); net_connection_editor_update_title (editor); + sc = nm_connection_get_setting_connection (connection); + type = nm_setting_connection_get_connection_type (sc); + add_page (editor, ce_page_details_new (editor->connection, editor->client, editor->settings, editor->device, editor->ap)); - add_page (editor, ce_page_wifi_new (editor->connection, editor->client, editor->settings)); + if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0) + add_page (editor, ce_page_wifi_new (editor->connection, editor->client, editor->settings)); + else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0) + add_page (editor, ce_page_ethernet_new (editor->connection, editor->client, editor->settings)); + add_page (editor, ce_page_ip4_new (editor->connection, editor->client, editor->settings)); add_page (editor, ce_page_ip6_new (editor->connection, editor->client, editor->settings)); - add_page (editor, ce_page_security_new (editor->connection, editor->client, editor->settings)); + + if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0) + add_page (editor, ce_page_security_new (editor->connection, editor->client, editor->settings)); + else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0) + add_page (editor, ce_page_8021x_security_new (editor->connection, editor->client, editor->settings)); + add_page (editor, ce_page_reset_new (editor->connection, editor->client, editor->settings, editor)); pages = g_slist_copy (editor->initializing_pages); diff --git a/panels/network/net-device-ethernet.c b/panels/network/net-device-ethernet.c index 3ac6faa35..f3ef7744d 100644 --- a/panels/network/net-device-ethernet.c +++ b/panels/network/net-device-ethernet.c @@ -28,9 +28,14 @@ #include <nm-device.h> #include <nm-device-ethernet.h> #include <nm-remote-connection.h> +#include <nm-utils.h> #include "panel-common.h" +#include "egg-list-box/egg-list-box.h" +#include "connection-editor/net-connection-editor.h" +#include "connection-editor/ce-page.h" + #include "net-device-ethernet.h" G_DEFINE_TYPE (NetDeviceEthernet, net_device_ethernet, NET_TYPE_DEVICE_SIMPLE) @@ -51,15 +56,459 @@ device_ethernet_get_speed (NetDeviceSimple *device_simple) return NULL; } +static GSList * +valid_connections_for_device (NMRemoteSettings *remote_settings, + NetDevice *device) +{ + GSList *all, *filtered, *iterator, *valid; + NMConnection *connection; + NMSettingConnection *s_con; + + all = nm_remote_settings_list_connections (remote_settings); + filtered = nm_device_filter_connections (net_device_get_nm_device (device), all); + g_slist_free (all); + + valid = NULL; + for (iterator = filtered; iterator; iterator = iterator->next) { + connection = iterator->data; + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) + continue; + + if (nm_setting_connection_get_master (s_con)) + continue; + + valid = g_slist_prepend (valid, connection); + } + g_slist_free (filtered); + + return g_slist_reverse (valid); +} + +static GtkWidget * +device_ethernet_add_to_notebook (NetObject *object, + GtkNotebook *notebook, + GtkSizeGroup *heading_size_group) +{ + NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); + GtkWidget *vbox; + + vbox = GTK_WIDGET (gtk_builder_get_object (device->builder, "vbox6")); + g_object_ref (vbox); + gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (vbox)), vbox); + gtk_notebook_append_page (notebook, vbox, NULL); + g_object_unref (vbox); + return vbox; +} + +static void +add_details_row (GtkWidget *details, gint top, const gchar *heading, const gchar *value) +{ + GtkWidget *label; + + label = gtk_label_new (heading); + gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label"); + gtk_widget_set_halign (label, GTK_ALIGN_END); + gtk_widget_set_hexpand (label, TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); + + gtk_grid_attach (GTK_GRID (details), label, 0, top, 1, 1); + + label = gtk_label_new (value); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_widget_set_hexpand (label, TRUE); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + + gtk_grid_attach (GTK_GRID (details), label, 1, top, 1, 1); +} + +static gchar * +get_last_used_string (NMConnection *connection) +{ + gchar *last_used = NULL; + GDateTime *now = NULL; + GDateTime *then = NULL; + gint days; + GTimeSpan diff; + guint64 timestamp; + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + if (s_con == NULL) + goto out; + timestamp = nm_setting_connection_get_timestamp (s_con); + if (timestamp == 0) { + last_used = g_strdup (_("never")); + goto out; + } + + /* calculate the amount of time that has elapsed */ + now = g_date_time_new_now_utc (); + then = g_date_time_new_from_unix_utc (timestamp); + diff = g_date_time_difference (now, then); + days = diff / G_TIME_SPAN_DAY; + if (days == 0) + last_used = g_strdup (_("today")); + else if (days == 1) + last_used = g_strdup (_("yesterday")); + else + last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days); +out: + if (now != NULL) + g_date_time_unref (now); + if (then != NULL) + g_date_time_unref (then); + + return last_used; +} + +static void +add_details (GtkWidget *details, NMDevice *device, NMConnection *connection) +{ + NMIP4Config *ip4_config = NULL; + NMIP6Config *ip6_config = NULL; + gchar *ip4_address = NULL; + gchar *ip4_route = NULL; + gchar *ip4_dns = NULL; + gchar *ip6_address = NULL; + gint i = 0; + + ip4_config = nm_device_get_ip4_config (device); + if (ip4_config) { + ip4_address = panel_get_ip4_address_as_string (ip4_config, "address"); + ip4_route = panel_get_ip4_address_as_string (ip4_config, "gateway"); + ip4_dns = panel_get_ip4_dns_as_string (ip4_config); + } + ip6_config = nm_device_get_ip6_config (device); + if (ip6_config) { + ip6_address = panel_get_ip6_address_as_string (ip6_config); + } + + if (ip4_address && ip6_address) { + add_details_row (details, i++, _("IP4 Address"), ip4_address); + add_details_row (details, i++, _("IP6 Address"), ip6_address); + } else if (ip4_address) { + add_details_row (details, i++, _("IP Address"), ip4_address); + } else if (ip6_address) { + add_details_row (details, i++, _("IP Address"), ip6_address); + } + + add_details_row (details, i++, _("Hardware Address"), + nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device))); + + if (ip4_route) + add_details_row (details, i++, _("Default Route"), ip4_route); + if (ip4_dns) + add_details_row (details, i++, _("DNS"), ip4_dns); + + if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) { + gchar *last_used; + last_used = get_last_used_string (connection); + add_details_row (details, i++, _("Last used"), last_used); + g_free (last_used); + } + + g_free (ip4_address); + g_free (ip4_route); + g_free (ip4_dns); + g_free (ip6_address); +} + +static void populate_ui (NetDeviceEthernet *device); + +static void +editor_done (NetConnectionEditor *editor, + gboolean success, + NetDeviceEthernet *device) +{ + g_object_unref (editor); + populate_ui (device); +} + +static void +show_details_for_row (GtkButton *button, NetDeviceEthernet *device) +{ + GtkWidget *row; + NMConnection *connection; + GtkWidget *window; + NetConnectionEditor *editor; + NMClient *client; + NMRemoteSettings *settings; + NMDevice *nmdev; + + window = gtk_widget_get_toplevel (GTK_WIDGET (button)); + + row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row")); + connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection")); + + nmdev = net_device_get_nm_device (NET_DEVICE (device)); + client = net_object_get_client (NET_OBJECT (device)); + settings = net_object_get_remote_settings (NET_OBJECT (device)); + editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings); + g_signal_connect (editor, "done", G_CALLBACK (editor_done), device); + net_connection_editor_run (editor); +} + +static void +add_row (NetDeviceEthernet *device, NMConnection *connection) +{ + GtkWidget *row; + GtkWidget *widget; + GtkWidget *box; + GtkWidget *details; + NMDevice *nmdev; + NMActiveConnection *aconn; + gboolean active; + GtkWidget *image; + + active = FALSE; + + nmdev = net_device_get_nm_device (NET_DEVICE (device)); + aconn = nm_device_get_active_connection (nmdev); + if (aconn) { + const gchar *path1, *path2; + path1 = nm_active_connection_get_connection (aconn); + path2 = nm_connection_get_path (connection); + active = g_strcmp0 (path1, path2) == 0; + } + + row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (row), box, FALSE, TRUE, 0); + widget = gtk_label_new (nm_connection_get_id (connection)); + gtk_widget_set_margin_left (widget, 12); + gtk_widget_set_margin_right (widget, 12); + gtk_widget_set_margin_top (widget, 12); + gtk_widget_set_margin_bottom (widget, 12); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); + + if (active) { + widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); + + details = gtk_grid_new (); + gtk_grid_set_row_spacing (GTK_GRID (details), 10); + gtk_grid_set_column_spacing (GTK_GRID (details), 10); + + gtk_box_pack_start (GTK_BOX (row), details, FALSE, TRUE, 0); + + add_details (details, nmdev, connection); + } + + /* filler */ + widget = gtk_label_new (""); + gtk_widget_set_hexpand (widget, TRUE); + gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0); + + image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + widget = gtk_button_new (); + gtk_widget_set_margin_left (widget, 12); + gtk_widget_set_margin_right (widget, 12); + gtk_widget_set_margin_top (widget, 12); + gtk_widget_set_margin_bottom (widget, 12); + gtk_widget_show (widget); + gtk_container_add (GTK_CONTAINER (widget), image); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); + g_object_set_data (G_OBJECT (row), "edit", widget); + g_object_set_data (G_OBJECT (widget), "row", row); + g_signal_connect (widget, "clicked", + G_CALLBACK (show_details_for_row), device); + + gtk_widget_show_all (row); + + g_object_set_data (G_OBJECT (row), "connection", connection); + + gtk_container_add (GTK_CONTAINER (device->list), row); +} + +static void +populate_ui (NetDeviceEthernet *device) +{ + NMRemoteSettings *settings; + GList *children, *c; + GSList *connections, *l; + NMConnection *connection; + gint n_connections; + + children = gtk_container_get_children (GTK_CONTAINER (device->list)); + for (c = children; c; c = c->next) { + gtk_container_remove (GTK_CONTAINER (device->list), c->data); + } + g_list_free (children); + + children = gtk_container_get_children (GTK_CONTAINER (device->details)); + for (c = children; c; c = c->next) { + gtk_container_remove (GTK_CONTAINER (device->details), c->data); + } + g_list_free (children); + + settings = net_object_get_remote_settings (NET_OBJECT (device)); + connections = valid_connections_for_device (settings, NET_DEVICE (device)); + + n_connections = g_slist_length (connections); + if (n_connections > 1) { + gtk_widget_hide (device->details); + gtk_widget_hide (device->details_button); + for (l = connections; l; l = l->next) { + NMConnection *connection = l->data; + add_row (device, connection); + } + gtk_widget_show (device->scrolled_window); + } else if (n_connections == 1) { + connection = connections->data; + gtk_widget_hide (device->scrolled_window); + add_details (device->details, net_device_get_nm_device (NET_DEVICE (device)), connection); + gtk_widget_show_all (device->details); + gtk_widget_show (device->details_button); + g_object_set_data (G_OBJECT (device->details_button), "row", device->details_button); + g_object_set_data (G_OBJECT (device->details_button), "connection", connection); + + } else { + gtk_widget_hide (device->scrolled_window); + gtk_widget_hide (device->details); + gtk_widget_hide (device->details_button); + } +} + +static void +remote_settings_read_cb (NMRemoteSettings *settings, + NetDeviceEthernet *device) +{ + populate_ui (device); +} + +static void +update_separator (GtkWidget **separator, + GtkWidget *child, + GtkWidget *before, + gpointer user_data) +{ + if (before == NULL) + return; + + if (*separator == NULL) + { + *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); + gtk_widget_show (*separator); + g_object_ref_sink (*separator); + } +} + +static void +add_profile (GtkButton *button, NetDeviceEthernet *device) +{ + NMRemoteSettings *settings; + NMConnection *connection; + NMSettingConnection *sc; + gchar *uuid, *id; + NetConnectionEditor *editor; + GtkWidget *window; + NMClient *client; + NMDevice *nmdev; + GSList *connections; + + connection = nm_connection_new (); + sc = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + nm_connection_add_setting (connection, NM_SETTING (sc)); + + uuid = nm_utils_uuid_generate (); + + settings = net_object_get_remote_settings (NET_OBJECT (device)); + connections = nm_remote_settings_list_connections (settings); + id = ce_page_get_next_available_name (connections, _("Profile %d")); + g_slist_free (connections); + + g_object_set (sc, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_ID, id, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NULL); + + nm_connection_add_setting (connection, nm_setting_wired_new ()); + + g_free (uuid); + g_free (id); + + window = gtk_widget_get_toplevel (GTK_WIDGET (button)); + + nmdev = net_device_get_nm_device (NET_DEVICE (device)); + client = net_object_get_client (NET_OBJECT (device)); + editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings); + g_signal_connect (editor, "done", G_CALLBACK (editor_done), device); + net_connection_editor_run (editor); +} + +static void +device_ethernet_constructed (GObject *object) +{ + NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); + NMRemoteSettings *settings; + GtkWidget *list; + GtkWidget *swin; + + device->scrolled_window = swin = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "list")); + device->list = list = GTK_WIDGET (egg_list_box_new ()); + egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE); + egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL); + egg_list_box_add_to_scrolled (EGG_LIST_BOX (list), GTK_SCROLLED_WINDOW (swin)); + gtk_widget_show (list); + + device->details = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details")); + + device->details_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details_button")); + g_signal_connect (device->details_button, "clicked", + G_CALLBACK (show_details_for_row), device); + + device->add_profile_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "add_profile_button")); + g_signal_connect (device->add_profile_button, "clicked", + G_CALLBACK (add_profile), device); + + settings = net_object_get_remote_settings (NET_OBJECT (object)); + g_signal_connect (settings, "connections-read", + G_CALLBACK (remote_settings_read_cb), object); +} + +static void +device_ethernet_finalize (GObject *object) +{ + NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); + + g_object_unref (device->builder); + + G_OBJECT_CLASS (net_device_ethernet_parent_class)->finalize (object); +} + static void net_device_ethernet_class_init (NetDeviceEthernetClass *klass) { NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass); + NetObjectClass *obj_class = NET_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); simple_class->get_speed = device_ethernet_get_speed; + obj_class->add_to_notebook = device_ethernet_add_to_notebook; + object_class->constructed = device_ethernet_constructed; + object_class->finalize = device_ethernet_finalize; } static void -net_device_ethernet_init (NetDeviceEthernet *device_ethernet) +net_device_ethernet_init (NetDeviceEthernet *device) { + GError *error = NULL; + + device->builder = gtk_builder_new (); + gtk_builder_add_from_file (device->builder, + GNOMECC_UI_DIR "/network-ethernet.ui", + &error); + if (error != NULL) { + g_warning ("Could not load interface file: %s", error->message); + g_error_free (error); + return; + } } diff --git a/panels/network/net-device-ethernet.h b/panels/network/net-device-ethernet.h index 5c22937b6..d7a2f7ada 100644 --- a/panels/network/net-device-ethernet.h +++ b/panels/network/net-device-ethernet.h @@ -41,16 +41,23 @@ typedef struct _NetDeviceEthernetClass NetDeviceEthernetClass; struct _NetDeviceEthernet { - NetDeviceSimple parent; - NetDeviceEthernetPrivate *priv; + NetDeviceSimple parent; + + GtkBuilder *builder; + + GtkWidget *list; + GtkWidget *scrolled_window; + GtkWidget *details; + GtkWidget *details_button; + GtkWidget *add_profile_button; }; struct _NetDeviceEthernetClass { - NetDeviceSimpleClass parent_class; + NetDeviceSimpleClass parent_class; }; -GType net_device_ethernet_get_type (void); +GType net_device_ethernet_get_type (void); G_END_DECLS diff --git a/panels/network/network-ethernet.ui b/panels/network/network-ethernet.ui new file mode 100644 index 000000000..574e84ad2 --- /dev/null +++ b/panels/network/network-ethernet.ui @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <!-- interface-requires gtk+ 3.0 --> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">emblem-system-symbolic</property> + </object> + <object class="GtkWindow" id="window_tmp"> + <property name="can_focus">False</property> + <child> + <object class="GtkVBox" id="vbox6"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="spacing">6</property> + <child> + <object class="GtkGrid" id="grid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="row_spacing">10</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkImage" id="image_device"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="valign">start</property> + <property name="xalign">1</property> + <property name="pixel_size">48</property> + <property name="icon_name">network-wired</property> + <property name="icon-size">6</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">start</property> + <property name="hexpand">True</property> + <property name="spacing">3</property> + <child> + <object class="GtkLabel" id="label_device"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">Wired</property> + <property name="ellipsize">end</property> + <attributes> + <attribute name="weight" value="bold"/> + <attribute name="scale" value="1.2"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_status"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">Cable unplugged</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkAlignment" id="alignment_switch"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="valign">start</property> + <child> + <object class="GtkSwitch" id="device_off_switch"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="halign">end</property> + <property name="valign">start</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="list"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="hscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <property name="margin_top">20</property> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">3</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkGrid" id="details"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="row_spacing">10</property> + <property name="column_spacing">10</property> + <property name="margin_top">20</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">3</property> + <property name="height">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="actions"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_top">20</property> + <child> + <object class="GtkButton" id="add_profile_button"> + <property name="label" translatable="yes">_Add profileā¦</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="halign">start</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="details_button"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="halign">end</property> + <property name="image">image1</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <object class="GtkSizeGroup" id="sizegroup1"/> +</interface> diff --git a/panels/network/network-simple.ui b/panels/network/network-simple.ui index a5ceb47a9..194e25f60 100644 --- a/panels/network/network-simple.ui +++ b/panels/network/network-simple.ui @@ -1,6 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> <!-- interface-requires gtk+ 3.0 --> + <object class="GtkOffscreenWindow" id="offscreenwindow1"> + <property name="can_focus">False</property> + <child> + <placeholder/> + </child> + </object> <object class="GtkWindow" id="window_tmp"> <property name="can_focus">False</property> <child> @@ -82,174 +88,6 @@ </packing> </child> <child> - <object class="GtkLabel" id="heading_mac"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">Hardware Address</property> - <property name="mnemonic_widget">label_mac</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="heading_ipv4"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">IPv4 Address</property> - <property name="mnemonic_widget">label_ipv4</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="heading_ipv6"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">IPv6 Address</property> - <property name="mnemonic_widget">label_ipv6</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="heading_route"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">1</property> - <property name="label" translatable="yes">Default Route</property> - <property name="mnemonic_widget">label_route</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">5</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="heading_dns"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">1</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">DNS</property> - <property name="mnemonic_widget">label_dns</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">6</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_mac"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="xalign">0</property> - <property name="label">AA:BB:CC:DD:55:66:77:88</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - <property name="width">2</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_ipv4"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="xalign">0</property> - <property name="label">127.0.0.1</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> - <property name="width">2</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_ipv6"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="xalign">0</property> - <property name="label">::1</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> - <property name="width">2</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_route"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="xalign">0</property> - <property name="label">127.0.0.1</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">5</property> - <property name="width">2</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_dns"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label">127.0.0.1</property> - <property name="wrap">True</property> - <property name="selectable">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">6</property> - <property name="width">2</property> - <property name="height">1</property> - </packing> - </child> - <child> <object class="GtkAlignment" id="alignment_switch"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -272,13 +110,189 @@ </packing> </child> <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> + <object class="GtkGrid" id="grid1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_top">20</property> + <property name="row_spacing">10</property> + <property name="column_spacing">6</property> + <property name="row_homogeneous">True</property> + <property name="column_homogeneous">True</property> + <child> + <object class="GtkLabel" id="heading_mac"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Hardware Address</property> + <property name="mnemonic_widget">label_mac</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_ipv4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">IPv4 Address</property> + <property name="mnemonic_widget">label_ipv4</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_ipv6"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">IPv6 Address</property> + <property name="mnemonic_widget">label_ipv6</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_route"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Default Route</property> + <property name="mnemonic_widget">label_route</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="heading_dns"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">DNS</property> + <property name="mnemonic_widget">label_dns</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_mac"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="xalign">0</property> + <property name="label">AA:BB:CC:DD:55:66:77:88</property> + <property name="selectable">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_ipv4"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="xalign">0</property> + <property name="label">127.0.0.1</property> + <property name="selectable">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_ipv6"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="xalign">0</property> + <property name="label">::1</property> + <property name="selectable">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_route"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="xalign">0</property> + <property name="label">127.0.0.1</property> + <property name="selectable">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_dns"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label">127.0.0.1</property> + <property name="wrap">True</property> + <property name="selectable">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">3</property> + <property name="height">1</property> + </packing> </child> </object> <packing> @@ -321,13 +335,5 @@ </object> </child> </object> - <object class="GtkSizeGroup" id="sizegroup1"> - <widgets> - <widget name="heading_mac"/> - <widget name="heading_ipv4"/> - <widget name="heading_ipv6"/> - <widget name="heading_route"/> - <widget name="heading_dns"/> - </widgets> - </object> + <object class="GtkSizeGroup" id="sizegroup1"/> </interface> diff --git a/panels/network/panel-common.c b/panels/network/panel-common.c index fe7baf4eb..cafdc327b 100644 --- a/panels/network/panel-common.c +++ b/panels/network/panel-common.c @@ -655,3 +655,21 @@ panel_unset_device_widgets (GtkBuilder *builder) panel_set_device_widget_details (builder, "dns", NULL); panel_set_device_widget_details (builder, "route", NULL); } + +gchar * +panel_get_ip4_address_as_string (NMIP4Config *ip4, const gchar *what) +{ + return get_ipv4_config_address_as_string (ip4, what); +} + +gchar * +panel_get_ip4_dns_as_string (NMIP4Config *ip4) +{ + return get_ipv4_config_name_servers_as_string (ip4); +} + +gchar * +panel_get_ip6_address_as_string (NMIP6Config *ip6) +{ + return get_ipv6_config_address_as_string (ip6); +} diff --git a/panels/network/panel-common.h b/panels/network/panel-common.h index c55d46b3a..9288e4fbe 100644 --- a/panels/network/panel-common.h +++ b/panels/network/panel-common.h @@ -45,6 +45,9 @@ gboolean panel_set_device_widget_header (GtkBuilder *buil void panel_set_device_widgets (GtkBuilder *builder, NMDevice *device); void panel_unset_device_widgets (GtkBuilder *builder); +gchar *panel_get_ip4_address_as_string (NMIP4Config *config, const gchar *what); +gchar *panel_get_ip4_dns_as_string (NMIP4Config *config); +gchar *panel_get_ip6_address_as_string (NMIP6Config *config); G_END_DECLS |