Merge lp:~khurshid-alam/unity-control-center/libnm-port into lp:unity-control-center

Proposed by Khurshid Alam on 2019-05-01
Status: Merged
Approved by: Sebastien Bacher on 2019-05-02
Approved revision: 12921
Merged at revision: 12921
Proposed branch: lp:~khurshid-alam/unity-control-center/libnm-port
Merge into: lp:unity-control-center
Diff against target: 29643 lines (+22886/-3425)
112 files modified
configure.ac (+15/-8)
debian/control (+3/-3)
panels/network/Makefile.am (+25/-31)
panels/network/cc-network-panel.c (+541/-315)
panels/network/cc-network-panel.h (+3/-1)
panels/network/connection-editor/8021x-security-page.ui (+295/-0)
panels/network/connection-editor/Makefile.am (+54/-0)
panels/network/connection-editor/ce-page-8021x-security.c (+186/-0)
panels/network/connection-editor/ce-page-8021x-security.h (+63/-0)
panels/network/connection-editor/ce-page-details.c (+289/-0)
panels/network/connection-editor/ce-page-details.h (+68/-0)
panels/network/connection-editor/ce-page-ethernet.c (+187/-0)
panels/network/connection-editor/ce-page-ethernet.h (+71/-0)
panels/network/connection-editor/ce-page-ip4.c (+907/-0)
panels/network/connection-editor/ce-page-ip4.h (+70/-0)
panels/network/connection-editor/ce-page-ip6.c (+838/-0)
panels/network/connection-editor/ce-page-ip6.h (+70/-0)
panels/network/connection-editor/ce-page-security.c (+467/-0)
panels/network/connection-editor/ce-page-security.h (+65/-0)
panels/network/connection-editor/ce-page-vpn.c (+198/-0)
panels/network/connection-editor/ce-page-vpn.h (+71/-0)
panels/network/connection-editor/ce-page-wifi.c (+201/-0)
panels/network/connection-editor/ce-page-wifi.h (+62/-0)
panels/network/connection-editor/ce-page.c (+541/-0)
panels/network/connection-editor/ce-page.h (+114/-0)
panels/network/connection-editor/connection-editor.gresource.xml (+14/-0)
panels/network/connection-editor/connection-editor.ui (+130/-0)
panels/network/connection-editor/details-page.ui (+379/-0)
panels/network/connection-editor/ethernet-page.ui (+236/-0)
panels/network/connection-editor/ip4-page.ui (+428/-0)
panels/network/connection-editor/ip6-page.ui (+442/-0)
panels/network/connection-editor/net-connection-editor.c (+893/-0)
panels/network/connection-editor/net-connection-editor.h (+92/-0)
panels/network/connection-editor/security-page.ui (+294/-0)
panels/network/connection-editor/ui-helpers.c (+38/-0)
panels/network/connection-editor/ui-helpers.h (+27/-0)
panels/network/connection-editor/vpn-helpers.c (+352/-0)
panels/network/connection-editor/vpn-helpers.h (+41/-0)
panels/network/connection-editor/vpn-page.ui (+75/-0)
panels/network/connection-editor/wifi-page.ui (+140/-0)
panels/network/net-device-ethernet.c (+638/-0)
panels/network/net-device-ethernet.h (+68/-0)
panels/network/net-device-mobile.c (+533/-165)
panels/network/net-device-mobile.h (+1/-1)
panels/network/net-device-simple.c (+299/-0)
panels/network/net-device-simple.h (+67/-0)
panels/network/net-device-wifi.c (+1097/-1117)
panels/network/net-device.c (+58/-89)
panels/network/net-device.h (+5/-1)
panels/network/net-object.c (+25/-37)
panels/network/net-object.h (+3/-3)
panels/network/net-proxy.c (+60/-164)
panels/network/net-vpn.c (+131/-53)
panels/network/net-vpn.h (+1/-3)
panels/network/network-dialogs.c (+59/-101)
panels/network/network-dialogs.h (+16/-18)
panels/network/network-ethernet.ui (+219/-0)
panels/network/network-mobile.ui (+114/-86)
panels/network/network-proxy.ui (+141/-90)
panels/network/network-simple.ui (+340/-0)
panels/network/network-vpn.ui (+114/-95)
panels/network/network-wifi.ui (+1593/-635)
panels/network/network.gresource.xml (+12/-0)
panels/network/network.ui (+5/-198)
panels/network/panel-common.c (+163/-202)
panels/network/panel-common.h (+11/-9)
panels/network/wireless-security/Makefile.am (+72/-0)
panels/network/wireless-security/eap-method-fast.c (+450/-0)
panels/network/wireless-security/eap-method-fast.h (+36/-0)
panels/network/wireless-security/eap-method-fast.ui (+202/-0)
panels/network/wireless-security/eap-method-leap.c (+263/-0)
panels/network/wireless-security/eap-method-leap.h (+35/-0)
panels/network/wireless-security/eap-method-leap.ui (+107/-0)
panels/network/wireless-security/eap-method-peap.c (+450/-0)
panels/network/wireless-security/eap-method-peap.h (+36/-0)
panels/network/wireless-security/eap-method-peap.ui (+220/-0)
panels/network/wireless-security/eap-method-simple.c (+366/-0)
panels/network/wireless-security/eap-method-simple.h (+63/-0)
panels/network/wireless-security/eap-method-simple.ui (+120/-0)
panels/network/wireless-security/eap-method-tls.c (+552/-0)
panels/network/wireless-security/eap-method-tls.h (+36/-0)
panels/network/wireless-security/eap-method-tls.ui (+216/-0)
panels/network/wireless-security/eap-method-ttls.c (+476/-0)
panels/network/wireless-security/eap-method-ttls.h (+36/-0)
panels/network/wireless-security/eap-method-ttls.ui (+167/-0)
panels/network/wireless-security/eap-method.c (+676/-0)
panels/network/wireless-security/eap-method.h (+131/-0)
panels/network/wireless-security/helpers.c (+53/-0)
panels/network/wireless-security/helpers.h (+35/-0)
panels/network/wireless-security/nm-connection-editor-to-network-panel.patch (+44/-0)
panels/network/wireless-security/nm-connection-editor-ui-to-network-panel.patch (+495/-0)
panels/network/wireless-security/nm-default.h (+62/-0)
panels/network/wireless-security/utils.c (+77/-0)
panels/network/wireless-security/utils.h (+44/-0)
panels/network/wireless-security/wireless-security.c (+604/-0)
panels/network/wireless-security/wireless-security.gresource.xml (+16/-0)
panels/network/wireless-security/wireless-security.h (+154/-0)
panels/network/wireless-security/ws-dynamic-wep.c (+132/-0)
panels/network/wireless-security/ws-dynamic-wep.h (+32/-0)
panels/network/wireless-security/ws-dynamic-wep.ui (+94/-0)
panels/network/wireless-security/ws-leap.c (+213/-0)
panels/network/wireless-security/ws-leap.h (+30/-0)
panels/network/wireless-security/ws-leap.ui (+108/-0)
panels/network/wireless-security/ws-wep-key.c (+364/-0)
panels/network/wireless-security/ws-wep-key.h (+33/-0)
panels/network/wireless-security/ws-wep-key.ui (+196/-0)
panels/network/wireless-security/ws-wpa-eap.c (+133/-0)
panels/network/wireless-security/ws-wpa-eap.h (+32/-0)
panels/network/wireless-security/ws-wpa-eap.ui (+87/-0)
panels/network/wireless-security/ws-wpa-psk.c (+233/-0)
panels/network/wireless-security/ws-wpa-psk.h (+30/-0)
panels/network/wireless-security/ws-wpa-psk.ui (+117/-0)
To merge this branch: bzr merge lp:~khurshid-alam/unity-control-center/libnm-port
Reviewer Review Type Date Requested Status
Sebastien Bacher 2019-05-01 Approve on 2019-05-02
Review via email: mp+366762@code.launchpad.net

Commit message

Network: Port to libnm 1.2

Reference: https://bugzilla.gnome.org/show_bug.cgi?id=765910

Description of the change

This is a direct port from gnome-control-center 3.26. Connection editor & wireless security codes are basically the same. Simply use directory comparison with meld for easier comparison or review.

I would have cherry picked more commits for connection-editor & wifi-security from 3.28/3.30, but in 3.28 they broke away wifi panel and the code is tied with that. But 3.26 is stable and Linux Mint Cinnamon is also using the same.

PPA: ppa:unity7maintainers/unity7-desktop

Community-Thread: https://community.ubuntu.com/t/testing-of-new-wetwork-panel-in-unity-libnm-port-1-2-eoan/10792

Other details:
---------------------

1) Gnome started using g-s-d for switching on/off Airplane mode. We will follow that. Hence rfkill related code was removed from cc-network-panel.c. See https://bugzilla.gnome.org/show_bug.cgi?id=703411 and https://github.com/GNOME/gnome-control-center/commit/085e7695133ae482cfbba78ab151a90a3960052d

2) In g-c-c new VPN connections are created within the control center from 8a52138cf6e31d1030ea2829acb6ec96892a8d8c and other types
currently hit the nm-connection-editor fallback. We are doing the same here. For vpn & otype of conection it will simply fall back using nm-connection-editor See https://bugzilla.gnome.org/show_bug.cgi?id=674498 and https://github.com/GNOME/gnome-control-center/commit/8a52138cf6e31d1030ea2829acb6ec96892a8d8c

3) This also includes support for the 'ModemManager1' interface. See https://github.com/GNOME/gnome-control-center/commit/0225d1a9e73cf741f627d595925abb7e886164be

To post a comment you must log in.
Sebastien Bacher (seb128) wrote :

Thanks for the work, I don't think it makes sense to review the code there since it's a lot of change and basically a backport from upstream code already used in GNOME, let's rather go through functional testing. Landing the change (especially early in the cycle) is +1 from me, let me know when you are happy uploading

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure.ac'
2--- configure.ac 2018-11-20 08:48:24 +0000
3+++ configure.ac 2019-05-01 13:56:52 +0000
4@@ -113,7 +113,9 @@
5 CANBERRA_REQUIRED_VERSION=0.13
6 GDKPIXBUF_REQUIRED_VERSION=2.23.0
7 POLKIT_REQUIRED_VERSION=0.103
8-NETWORK_MANAGER_REQUIRED_VERSION=0.8.992
9+NETWORK_MANAGER_REQUIRED_VERSION=1.2.0
10+NETWORK_MANAGER_APPLET_REQUIRED_VERSION=1.2.0
11+MODEM_MANAGER_REQUIRED_VERSION=0.7
12 LIBNOTIFY_REQUIRED_VERSION=0.7.3
13 GNOME_DESKTOP_REQUIRED_VERSION=3.27.3
14 SCHEMAS_REQUIRED_VERSION=3.15.4
15@@ -149,7 +151,8 @@
16 PKG_CHECK_MODULES(MEDIA_PANEL, $COMMON_MODULES)
17 PKG_CHECK_MODULES(MOUSE_PANEL, $COMMON_MODULES xi >= 1.2
18 unity-settings-daemon x11)
19-PKG_CHECK_MODULES(NETWORK_PANEL, $COMMON_MODULES)
20+PKG_CHECK_MODULES(NETWORK_PANEL, $COMMON_MODULES gmodule-2.0
21+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
22 PKG_CHECK_MODULES(POWER_PANEL, $COMMON_MODULES upower-glib >= 0.9.1
23 unity-settings-daemon)
24 PKG_CHECK_MODULES(COLOR_PANEL, $COMMON_MODULES colord >= 0.1.8)
25@@ -182,14 +185,16 @@
26 GDESKTOP_PREFIX=`$PKG_CONFIG --variable prefix gsettings-desktop-schemas`
27 AC_SUBST(GDESKTOP_PREFIX)
28
29-# Check for NetworkManager ~0.9
30-PKG_CHECK_MODULES(NETWORK_MANAGER, NetworkManager >= $NETWORK_MANAGER_REQUIRED_VERSION
31- libnm-glib >= $NETWORK_MANAGER_REQUIRED_VERSION
32- libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION
33- libnm-gtk >= $NETWORK_MANAGER_REQUIRED_VERSION,
34+# Check for NetworkManager ~1.2
35+PKG_CHECK_MODULES(NETWORK_MANAGER,
36+ libnm >= $NETWORK_MANAGER_REQUIRED_VERSION
37+ libnma >= $NETWORK_MANAGER_APPLET_REQUIRED_VERSION
38+ mm-glib >= $MODEM_MANAGER_REQUIRED_VERSION,
39 [have_networkmanager=yes], have_networkmanager=no)
40 if test "x$have_networkmanager" = xno ; then
41- AC_MSG_WARN(*** Network panel will not be built (NetworkManager ~0.9 or newer not found) ***)
42+ AC_MSG_WARN(*** Network panel will not be built (NetworkManager ~1.2 or newer not found) ***)
43+else
44+ AC_DEFINE(BUILD_NETWORK, 1, [Define to 1 to build the Network panel])
45 fi
46 AM_CONDITIONAL(BUILD_NETWORK, [test x$have_networkmanager = xyes])
47
48@@ -516,6 +521,8 @@
49 panels/printers/Makefile
50 panels/printers/unity-printers-panel.desktop.in
51 panels/network/Makefile
52+panels/network/wireless-security/Makefile
53+panels/network/connection-editor/Makefile
54 panels/network/unity-network-panel.desktop.in
55 panels/universal-access/Makefile
56 panels/universal-access/unity-universal-access-panel.desktop.in
57
58=== modified file 'debian/control'
59--- debian/control 2019-01-09 16:51:00 +0000
60+++ debian/control 2019-05-01 13:56:52 +0000
61@@ -35,9 +35,9 @@
62 libgtop2-dev,
63 libibus-1.0-dev (>= 1.5.0),
64 libkrb5-dev,
65- libnm-glib-dev (>= 0.9) [linux-any],
66- libnm-gtk-dev (>= 0.9) [linux-any],
67- libnm-util-dev (>= 0.9) [linux-any],
68+ libnm-dev (>= 1.2.0) [linux-any],
69+ libnma-dev (>= 1.2.0) [linux-any],
70+ libmm-glib-dev [linux-any],
71 libnotify-dev (>= 0.7.3),
72 libpolkit-gobject-1-dev (>= 0.103),
73 libpulse-dev (>= 1:2.0),
74
75=== modified file 'panels/network/Makefile.am'
76--- panels/network/Makefile.am 2017-04-06 13:23:05 +0000
77+++ panels/network/Makefile.am 2019-05-01 13:56:52 +0000
78@@ -1,19 +1,26 @@
79 cappletname = network
80
81-INCLUDES = \
82+SUBDIRS = wireless-security connection-editor
83+
84+AM_CPPFLAGS = \
85 $(PANEL_CFLAGS) \
86 $(NETWORK_PANEL_CFLAGS) \
87 $(NETWORK_MANAGER_CFLAGS) \
88 -DGNOMECC_UI_DIR="\"$(uidir)\"" \
89 -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
90 -DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
91+ -I$(srcdir)/wireless-security \
92 $(NULL)
93
94 ccpanelsdir = $(PANELS_DIR)
95 ccpanels_LTLIBRARIES = libnetwork.la
96
97+BUILT_SOURCES = \
98+ cc-network-resources.c \
99+ cc-network-resources.h
100+
101 libnetwork_la_SOURCES = \
102- network-module.c \
103+ $(BUILT_SOURCES) \
104 panel-common.c \
105 panel-common.h \
106 net-object.c \
107@@ -22,45 +29,31 @@
108 net-device.h \
109 net-device-wifi.c \
110 net-device-wifi.h \
111- net-device-wired.c \
112- net-device-wired.h \
113+ net-device-simple.c \
114+ net-device-simple.h \
115+ net-device-ethernet.c \
116+ net-device-ethernet.h \
117 net-device-mobile.c \
118 net-device-mobile.h \
119 net-vpn.c \
120 net-vpn.h \
121 net-proxy.c \
122 net-proxy.h \
123- panel-cell-renderer-mode.c \
124- panel-cell-renderer-mode.h \
125- panel-cell-renderer-security.c \
126- panel-cell-renderer-security.h \
127- panel-cell-renderer-signal.c \
128- panel-cell-renderer-signal.h \
129- panel-cell-renderer-separator.c \
130- panel-cell-renderer-separator.h \
131- panel-cell-renderer-text.c \
132- panel-cell-renderer-text.h \
133- panel-cell-renderer-pixbuf.c \
134- panel-cell-renderer-pixbuf.h \
135 network-dialogs.c \
136 network-dialogs.h \
137+ network-module.c \
138 cc-network-panel.c \
139- cc-network-panel.h \
140- rfkill-glib.c \
141- rfkill-glib.h \
142- rfkill.h
143-
144-libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS)
145+ cc-network-panel.h
146+
147+libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS) $(builddir)/connection-editor/libconnection-editor.la
148+
149 libnetwork_la_LDFLAGS = $(PANEL_LDFLAGS)
150
151-uidir = $(pkgdatadir)/ui
152-dist_ui_DATA = \
153- network-proxy.ui \
154- network-vpn.ui \
155- network-wifi.ui \
156- network-wired.ui \
157- network-mobile.ui \
158- network.ui
159+resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/network.gresource.xml)
160+cc-network-resources.c: network.gresource.xml $(resource_files)
161+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name cc_network $<
162+cc-network-resources.h: network.gresource.xml $(resource_files)
163+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name cc_network $<
164
165 @INTLTOOL_DESKTOP_RULE@
166
167@@ -68,6 +61,7 @@
168 desktop_in_files = unity-network-panel.desktop.in
169 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
170
171-CLEANFILES = $(desktop_in_files) $(desktop_DATA)
172+CLEANFILES = $(desktop_in_files) $(desktop_DATA) $(BUILT_SOURCES)
173+EXTRA_DIST = $(resource_files) network.gresource.xml
174
175 -include $(top_srcdir)/git.mk
176
177=== modified file 'panels/network/cc-network-panel.c'
178--- panels/network/cc-network-panel.c 2016-03-09 21:55:46 +0000
179+++ panels/network/cc-network-panel.c 2019-05-01 13:56:52 +0000
180@@ -2,6 +2,7 @@
181 *
182 * Copyright (C) 2010-2012 Richard Hughes <richard@hughsie.com>
183 * Copyright (C) 2012 Thomas Bechtold <thomasbechtold@jpberlin.de>
184+ * Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org>
185 *
186 * This program is free software; you can redistribute it and/or modify
187 * it under the terms of the GNU General Public License as published by
188@@ -14,8 +15,7 @@
189 * GNU General Public License for more details.
190 *
191 * You should have received a copy of the GNU General Public License
192- * along with this program; if not, write to the Free Software
193- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
194+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
195 *
196 */
197
198@@ -24,25 +24,24 @@
199 #include <stdlib.h>
200
201 #include "cc-network-panel.h"
202+#include "cc-network-resources.h"
203
204-#include "nm-remote-settings.h"
205-#include "nm-client.h"
206-#include "nm-device.h"
207-#include "nm-device-modem.h"
208+#include <NetworkManager.h>
209
210 #include "net-device.h"
211 #include "net-device-mobile.h"
212 #include "net-device-wifi.h"
213-#include "net-device-wired.h"
214+#include "net-device-ethernet.h"
215 #include "net-object.h"
216 #include "net-proxy.h"
217 #include "net-vpn.h"
218
219-#include "rfkill-glib.h"
220-
221 #include "panel-common.h"
222
223 #include "network-dialogs.h"
224+#include "connection-editor/net-connection-editor.h"
225+
226+#include <libmm-glib.h>
227
228 CC_PANEL_REGISTER (CcNetworkPanel, cc_network_panel)
229
230@@ -64,17 +63,13 @@
231 GtkBuilder *builder;
232 GtkWidget *treeview;
233 NMClient *client;
234- NMRemoteSettings *remote_settings;
235+ MMManager *modem_manager;
236 gboolean updating_device;
237- guint add_header_widgets_idle;
238- guint nm_warning_idle;
239- guint refresh_idle;
240
241 /* Killswitch stuff */
242+ GDBusProxy *rfkill_proxy;
243 GtkWidget *kill_switch_header;
244- CcRfkillGlib *rfkill;
245 GtkSwitch *rfkill_switch;
246- GHashTable *killswitches;
247
248 /* wireless dialog stuff */
249 CmdlineOperation arg_operation;
250@@ -85,8 +80,6 @@
251
252 enum {
253 PANEL_DEVICES_COLUMN_ICON,
254- PANEL_DEVICES_COLUMN_TITLE,
255- PANEL_DEVICES_COLUMN_SORT,
256 PANEL_DEVICES_COLUMN_OBJECT,
257 PANEL_DEVICES_COLUMN_LAST
258 };
259@@ -96,7 +89,7 @@
260 PROP_ARGV
261 };
262
263-static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id);
264+static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out);
265 static void handle_argv (CcNetworkPanel *panel);
266
267 static void
268@@ -205,27 +198,13 @@
269 g_cancellable_cancel (priv->cancellable);
270
271 g_clear_object (&priv->cancellable);
272+ g_clear_object (&priv->rfkill_proxy);
273 g_clear_object (&priv->builder);
274 g_clear_object (&priv->client);
275- g_clear_object (&priv->remote_settings);
276+ g_clear_object (&priv->modem_manager);
277 g_clear_object (&priv->kill_switch_header);
278- g_clear_object (&priv->rfkill);
279- g_clear_pointer (&priv->killswitches, g_hash_table_destroy);
280 priv->rfkill_switch = NULL;
281
282- if (priv->refresh_idle != 0) {
283- g_source_remove (priv->refresh_idle);
284- priv->refresh_idle = 0;
285- }
286- if (priv->nm_warning_idle != 0) {
287- g_source_remove (priv->nm_warning_idle);
288- priv->nm_warning_idle = 0;
289- }
290- if (priv->add_header_widgets_idle != 0) {
291- g_source_remove (priv->add_header_widgets_idle);
292- priv->add_header_widgets_idle = 0;
293- }
294-
295 G_OBJECT_CLASS (cc_network_panel_parent_class)->dispose (object);
296 }
297
298@@ -242,7 +221,132 @@
299 static const char *
300 cc_network_panel_get_help_uri (CcPanel *panel)
301 {
302- return "help:ubuntu-help/net";
303+ return "help:gnome-help/net";
304+}
305+
306+static void
307+cc_network_panel_notify_enable_active_cb (GtkSwitch *sw,
308+ GParamSpec *pspec,
309+ CcNetworkPanel *panel)
310+{
311+ CcNetworkPanelPrivate *priv = panel->priv;
312+ gboolean enable;
313+ enable = gtk_switch_get_active (sw);
314+ g_dbus_proxy_call (priv->rfkill_proxy,
315+ "org.freedesktop.DBus.Properties.Set",
316+ g_variant_new_parsed ("('org.gnome.SettingsDaemon.Rfkill',"
317+ "'AirplaneMode', %v)",
318+ g_variant_new_boolean (enable)),
319+ G_DBUS_CALL_FLAGS_NONE,
320+ -1,
321+ priv->cancellable,
322+ NULL, NULL);
323+}
324+
325+static void
326+sync_airplane_mode_switch (CcNetworkPanel *panel)
327+{
328+ GVariant *result;
329+ gboolean enabled, should_show;
330+ gboolean hw_enabled;
331+
332+ result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "HasAirplaneMode");
333+ enabled = g_variant_get_boolean (result);
334+
335+ result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "ShouldShowAirplaneMode");
336+ should_show = g_variant_get_boolean (result);
337+
338+ gtk_widget_set_visible (GTK_WIDGET (panel->priv->kill_switch_header), enabled && should_show);
339+ if (!enabled || !should_show)
340+ return;
341+
342+ result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "AirplaneMode");
343+ enabled = g_variant_get_boolean (result);
344+
345+ result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "HardwareAirplaneMode");
346+ hw_enabled = !!g_variant_get_boolean (result);
347+
348+ enabled |= hw_enabled;
349+
350+ if (enabled != gtk_switch_get_active (panel->priv->rfkill_switch)) {
351+ g_signal_handlers_block_by_func (panel->priv->rfkill_switch,
352+ cc_network_panel_notify_enable_active_cb,
353+ panel);
354+ gtk_switch_set_active (panel->priv->rfkill_switch, enabled);
355+ g_signal_handlers_unblock_by_func (panel->priv->rfkill_switch,
356+ cc_network_panel_notify_enable_active_cb,
357+ panel);
358+ }
359+
360+ gtk_widget_set_sensitive (GTK_WIDGET (panel->priv->rfkill_switch), !hw_enabled);
361+}
362+
363+static void
364+on_property_change (GDBusProxy *proxy,
365+ GVariant *changed_properties,
366+ GVariant *invalidated_properties,
367+ gpointer user_data)
368+{
369+ sync_airplane_mode_switch (CC_NETWORK_PANEL (user_data));
370+}
371+
372+static void
373+got_rfkill_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
374+{
375+ GError *error = NULL;
376+ CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
377+
378+ panel->priv->rfkill_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
379+ if (panel->priv->rfkill_proxy == NULL) {
380+ g_printerr ("Error creating rfkill proxy: %s\n", error->message);
381+ g_error_free (error);
382+ return;
383+ }
384+
385+ g_signal_connect (panel->priv->rfkill_proxy, "g-properties-changed",
386+ G_CALLBACK (on_property_change), panel);
387+ sync_airplane_mode_switch (panel);
388+}
389+
390+static void
391+cc_network_panel_constructed (GObject *object)
392+{
393+ CcNetworkPanel *panel = CC_NETWORK_PANEL (object);
394+ GtkWidget *box;
395+ GtkWidget *label;
396+ GtkWidget *widget;
397+
398+ G_OBJECT_CLASS (cc_network_panel_parent_class)->constructed (object);
399+
400+ /* add kill switch widgets */
401+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
402+ /* TRANSLATORS: this is to disable the radio hardware in the
403+ * network panel */
404+ label = gtk_label_new_with_mnemonic (_("Air_plane Mode"));
405+ gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
406+ gtk_widget_set_visible (label, TRUE);
407+ widget = gtk_switch_new ();
408+ gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
409+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
410+ gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 4);
411+ gtk_widget_show_all (box);
412+ panel->priv->rfkill_switch = GTK_SWITCH (widget);
413+ cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (panel)), box);
414+ panel->priv->kill_switch_header = g_object_ref (box);
415+
416+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
417+ G_DBUS_PROXY_FLAGS_NONE,
418+ NULL,
419+ "org.gnome.SettingsDaemon.Rfkill",
420+ "/org/gnome/SettingsDaemon/Rfkill",
421+ "org.gnome.SettingsDaemon.Rfkill",
422+ panel->priv->cancellable,
423+ got_rfkill_proxy_cb,
424+ panel);
425+
426+ g_signal_connect (panel->priv->rfkill_switch, "notify::active",
427+ G_CALLBACK (cc_network_panel_notify_enable_active_cb),
428+ panel);
429 }
430
431 static void
432@@ -259,6 +363,7 @@
433 object_class->set_property = cc_network_panel_set_property;
434 object_class->dispose = cc_network_panel_dispose;
435 object_class->finalize = cc_network_panel_finalize;
436+ object_class->constructed = cc_network_panel_constructed;
437
438 g_object_class_override_property (object_class, PROP_ARGV, "argv");
439 }
440@@ -333,16 +438,140 @@
441 if (g_strcmp0 (net_object_get_id (object),
442 net_object_get_id (object_tmp)) == 0) {
443 g_object_unref (object_tmp);
444- if (!gtk_list_store_remove (GTK_LIST_STORE (model), &iter))
445- gtk_tree_model_get_iter_first (model, &iter);
446- gtk_tree_selection_select_iter (selection, &iter);
447-
448+ if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) {
449+ if (gtk_tree_model_get_iter_first (model, &iter))
450+ gtk_tree_selection_select_iter (selection, &iter);
451+ }
452 break;
453 }
454 g_object_unref (object_tmp);
455 } while (gtk_tree_model_iter_next (model, &iter));
456 }
457
458+GPtrArray *
459+cc_network_panel_get_devices (CcNetworkPanel *panel)
460+{
461+ GPtrArray *devices;
462+ GtkTreeModel *model;
463+ GtkTreeIter iter;
464+ NetObject *object;
465+
466+ devices = g_ptr_array_new_with_free_func (g_object_unref);
467+
468+ model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder,
469+ "liststore_devices"));
470+ if (!gtk_tree_model_get_iter_first (model, &iter))
471+ return devices;
472+
473+ do {
474+ gtk_tree_model_get (model, &iter,
475+ PANEL_DEVICES_COLUMN_OBJECT, &object,
476+ -1);
477+ if (NET_IS_DEVICE (object))
478+ g_ptr_array_add (devices, object);
479+ else
480+ g_object_unref (object);
481+ } while (gtk_tree_model_iter_next (model, &iter));
482+
483+ return devices;
484+}
485+
486+static gint
487+panel_net_object_get_sort_category (NetObject *net_object)
488+{
489+ if (NET_IS_DEVICE (net_object)) {
490+ return panel_device_get_sort_category (net_device_get_nm_device (NET_DEVICE (net_object)));
491+ } else if (NET_IS_PROXY (net_object)) {
492+ return 9;
493+ } else if (NET_IS_VPN (net_object)) {
494+ return 5;
495+ }
496+
497+ g_assert_not_reached ();
498+}
499+
500+static gint
501+panel_net_object_sort_func (GtkTreeModel *model, GtkTreeIter *a,
502+ GtkTreeIter *b, void *data)
503+{
504+ g_autoptr(NetObject) obj_a = NULL;
505+ g_autoptr(NetObject) obj_b = NULL;
506+ gint cat_a, cat_b;
507+
508+ gtk_tree_model_get (model, a,
509+ PANEL_DEVICES_COLUMN_OBJECT, &obj_a,
510+ -1);
511+ gtk_tree_model_get (model, b,
512+ PANEL_DEVICES_COLUMN_OBJECT, &obj_b,
513+ -1);
514+
515+ cat_a = panel_net_object_get_sort_category (obj_a);
516+ cat_b = panel_net_object_get_sort_category (obj_b);
517+
518+ if (cat_a != cat_b)
519+ return cat_a - cat_b;
520+
521+ return g_utf8_collate (net_object_get_title (obj_a), net_object_get_title (obj_b));
522+}
523+
524+static void
525+panel_net_object_notify_title_cb (NetObject *net_object, GParamSpec *pspec, CcNetworkPanel *panel)
526+{
527+ GtkTreeIter iter;
528+ GtkListStore *liststore;
529+
530+ if (!find_in_model_by_id (panel, net_object_get_id (net_object), &iter))
531+ return;
532+
533+ liststore = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
534+ "liststore_devices"));
535+
536+ /* gtk_tree_model_row_changed would not cause the list store to resort.
537+ * Instead set the object column to the current value.
538+ * See https://bugzilla.gnome.org/show_bug.cgi?id=782737 */
539+ gtk_list_store_set (liststore, &iter,
540+ PANEL_DEVICES_COLUMN_OBJECT, net_object,
541+ -1);
542+}
543+
544+static void
545+panel_refresh_device_titles (CcNetworkPanel *panel)
546+{
547+ GPtrArray *ndarray, *nmdarray;
548+ NetDevice **devices;
549+ NMDevice **nm_devices, *nm_device;
550+ gchar **titles;
551+ gint i, num_devices;
552+
553+ ndarray = cc_network_panel_get_devices (panel);
554+ if (!ndarray->len) {
555+ g_ptr_array_free (ndarray, TRUE);
556+ return;
557+ }
558+
559+ nmdarray = g_ptr_array_new ();
560+ for (i = 0; i < ndarray->len; i++) {
561+ nm_device = net_device_get_nm_device (ndarray->pdata[i]);
562+ if (nm_device)
563+ g_ptr_array_add (nmdarray, nm_device);
564+ else
565+ g_ptr_array_remove_index (ndarray, i--);
566+ }
567+
568+ devices = (NetDevice **)ndarray->pdata;
569+ nm_devices = (NMDevice **)nmdarray->pdata;
570+ num_devices = ndarray->len;
571+
572+ titles = nm_device_disambiguate_names (nm_devices, num_devices);
573+ for (i = 0; i < num_devices; i++) {
574+ net_object_set_title (NET_OBJECT (devices[i]), titles[i]);
575+ g_free (titles[i]);
576+ }
577+ g_free (titles);
578+ g_ptr_array_free (ndarray, TRUE);
579+ g_ptr_array_free (nmdarray, TRUE);
580+}
581+
582 static gboolean
583 handle_argv_for_device (CcNetworkPanel *panel,
584 NMDevice *device,
585@@ -350,6 +579,7 @@
586 {
587 CcNetworkPanelPrivate *priv = panel->priv;
588 NMDeviceType type;
589+ GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)));
590
591 if (priv->arg_operation == OPERATION_NULL)
592 return TRUE;
593@@ -363,21 +593,21 @@
594 select_tree_iter (panel, iter);
595
596 if (priv->arg_operation == OPERATION_CREATE_WIFI)
597- cc_network_panel_create_wifi_network (panel, priv->client, priv->remote_settings);
598+ cc_network_panel_create_wifi_network (toplevel, priv->client);
599 else
600- cc_network_panel_connect_to_hidden_network (panel, priv->client, priv->remote_settings);
601+ cc_network_panel_connect_to_hidden_network (toplevel, priv->client);
602
603 reset_command_line_args (panel); /* done */
604 return TRUE;
605 } else if (g_strcmp0 (nm_object_get_path (NM_OBJECT (device)), priv->arg_device) == 0) {
606 if (priv->arg_operation == OPERATION_CONNECT_MOBILE) {
607- cc_network_panel_connect_to_3g_network (panel, priv->client, priv->remote_settings, device);
608+ cc_network_panel_connect_to_3g_network (toplevel, priv->client, device);
609
610 reset_command_line_args (panel); /* done */
611 select_tree_iter (panel, iter);
612 return TRUE;
613 } else if (priv->arg_operation == OPERATION_CONNECT_8021X) {
614- cc_network_panel_connect_to_8021x_network (panel, priv->client, priv->remote_settings, device, priv->arg_access_point);
615+ cc_network_panel_connect_to_8021x_network (toplevel, priv->client, device, priv->arg_access_point);
616 reset_command_line_args (panel); /* done */
617 select_tree_iter (panel, iter);
618 return TRUE;
619@@ -392,6 +622,28 @@
620 return FALSE;
621 }
622
623+static gboolean
624+handle_argv_for_connection (CcNetworkPanel *panel,
625+ NMConnection *connection,
626+ GtkTreeIter *iter)
627+{
628+ CcNetworkPanelPrivate *priv = panel->priv;
629+
630+ if (priv->arg_operation == OPERATION_NULL)
631+ return TRUE;
632+ if (priv->arg_operation != OPERATION_SHOW_DEVICE)
633+ return FALSE;
634+
635+ if (g_strcmp0 (nm_connection_get_path (connection), priv->arg_device) == 0) {
636+ reset_command_line_args (panel);
637+ select_tree_iter (panel, iter);
638+ return TRUE;
639+ }
640+
641+ return FALSE;
642+}
643+
644+
645 static void
646 handle_argv (CcNetworkPanel *panel)
647 {
648@@ -408,15 +660,20 @@
649 while (ret) {
650 GObject *object_tmp;
651 NMDevice *device;
652+ NMConnection *connection;
653 gboolean done = FALSE;
654
655 gtk_tree_model_get (model, &iter,
656 PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
657 -1);
658- if (g_object_class_find_property (G_OBJECT_GET_CLASS (object_tmp), "nm-device") != NULL) {
659+ if (NET_IS_DEVICE (object_tmp)) {
660 g_object_get (object_tmp, "nm-device", &device, NULL);
661 done = handle_argv_for_device (panel, device, &iter);
662 g_object_unref (device);
663+ } else if (NET_IS_VPN (object_tmp)) {
664+ g_object_get (object_tmp, "connection", &connection, NULL);
665+ done = handle_argv_for_connection (panel, connection, &iter);
666+ g_object_unref (connection);
667 }
668
669 g_object_unref (object_tmp);
670@@ -430,10 +687,31 @@
671 g_debug ("Could not handle argv operation, no matching device yet?");
672 }
673
674+static void
675+state_changed_cb (NMDevice *device,
676+ NMDeviceState new_state,
677+ NMDeviceState old_state,
678+ NMDeviceStateReason reason,
679+ CcNetworkPanel *panel)
680+{
681+ GtkListStore *store;
682+ GtkTreeIter iter;
683+
684+ if (!find_in_model_by_id (panel, nm_device_get_udi (device), &iter)) {
685+ return;
686+ }
687+
688+ store = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
689+ "liststore_devices"));
690+
691+ gtk_list_store_set (store, &iter,
692+ PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE),
693+ -1);
694+}
695+
696 static gboolean
697 panel_add_device (CcNetworkPanel *panel, NMDevice *device)
698 {
699- const gchar *title;
700 GtkListStore *liststore_devices;
701 GtkTreeIter iter;
702 NMDeviceType type;
703@@ -442,20 +720,25 @@
704 GtkNotebook *notebook;
705 GtkSizeGroup *size_group;
706 GType device_g_type;
707+ const char *udi;
708+
709+ if (!nm_device_get_managed (device))
710+ goto out;
711
712 /* do we have an existing object with this id? */
713- if (find_in_model_by_id (panel, nm_device_get_udi (device)) != NULL)
714+ udi = nm_device_get_udi (device);
715+ if (find_in_model_by_id (panel, udi, NULL) != NULL)
716 goto out;
717
718 type = nm_device_get_device_type (device);
719
720 g_debug ("device %s type %i path %s",
721- nm_device_get_udi (device), type, nm_object_get_path (NM_OBJECT (device)));
722+ udi, type, nm_object_get_path (NM_OBJECT (device)));
723
724- /* map the NMDeviceType to the GType */
725+ /* map the NMDeviceType to the GType, or ignore */
726 switch (type) {
727 case NM_DEVICE_TYPE_ETHERNET:
728- device_g_type = NET_TYPE_DEVICE_WIRED;
729+ device_g_type = NET_TYPE_DEVICE_ETHERNET;
730 break;
731 case NM_DEVICE_TYPE_MODEM:
732 device_g_type = NET_TYPE_DEVICE_MOBILE;
733@@ -463,23 +746,56 @@
734 case NM_DEVICE_TYPE_WIFI:
735 device_g_type = NET_TYPE_DEVICE_WIFI;
736 break;
737+ /* not going to set up a cluster in GNOME */
738+ case NM_DEVICE_TYPE_VETH:
739+ /* enterprise features */
740+ case NM_DEVICE_TYPE_BOND:
741+ case NM_DEVICE_TYPE_TEAM:
742+ /* Don't need the libvirtd bridge */
743+ case NM_DEVICE_TYPE_BRIDGE:
744+ /* Don't add VPN devices */
745+ case NM_DEVICE_TYPE_TUN:
746+ goto out;
747 default:
748- goto out;
749+ device_g_type = NET_TYPE_DEVICE_SIMPLE;
750+ break;
751 }
752
753 /* create device */
754- title = panel_device_to_localized_string (device);
755 net_device = g_object_new (device_g_type,
756 "panel", panel,
757 "removable", FALSE,
758 "cancellable", panel->priv->cancellable,
759 "client", panel->priv->client,
760- "remote-settings", panel->priv->remote_settings,
761 "nm-device", device,
762 "id", nm_device_get_udi (device),
763- "title", title,
764 NULL);
765
766+ if (type == NM_DEVICE_TYPE_MODEM &&
767+ g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager1/Modem/")) {
768+ GDBusObject *modem_object;
769+
770+ if (priv->modem_manager == NULL) {
771+ g_warning ("Cannot grab information for modem at %s: No ModemManager support",
772+ nm_device_get_udi (device));
773+ goto out;
774+ }
775+
776+ modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (priv->modem_manager),
777+ nm_device_get_udi (device));
778+ if (modem_object == NULL) {
779+ g_warning ("Cannot grab information for modem at %s: Not found",
780+ nm_device_get_udi (device));
781+ goto out;
782+ }
783+
784+ /* Set the modem object in the NetDeviceMobile */
785+ g_object_set (net_device,
786+ "mm-object", modem_object,
787+ NULL);
788+ g_object_unref (modem_object);
789+ }
790+
791 /* add as a panel */
792 if (device_g_type != NET_TYPE_DEVICE) {
793 notebook = GTK_NOTEBOOK (gtk_builder_get_object (panel->priv->builder,
794@@ -498,11 +814,15 @@
795 gtk_list_store_append (liststore_devices, &iter);
796 gtk_list_store_set (liststore_devices,
797 &iter,
798- PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device),
799- PANEL_DEVICES_COLUMN_SORT, panel_device_to_sortable_string (device),
800- PANEL_DEVICES_COLUMN_TITLE, title,
801+ PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE),
802 PANEL_DEVICES_COLUMN_OBJECT, net_device,
803 -1);
804+ g_signal_connect (net_device, "notify::title",
805+ G_CALLBACK (panel_net_object_notify_title_cb), panel);
806+
807+ g_object_unref (net_device);
808+ g_signal_connect (device, "state-changed",
809+ G_CALLBACK (state_changed_cb), panel);
810
811 out:
812 return FALSE;
813@@ -539,6 +859,25 @@
814 }
815
816 static void
817+get_object_title (GtkTreeViewColumn *column,
818+ GtkCellRenderer *cell,
819+ GtkTreeModel *model,
820+ GtkTreeIter *iter,
821+ gpointer data)
822+{
823+ NetObject *object;
824+
825+ gtk_tree_model_get (model, iter,
826+ PANEL_DEVICES_COLUMN_OBJECT, &object,
827+ -1);
828+ if (!object)
829+ return;
830+
831+ g_object_set (cell, "text", net_object_get_title (object), NULL);
832+ g_object_unref (object);
833+}
834+
835+static void
836 panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview)
837 {
838 CcNetworkPanelPrivate *priv = panel->priv;
839@@ -548,8 +887,13 @@
840
841 /* image */
842 renderer = gtk_cell_renderer_pixbuf_new ();
843- g_object_set (renderer, "stock-size", gtk_icon_size_from_name ("cc-sidebar-list"), NULL);
844- gtk_cell_renderer_set_padding (renderer, 4, 4);
845+ g_object_set (renderer,
846+ "width", 32,
847+ "xalign", 1.0,
848+ "stock-size", GTK_ICON_SIZE_MENU,
849+ "follow-state", TRUE,
850+ NULL);
851+ gtk_cell_renderer_set_padding (renderer, 4, 10);
852
853 column = gtk_tree_view_column_new_with_attributes ("icon", renderer,
854 "icon-name", PANEL_DEVICES_COLUMN_ICON,
855@@ -562,14 +906,19 @@
856 "wrap-mode", PANGO_WRAP_WORD,
857 "ellipsize", PANGO_ELLIPSIZE_END,
858 NULL);
859- column = gtk_tree_view_column_new_with_attributes ("title", renderer,
860- "markup", PANEL_DEVICES_COLUMN_TITLE,
861- NULL);
862- gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_SORT);
863+ column = gtk_tree_view_column_new_with_attributes ("title", renderer, NULL);
864+ gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column),
865+ renderer,
866+ get_object_title,
867+ NULL, NULL);
868+ gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_OBJECT);
869 liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
870 "liststore_devices"));
871+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (liststore_devices),
872+ PANEL_DEVICES_COLUMN_OBJECT,
873+ panel_net_object_sort_func, NULL, NULL);
874 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore_devices),
875- PANEL_DEVICES_COLUMN_SORT,
876+ PANEL_DEVICES_COLUMN_OBJECT,
877 GTK_SORT_ASCENDING);
878 gtk_tree_view_append_column (treeview, column);
879 gtk_tree_view_column_set_expand (column, TRUE);
880@@ -616,6 +965,7 @@
881 }
882 i++;
883 }
884+ g_object_unref (object);
885 out:
886 g_list_free (panels);
887 }
888@@ -623,7 +973,6 @@
889 static void
890 panel_add_proxy_device (CcNetworkPanel *panel)
891 {
892- gchar *title;
893 GtkListStore *liststore_devices;
894 GtkTreeIter iter;
895 NetProxy *proxy;
896@@ -643,39 +992,21 @@
897 /* add proxy to device list */
898 liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
899 "liststore_devices"));
900- title = g_strdup_printf ("%s", _("Network proxy"));
901+ net_object_set_title (NET_OBJECT (proxy), _("Network proxy"));
902 gtk_list_store_append (liststore_devices, &iter);
903 gtk_list_store_set (liststore_devices,
904 &iter,
905- PANEL_DEVICES_COLUMN_ICON, "preferences-system-network",
906- PANEL_DEVICES_COLUMN_TITLE, title,
907- PANEL_DEVICES_COLUMN_SORT, "9",
908+ PANEL_DEVICES_COLUMN_ICON, "preferences-system-network-symbolic",
909 PANEL_DEVICES_COLUMN_OBJECT, proxy,
910 -1);
911- g_free (title);
912+
913+ /* NOTE: No connect to notify::title here as it is guaranteed to not
914+ * be changed by anyone.*/
915+
916 g_object_unref (proxy);
917 }
918
919 static void
920-cc_network_panel_notify_enable_active_cb (GtkSwitch *sw,
921- GParamSpec *pspec,
922- CcNetworkPanel *panel)
923-{
924- gboolean enable;
925- struct rfkill_event event;
926-
927- enable = gtk_switch_get_active (sw);
928- g_debug ("Setting killswitch to %d", enable);
929-
930- memset (&event, 0, sizeof(event));
931- event.op = RFKILL_OP_CHANGE_ALL;
932- event.type = RFKILL_TYPE_ALL;
933- event.soft = enable ? 1 : 0;
934- if (cc_rfkill_glib_send_event (panel->priv->rfkill, &event) < 0)
935- g_warning ("Setting the killswitch %s failed", enable ? "on" : "off");
936-}
937-
938-static void
939 connection_state_changed (NMActiveConnection *c, GParamSpec *pspec, CcNetworkPanel *panel)
940 {
941 }
942@@ -699,7 +1030,7 @@
943 for (j = 0; devices && j < devices->len; j++)
944 g_debug (" %s", nm_device_get_udi (g_ptr_array_index (devices, j)));
945 if (NM_IS_VPN_CONNECTION (connection))
946- g_debug (" VPN base connection: %s", nm_active_connection_get_specific_object (connection));
947+ g_debug (" VPN base connection: %s", nm_active_connection_get_specific_object_path (connection));
948
949 if (g_object_get_data (G_OBJECT (connection), "has-state-changed-handler") == NULL) {
950 g_signal_connect_object (connection, "notify::state",
951@@ -714,6 +1045,7 @@
952 {
953 g_debug ("New device added");
954 panel_add_device (panel, device);
955+ panel_refresh_device_titles (panel);
956 }
957
958 static void
959@@ -721,6 +1053,7 @@
960 {
961 g_debug ("Device removed");
962 panel_remove_device (panel, device);
963+ panel_refresh_device_titles (panel);
964 }
965
966 static void
967@@ -734,7 +1067,7 @@
968 CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
969
970 /* clear all devices we added */
971- if (!nm_client_get_manager_running (client)) {
972+ if (!nm_client_get_nm_running (client)) {
973 g_debug ("NM disappeared");
974 liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
975 "liststore_devices"));
976@@ -759,12 +1092,14 @@
977 select_first_device (panel);
978 }
979
980+ panel_refresh_device_titles (panel);
981+
982 g_debug ("Calling handle_argv() after cold-plugging devices");
983 handle_argv (panel);
984 }
985
986 static NetObject *
987-find_in_model_by_id (CcNetworkPanel *panel, const gchar *id)
988+find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out)
989 {
990 gboolean ret;
991 NetObject *object_tmp;
992@@ -793,6 +1128,8 @@
993 }
994 } while (object == NULL && gtk_tree_model_iter_next (model, &iter));
995 out:
996+ if (iter_out)
997+ *iter_out = iter;
998 return object;
999 }
1000
1001@@ -800,7 +1137,6 @@
1002 panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
1003 {
1004 gchar *title;
1005- gchar *title_markup;
1006 GtkListStore *liststore_devices;
1007 GtkTreeIter iter;
1008 NetVpn *net_vpn;
1009@@ -810,10 +1146,10 @@
1010
1011 /* does already exist */
1012 id = nm_connection_get_path (connection);
1013- if (find_in_model_by_id (panel, id) != NULL)
1014+ if (find_in_model_by_id (panel, id, NULL) != NULL)
1015 return;
1016
1017- /* add as a virtual object */
1018+ /* add as a VPN object */
1019 net_vpn = g_object_new (NET_TYPE_VPN,
1020 "panel", panel,
1021 "removable", TRUE,
1022@@ -836,19 +1172,19 @@
1023 liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
1024 "liststore_devices"));
1025 title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (connection));
1026- title_markup = g_strdup (title);
1027
1028 net_object_set_title (NET_OBJECT (net_vpn), title);
1029 gtk_list_store_append (liststore_devices, &iter);
1030 gtk_list_store_set (liststore_devices,
1031 &iter,
1032- PANEL_DEVICES_COLUMN_ICON, "network-vpn",
1033- PANEL_DEVICES_COLUMN_TITLE, title_markup,
1034- PANEL_DEVICES_COLUMN_SORT, "5",
1035+ PANEL_DEVICES_COLUMN_ICON, "network-vpn-symbolic",
1036 PANEL_DEVICES_COLUMN_OBJECT, net_vpn,
1037 -1);
1038+ g_signal_connect (net_vpn, "notify::title",
1039+ G_CALLBACK (panel_net_object_notify_title_cb), panel);
1040+
1041 g_free (title);
1042- g_free (title_markup);
1043+ g_object_unref (net_vpn);
1044 }
1045
1046 static void
1047@@ -856,130 +1192,91 @@
1048 NMConnection *connection)
1049 {
1050 NMSettingConnection *s_con;
1051- const gchar *type;
1052+ const gchar *type, *iface;
1053
1054 s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection,
1055 NM_TYPE_SETTING_CONNECTION));
1056 type = nm_setting_connection_get_connection_type (s_con);
1057- if (g_strcmp0 (type, "vpn") != 0)
1058- return;
1059+ iface = nm_connection_get_interface_name (connection);
1060+ if (g_strcmp0 (type, "vpn") != 0 && iface == NULL)
1061+ return;
1062+
1063+ /* Don't add the libvirtd bridge to the UI */
1064+ if (g_strcmp0 (nm_setting_connection_get_interface_name (s_con), "virbr0") == 0)
1065+ return;
1066+
1067 g_debug ("add %s/%s remote connection: %s",
1068 type, g_type_name_from_instance ((GTypeInstance*)connection),
1069 nm_connection_get_path (connection));
1070- panel_add_vpn_device (panel, connection);
1071+ if (!iface)
1072+ panel_add_vpn_device (panel, connection);
1073 }
1074
1075 static void
1076-notify_new_connection_cb (NMRemoteSettings *settings,
1077- NMRemoteConnection *connection,
1078- CcNetworkPanel *panel)
1079+notify_connection_added_cb (NMClient *client,
1080+ NMRemoteConnection *connection,
1081+ CcNetworkPanel *panel)
1082 {
1083 add_connection (panel, NM_CONNECTION (connection));
1084 }
1085
1086 static void
1087-notify_connections_read_cb (NMRemoteSettings *settings,
1088- CcNetworkPanel *panel)
1089-{
1090- GSList *list, *iter;
1091- NMConnection *connection;
1092-
1093- list = nm_remote_settings_list_connections (settings);
1094- g_debug ("%p has %i remote connections",
1095- panel, g_slist_length (list));
1096- for (iter = list; iter; iter = g_slist_next (iter)) {
1097- connection = NM_CONNECTION (iter->data);
1098- add_connection (panel, connection);
1099- }
1100-}
1101-
1102-static gboolean
1103-display_version_warning_idle (CcNetworkPanel *panel)
1104-{
1105- GtkWidget *dialog;
1106- GtkWidget *image;
1107- GtkWindow *window;
1108- const char *message;
1109-
1110- /* TRANSLATORS: the user is running a NM that is not API compatible */
1111- message = _("The system network services are not compatible with this version.");
1112-
1113- window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
1114- dialog = gtk_message_dialog_new (window,
1115- GTK_DIALOG_MODAL,
1116- GTK_MESSAGE_ERROR,
1117- GTK_BUTTONS_CLOSE,
1118- "%s",
1119- message);
1120- image = gtk_image_new_from_icon_name ("computer-fail", GTK_ICON_SIZE_DIALOG);
1121- gtk_widget_show (image);
1122- gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
1123-
1124- gtk_dialog_run (GTK_DIALOG (dialog));
1125- gtk_widget_destroy (dialog);
1126-
1127- return FALSE;
1128-}
1129-
1130-static gboolean
1131 panel_check_network_manager_version (CcNetworkPanel *panel)
1132 {
1133+ GtkWidget *box;
1134+ GtkWidget *label;
1135+ gchar *markup;
1136 const gchar *version;
1137- guint minor = 0;
1138- gboolean ret = TRUE;
1139
1140 /* parse running version */
1141 version = nm_client_get_version (panel->priv->client);
1142 if (version == NULL) {
1143- ret = FALSE;
1144-
1145- /* do modal dialog in idle so we don't block startup */
1146- panel->priv->nm_warning_idle = g_idle_add ((GSourceFunc)display_version_warning_idle, panel);
1147+ gtk_container_remove (GTK_CONTAINER (panel), gtk_bin_get_child (GTK_BIN (panel)));
1148+
1149+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
1150+ gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1151+ gtk_widget_set_vexpand (box, TRUE);
1152+ gtk_container_add (GTK_CONTAINER (panel), box);
1153+
1154+ label = gtk_label_new (_("Oops, something has gone wrong. Please contact your software vendor."));
1155+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1156+ gtk_widget_set_valign (label, GTK_ALIGN_END);
1157+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
1158+
1159+ markup = g_strdup_printf ("<small><tt>%s</tt></small>",
1160+ _("NetworkManager needs to be running."));
1161+ label = gtk_label_new (NULL);
1162+ gtk_label_set_markup (GTK_LABEL (label), markup);
1163+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1164+ gtk_widget_set_valign (label, GTK_ALIGN_START);
1165+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
1166+
1167+ gtk_widget_show_all (box);
1168+ g_free (markup);
1169+ } else {
1170+ manager_running (panel->priv->client, NULL, panel);
1171 }
1172+}
1173
1174- return ret;
1175+static void
1176+editor_done (NetConnectionEditor *editor,
1177+ gboolean success,
1178+ gpointer user_data)
1179+{
1180+ g_object_unref (editor);
1181 }
1182
1183 static void
1184 add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel)
1185 {
1186- GtkWidget *dialog;
1187- gint response;
1188-
1189- dialog = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
1190- "connection_type_dialog"));
1191- gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))));
1192-
1193- response = gtk_dialog_run (GTK_DIALOG (dialog));
1194-
1195- gtk_widget_hide (dialog);
1196-
1197- if (response == GTK_RESPONSE_OK) {
1198- GtkComboBox *combo;
1199- GtkTreeModel *model;
1200- GtkTreeIter iter;
1201- gchar *type;
1202- gchar *cmdline;
1203- GError *error;
1204-
1205- combo = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder,
1206- "connection_type_combo"));
1207- model = gtk_combo_box_get_model (combo);
1208- gtk_combo_box_get_active_iter (combo, &iter);
1209- type = NULL;
1210- gtk_tree_model_get (model, &iter, 1, &type, -1);
1211-
1212- cmdline = g_strdup_printf ("nm-connection-editor --create --type %s", type);
1213- g_debug ("Launching '%s'\n", cmdline);
1214-
1215- error = NULL;
1216- if (!g_spawn_command_line_async (cmdline, &error)) {
1217- g_warning ("Failed to launch nm-connection-editor: %s", error->message);
1218- g_error_free (error);
1219- }
1220- g_free (cmdline);
1221- g_free (type);
1222- }
1223+ NetConnectionEditor *editor;
1224+ GtkWindow *toplevel;
1225+
1226+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
1227+ editor = net_connection_editor_new (toplevel, NULL, NULL, NULL,
1228+ panel->priv->client);
1229+ g_signal_connect (editor, "done", G_CALLBACK (editor_done), panel);
1230+ net_connection_editor_run (editor);
1231 }
1232
1233 static void
1234@@ -994,131 +1291,38 @@
1235
1236 /* delete the object */
1237 net_object_delete (object);
1238+ g_object_unref (object);
1239 }
1240
1241 static void
1242 on_toplevel_map (GtkWidget *widget,
1243 CcNetworkPanel *panel)
1244 {
1245- gboolean ret;
1246-
1247 /* is the user compiling against a new version, but not running
1248 * the daemon? */
1249- ret = panel_check_network_manager_version (panel);
1250- if (ret) {
1251- manager_running (panel->priv->client, NULL, panel);
1252- } else {
1253- /* just select the proxy settings */
1254- select_first_device (panel);
1255- }
1256-}
1257-
1258-static void
1259-rfkill_changed (CcRfkillGlib *rfkill,
1260- GList *events,
1261- CcNetworkPanel *panel)
1262-{
1263- gboolean enabled;
1264- GList *l;
1265- GHashTableIter iter;
1266- gpointer key, value;
1267-
1268- enabled = TRUE;
1269-
1270- for (l = events; l != NULL; l = l->next) {
1271- struct rfkill_event *event = l->data;
1272-
1273- if (event->op == RFKILL_OP_ADD)
1274- g_hash_table_insert (panel->priv->killswitches,
1275- GINT_TO_POINTER (event->idx),
1276- GINT_TO_POINTER (event->soft || event->hard));
1277- else if (event->op == RFKILL_OP_CHANGE)
1278- g_hash_table_insert (panel->priv->killswitches,
1279- GINT_TO_POINTER (event->idx),
1280- GINT_TO_POINTER (event->soft || event->hard));
1281- else if (event->op == RFKILL_OP_DEL)
1282- g_hash_table_remove (panel->priv->killswitches,
1283- GINT_TO_POINTER (event->idx));
1284- }
1285-
1286- g_hash_table_iter_init (&iter, panel->priv->killswitches);
1287- while (g_hash_table_iter_next (&iter, &key, &value)) {
1288- int idx, state;
1289-
1290- idx = GPOINTER_TO_INT (key);
1291- state = GPOINTER_TO_INT (value);
1292- g_debug ("Killswitch %d is %s", idx, state ? "enabled" : "disabled");
1293-
1294- /* A single device that's enabled? airplane mode is off */
1295- if (state == FALSE) {
1296- enabled = FALSE;
1297- break;
1298- }
1299- }
1300-
1301- if (enabled != gtk_switch_get_active (panel->priv->rfkill_switch)) {
1302- g_signal_handlers_block_by_func (panel->priv->rfkill_switch,
1303- cc_network_panel_notify_enable_active_cb,
1304- panel);
1305- gtk_switch_set_active (panel->priv->rfkill_switch, enabled);
1306- g_signal_handlers_unblock_by_func (panel->priv->rfkill_switch,
1307- cc_network_panel_notify_enable_active_cb,
1308- panel);
1309- }
1310-}
1311-
1312-static gboolean
1313-network_add_shell_header_widgets_cb (gpointer user_data)
1314-{
1315- CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
1316- GtkWidget *box;
1317- GtkWidget *label;
1318- GtkWidget *widget;
1319-
1320- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
1321- /* TRANSLATORS: this is to disable the radio hardware in the
1322- * network panel */
1323- label = gtk_label_new_with_mnemonic (_("Air_plane Mode"));
1324- gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
1325- gtk_widget_set_visible (label, TRUE);
1326- widget = gtk_switch_new ();
1327- gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
1328- gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
1329- gtk_widget_show_all (box);
1330- panel->priv->rfkill_switch = GTK_SWITCH (widget);
1331- cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (panel)), box);
1332- panel->priv->kill_switch_header = g_object_ref (box);
1333-
1334- panel->priv->killswitches = g_hash_table_new (g_direct_hash, g_direct_equal);
1335- panel->priv->rfkill = cc_rfkill_glib_new ();
1336- g_signal_connect (G_OBJECT (panel->priv->rfkill), "changed",
1337- G_CALLBACK (rfkill_changed), panel);
1338- if (cc_rfkill_glib_open (panel->priv->rfkill) < 0)
1339- gtk_widget_hide (box);
1340-
1341- g_signal_connect (panel->priv->rfkill_switch, "notify::active",
1342- G_CALLBACK (cc_network_panel_notify_enable_active_cb),
1343- panel);
1344-
1345- return FALSE;
1346+ panel_check_network_manager_version (panel);
1347 }
1348
1349 static void
1350 cc_network_panel_init (CcNetworkPanel *panel)
1351 {
1352- DBusGConnection *bus = NULL;
1353 GError *error = NULL;
1354 GtkStyleContext *context;
1355 GtkTreeSelection *selection;
1356 GtkWidget *widget;
1357 GtkWidget *toplevel;
1358+ GDBusConnection *system_bus;
1359+ GtkCssProvider *provider;
1360+ const GPtrArray *connections;
1361+ guint i;
1362
1363 panel->priv = NETWORK_PANEL_PRIVATE (panel);
1364+ g_resources_register (cc_network_get_resource ());
1365
1366 panel->priv->builder = gtk_builder_new ();
1367- gtk_builder_add_from_file (panel->priv->builder,
1368- GNOMECC_UI_DIR "/network.ui",
1369- &error);
1370+ gtk_builder_add_from_resource (panel->priv->builder,
1371+ "/org/gnome/control-center/network/network.ui",
1372+ &error);
1373 if (error != NULL) {
1374 g_warning ("Could not load interface file: %s", error->message);
1375 g_error_free (error);
1376@@ -1150,16 +1354,35 @@
1377 panel_add_proxy_device (panel);
1378
1379 /* use NetworkManager client */
1380- panel->priv->client = nm_client_new ();
1381- g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_MANAGER_RUNNING,
1382+ panel->priv->client = nm_client_new (NULL, NULL);
1383+ g_signal_connect (panel->priv->client, "notify::nm-running" ,
1384 G_CALLBACK (manager_running), panel);
1385- g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS,
1386+ g_signal_connect (panel->priv->client, "notify::active-connections",
1387 G_CALLBACK (active_connections_changed), panel);
1388 g_signal_connect (panel->priv->client, "device-added",
1389 G_CALLBACK (device_added_cb), panel);
1390 g_signal_connect (panel->priv->client, "device-removed",
1391 G_CALLBACK (device_removed_cb), panel);
1392
1393+ /* Setup ModemManager client */
1394+ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
1395+ if (system_bus == NULL) {
1396+ g_warning ("Error connecting to system D-Bus: %s",
1397+ error->message);
1398+ g_clear_error (&error);
1399+ } else {
1400+ panel->priv->modem_manager = mm_manager_new_sync (system_bus,
1401+ G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
1402+ NULL,
1403+ &error);
1404+ if (panel->priv->modem_manager == NULL) {
1405+ g_warning ("Error connecting to ModemManager: %s",
1406+ error->message);
1407+ g_clear_error (&error);
1408+ }
1409+ g_object_unref (system_bus);
1410+ }
1411+
1412 widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
1413 "add_toolbutton"));
1414 g_signal_connect (widget, "clicked",
1415@@ -1172,17 +1395,8 @@
1416 G_CALLBACK (remove_connection), panel);
1417
1418 /* add remote settings such as VPN settings as virtual devices */
1419- bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
1420- if (bus == NULL) {
1421- g_warning ("Error connecting to system D-Bus: %s",
1422- error->message);
1423- g_error_free (error);
1424- }
1425- panel->priv->remote_settings = nm_remote_settings_new (bus);
1426- g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ,
1427- G_CALLBACK (notify_connections_read_cb), panel);
1428- g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_NEW_CONNECTION,
1429- G_CALLBACK (notify_new_connection_cb), panel);
1430+ g_signal_connect (panel->priv->client, NM_CLIENT_CONNECTION_ADDED,
1431+ G_CALLBACK (notify_connection_added_cb), panel);
1432
1433 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel));
1434 g_signal_connect_after (toplevel, "map", G_CALLBACK (on_toplevel_map), panel);
1435@@ -1194,10 +1408,22 @@
1436
1437 widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
1438 "vbox1"));
1439- gtk_widget_reparent (widget, (GtkWidget *) panel);
1440-
1441- /* add kill switch widgets when dialog activated */
1442- panel->priv->add_header_widgets_idle = g_idle_add (network_add_shell_header_widgets_cb, panel);
1443+ gtk_container_add (GTK_CONTAINER (panel), widget);
1444+
1445+ provider = gtk_css_provider_new ();
1446+ gtk_css_provider_load_from_data (provider, ".circular-button { border-radius: 20px; -gtk-outline-radius: 20px; }", -1, NULL);
1447+ gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
1448+ GTK_STYLE_PROVIDER (provider),
1449+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
1450+ g_object_unref (provider);
1451+
1452+ /* Cold-plug existing connections */
1453+ connections = nm_client_get_connections (panel->priv->client);
1454+ for (i = 0; i < connections->len; i++)
1455+ add_connection (panel, connections->pdata[i]);
1456+
1457+ g_debug ("Calling handle_argv() after cold-plugging connections");
1458+ handle_argv (panel);
1459 }
1460
1461 void
1462
1463=== modified file 'panels/network/cc-network-panel.h'
1464--- panels/network/cc-network-panel.h 2011-11-07 18:03:14 +0000
1465+++ panels/network/cc-network-panel.h 2019-05-01 13:56:52 +0000
1466@@ -65,7 +65,9 @@
1467
1468 GType cc_network_panel_get_type (void) G_GNUC_CONST;
1469
1470-void cc_network_panel_register (GIOModule *module);
1471+void cc_network_panel_register (GIOModule *module);
1472+
1473+GPtrArray *cc_network_panel_get_devices (CcNetworkPanel *panel);
1474
1475 G_END_DECLS
1476
1477
1478=== added directory 'panels/network/connection-editor'
1479=== added file 'panels/network/connection-editor/8021x-security-page.ui'
1480--- panels/network/connection-editor/8021x-security-page.ui 1970-01-01 00:00:00 +0000
1481+++ panels/network/connection-editor/8021x-security-page.ui 2019-05-01 13:56:52 +0000
1482@@ -0,0 +1,295 @@
1483+<?xml version="1.0" encoding="UTF-8"?>
1484+<interface>
1485+ <!-- interface-requires gtk+ 3.0 -->
1486+ <object class="GtkNotebook" id="page">
1487+ <property name="visible">True</property>
1488+ <property name="can_focus">True</property>
1489+ <property name="show_tabs">False</property>
1490+ <property name="show_border">False</property>
1491+ <child>
1492+ <object class="GtkGrid" id="grid">
1493+ <property name="visible">True</property>
1494+ <property name="can_focus">False</property>
1495+ <property name="margin_start">50</property>
1496+ <property name="margin_end">50</property>
1497+ <property name="margin_top">12</property>
1498+ <property name="margin_bottom">12</property>
1499+ <property name="hexpand">True</property>
1500+ <property name="vexpand">True</property>
1501+ <property name="row_spacing">10</property>
1502+ <property name="column_spacing">6</property>
1503+ <child>
1504+ <object class="GtkLabel" id="heading_sec">
1505+ <property name="visible">True</property>
1506+ <property name="can_focus">False</property>
1507+ <property name="xalign">1</property>
1508+ <property name="label" translatable="yes">802.1x _Security</property>
1509+ <property name="use_underline">True</property>
1510+ <property name="mnemonic_widget">8021x_switch</property>
1511+ </object>
1512+ <packing>
1513+ <property name="left_attach">0</property>
1514+ <property name="top_attach">0</property>
1515+ <property name="width">1</property>
1516+ <property name="height">1</property>
1517+ </packing>
1518+ </child>
1519+ <child>
1520+ <object class="GtkSwitch" id="8021x_switch">
1521+ <property name="visible">True</property>
1522+ <property name="can_focus">True</property>
1523+ <property name="halign">start</property>
1524+ <property name="hexpand">True</property>
1525+ </object>
1526+ <packing>
1527+ <property name="left_attach">1</property>
1528+ <property name="top_attach">0</property>
1529+ <property name="width">1</property>
1530+ <property name="height">1</property>
1531+ </packing>
1532+ </child>
1533+ <child>
1534+ <object class="GtkBox" id="vbox">
1535+ <property name="visible">True</property>
1536+ <property name="can_focus">False</property>
1537+ <property name="orientation">vertical</property>
1538+ <child>
1539+ <placeholder/>
1540+ </child>
1541+ </object>
1542+ <packing>
1543+ <property name="left_attach">0</property>
1544+ <property name="top_attach">1</property>
1545+ <property name="width">2</property>
1546+ <property name="height">1</property>
1547+ </packing>
1548+ </child>
1549+ </object>
1550+ </child>
1551+ <child type="tab">
1552+ <object class="GtkLabel" id="label1">
1553+ <property name="visible">True</property>
1554+ <property name="can_focus">False</property>
1555+ <property name="label" translatable="yes">page 1</property>
1556+ </object>
1557+ <packing>
1558+ <property name="tab_fill">False</property>
1559+ </packing>
1560+ </child>
1561+ <child>
1562+ <object class="GtkGrid" id="grid1">
1563+ <property name="visible">True</property>
1564+ <property name="can_focus">False</property>
1565+ <property name="margin_start">50</property>
1566+ <property name="margin_end">50</property>
1567+ <property name="margin_top">12</property>
1568+ <property name="margin_bottom">12</property>
1569+ <property name="row_spacing">10</property>
1570+ <property name="column_spacing">6</property>
1571+ <child>
1572+ <object class="GtkEntry" id="entry1">
1573+ <property name="visible">True</property>
1574+ <property name="can_focus">True</property>
1575+ <property name="invisible_char">●</property>
1576+ <property name="width_chars">35</property>
1577+ </object>
1578+ <packing>
1579+ <property name="left_attach">1</property>
1580+ <property name="top_attach">0</property>
1581+ <property name="width">1</property>
1582+ <property name="height">1</property>
1583+ </packing>
1584+ </child>
1585+ <child>
1586+ <object class="GtkEntry" id="entry2">
1587+ <property name="visible">True</property>
1588+ <property name="can_focus">True</property>
1589+ <property name="invisible_char">●</property>
1590+ </object>
1591+ <packing>
1592+ <property name="left_attach">1</property>
1593+ <property name="top_attach">1</property>
1594+ <property name="width">1</property>
1595+ <property name="height">1</property>
1596+ </packing>
1597+ </child>
1598+ <child>
1599+ <object class="GtkEntry" id="entry3">
1600+ <property name="visible">True</property>
1601+ <property name="can_focus">True</property>
1602+ <property name="invisible_char">●</property>
1603+ </object>
1604+ <packing>
1605+ <property name="left_attach">1</property>
1606+ <property name="top_attach">2</property>
1607+ <property name="width">1</property>
1608+ <property name="height">1</property>
1609+ </packing>
1610+ </child>
1611+ <child>
1612+ <object class="GtkEntry" id="entry4">
1613+ <property name="visible">True</property>
1614+ <property name="can_focus">True</property>
1615+ <property name="invisible_char">●</property>
1616+ </object>
1617+ <packing>
1618+ <property name="left_attach">1</property>
1619+ <property name="top_attach">3</property>
1620+ <property name="width">1</property>
1621+ <property name="height">1</property>
1622+ </packing>
1623+ </child>
1624+ <child>
1625+ <object class="GtkEntry" id="entry5">
1626+ <property name="visible">True</property>
1627+ <property name="can_focus">True</property>
1628+ <property name="invisible_char">●</property>
1629+ </object>
1630+ <packing>
1631+ <property name="left_attach">1</property>
1632+ <property name="top_attach">4</property>
1633+ <property name="width">1</property>
1634+ <property name="height">1</property>
1635+ </packing>
1636+ </child>
1637+ <child>
1638+ <object class="GtkEntry" id="entry6">
1639+ <property name="visible">True</property>
1640+ <property name="can_focus">True</property>
1641+ <property name="invisible_char">●</property>
1642+ </object>
1643+ <packing>
1644+ <property name="left_attach">1</property>
1645+ <property name="top_attach">5</property>
1646+ <property name="width">1</property>
1647+ <property name="height">1</property>
1648+ </packing>
1649+ </child>
1650+ <child>
1651+ <object class="GtkEntry" id="entry7">
1652+ <property name="visible">True</property>
1653+ <property name="can_focus">True</property>
1654+ <property name="invisible_char">●</property>
1655+ </object>
1656+ <packing>
1657+ <property name="left_attach">1</property>
1658+ <property name="top_attach">6</property>
1659+ <property name="width">1</property>
1660+ <property name="height">1</property>
1661+ </packing>
1662+ </child>
1663+ <child>
1664+ <object class="GtkEntry" id="entry8">
1665+ <property name="visible">True</property>
1666+ <property name="can_focus">True</property>
1667+ <property name="invisible_char">●</property>
1668+ </object>
1669+ <packing>
1670+ <property name="left_attach">1</property>
1671+ <property name="top_attach">7</property>
1672+ <property name="width">1</property>
1673+ <property name="height">1</property>
1674+ </packing>
1675+ </child>
1676+ <child>
1677+ <object class="GtkEntry" id="entry9">
1678+ <property name="visible">True</property>
1679+ <property name="can_focus">True</property>
1680+ <property name="invisible_char">●</property>
1681+ </object>
1682+ <packing>
1683+ <property name="left_attach">1</property>
1684+ <property name="top_attach">8</property>
1685+ <property name="width">1</property>
1686+ <property name="height">1</property>
1687+ </packing>
1688+ </child>
1689+ <child>
1690+ <object class="GtkEntry" id="entry10">
1691+ <property name="visible">True</property>
1692+ <property name="can_focus">True</property>
1693+ <property name="invisible_char">●</property>
1694+ </object>
1695+ <packing>
1696+ <property name="left_attach">1</property>
1697+ <property name="top_attach">9</property>
1698+ <property name="width">1</property>
1699+ <property name="height">1</property>
1700+ </packing>
1701+ </child>
1702+ <child>
1703+ <object class="GtkLabel" id="label3">
1704+ <property name="visible">True</property>
1705+ <property name="can_focus">False</property>
1706+ <property name="label" translatable="yes">Anony_mous identity</property>
1707+ <property name="use_underline">True</property>
1708+ </object>
1709+ <packing>
1710+ <property name="left_attach">0</property>
1711+ <property name="top_attach">0</property>
1712+ <property name="width">1</property>
1713+ <property name="height">1</property>
1714+ </packing>
1715+ </child>
1716+ <child>
1717+ <object class="GtkLabel" id="label4">
1718+ <property name="visible">True</property>
1719+ <property name="can_focus">False</property>
1720+ <property name="label" translatable="yes">Inner _authentication</property>
1721+ <property name="use_underline">True</property>
1722+ </object>
1723+ <packing>
1724+ <property name="left_attach">0</property>
1725+ <property name="top_attach">1</property>
1726+ <property name="width">1</property>
1727+ <property name="height">1</property>
1728+ </packing>
1729+ </child>
1730+ <child>
1731+ <placeholder/>
1732+ </child>
1733+ <child>
1734+ <placeholder/>
1735+ </child>
1736+ <child>
1737+ <placeholder/>
1738+ </child>
1739+ <child>
1740+ <placeholder/>
1741+ </child>
1742+ <child>
1743+ <placeholder/>
1744+ </child>
1745+ <child>
1746+ <placeholder/>
1747+ </child>
1748+ <child>
1749+ <placeholder/>
1750+ </child>
1751+ <child>
1752+ <placeholder/>
1753+ </child>
1754+ </object>
1755+ <packing>
1756+ <property name="position">1</property>
1757+ </packing>
1758+ </child>
1759+ <child type="tab">
1760+ <object class="GtkLabel" id="label2">
1761+ <property name="visible">True</property>
1762+ <property name="can_focus">False</property>
1763+ <property name="label" translatable="yes">page 2</property>
1764+ </object>
1765+ <packing>
1766+ <property name="position">1</property>
1767+ <property name="tab_fill">False</property>
1768+ </packing>
1769+ </child>
1770+ <child>
1771+ <placeholder/>
1772+ </child>
1773+ <child type="tab">
1774+ <placeholder/>
1775+ </child>
1776+ </object>
1777+</interface>
1778
1779=== added file 'panels/network/connection-editor/Makefile.am'
1780--- panels/network/connection-editor/Makefile.am 1970-01-01 00:00:00 +0000
1781+++ panels/network/connection-editor/Makefile.am 2019-05-01 13:56:52 +0000
1782@@ -0,0 +1,54 @@
1783+noinst_LTLIBRARIES = libconnection-editor.la
1784+
1785+BUILT_SOURCES = \
1786+ net-connection-editor-resources.c \
1787+ net-connection-editor-resources.h
1788+
1789+libconnection_editor_la_SOURCES = \
1790+ $(BUILT_SOURCES) \
1791+ net-connection-editor.h \
1792+ net-connection-editor.c \
1793+ ce-page.h \
1794+ ce-page.c \
1795+ ce-page-details.h \
1796+ ce-page-details.c \
1797+ ce-page-wifi.h \
1798+ ce-page-wifi.c \
1799+ ce-page-ip4.h \
1800+ ce-page-ip4.c \
1801+ ce-page-ip6.h \
1802+ ce-page-ip6.c \
1803+ ce-page-security.h \
1804+ ce-page-security.c \
1805+ ce-page-ethernet.h \
1806+ ce-page-ethernet.c \
1807+ ce-page-8021x-security.h \
1808+ ce-page-8021x-security.c \
1809+ ce-page-vpn.h \
1810+ ce-page-vpn.c \
1811+ vpn-helpers.h \
1812+ vpn-helpers.c \
1813+ ui-helpers.h \
1814+ ui-helpers.c
1815+
1816+libconnection_editor_la_CPPFLAGS = \
1817+ $(PANEL_CFLAGS) \
1818+ -I$(srcdir)/../wireless-security \
1819+ $(NETWORK_PANEL_CFLAGS) \
1820+ $(NETWORK_MANAGER_CFLAGS)
1821+
1822+libconnection_editor_la_LIBADD = \
1823+ $(builddir)/../wireless-security/libwireless-security.la \
1824+ $(NETWORK_PANEL_LIBS) \
1825+ $(NETWORK_MANAGER_LIBS)
1826+
1827+resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/connection-editor.gresource.xml)
1828+net-connection-editor-resources.c: connection-editor.gresource.xml $(resource_files)
1829+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name net_connection_editor $<
1830+net-connection-editor-resources.h: connection-editor.gresource.xml $(resource_files)
1831+ $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name net_connection_editor $<
1832+
1833+EXTRA_DIST = \
1834+ $(resource_files) connection-editor.gresource.xml
1835+
1836+-include $(top_srcdir)/git.mk
1837
1838=== added file 'panels/network/connection-editor/ce-page-8021x-security.c'
1839--- panels/network/connection-editor/ce-page-8021x-security.c 1970-01-01 00:00:00 +0000
1840+++ panels/network/connection-editor/ce-page-8021x-security.c 2019-05-01 13:56:52 +0000
1841@@ -0,0 +1,186 @@
1842+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
1843+/* NetworkManager Connection editor -- Connection editor for NetworkManager
1844+ *
1845+ * Dan Williams <dcbw@redhat.com>
1846+ *
1847+ * This program is free software; you can redistribute it and/or modify
1848+ * it under the terms of the GNU General Public License as published by
1849+ * the Free Software Foundation; either version 2 of the License, or
1850+ * (at your option) any later version.
1851+ *
1852+ * This program is distributed in the hope that it will be useful,
1853+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1854+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1855+ * GNU General Public License for more details.
1856+ *
1857+ * You should have received a copy of the GNU General Public License along
1858+ * with this program; if not, write to the Free Software Foundation, Inc.,
1859+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1860+ *
1861+ * (C) Copyright 2008 - 2012 Red Hat, Inc.
1862+ */
1863+
1864+#include "config.h"
1865+
1866+#include <string.h>
1867+
1868+#include <gtk/gtk.h>
1869+#include <glib/gi18n.h>
1870+
1871+#include <NetworkManager.h>
1872+
1873+#include "wireless-security.h"
1874+#include "ce-page-ethernet.h"
1875+#include "ce-page-8021x-security.h"
1876+
1877+G_DEFINE_TYPE (CEPage8021xSecurity, ce_page_8021x_security, CE_TYPE_PAGE)
1878+
1879+static void
1880+enable_toggled (GObject *sw, GParamSpec *pspec, gpointer user_data)
1881+{
1882+ CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (user_data);
1883+
1884+ gtk_widget_set_sensitive (page->security_widget, gtk_switch_get_active (page->enabled));
1885+ ce_page_changed (CE_PAGE (page));
1886+}
1887+
1888+static void
1889+stuff_changed (WirelessSecurity *sec, gpointer user_data)
1890+{
1891+ ce_page_changed (CE_PAGE (user_data));
1892+}
1893+
1894+static void
1895+finish_setup (CEPage8021xSecurity *page, gpointer unused, GError *error, gpointer user_data)
1896+{
1897+ GtkWidget *parent;
1898+ GtkWidget *vbox;
1899+ GtkWidget *heading;
1900+
1901+ if (error)
1902+ return;
1903+
1904+ vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox"));
1905+ heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec"));
1906+
1907+ page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
1908+
1909+ page->security = (WirelessSecurity *) ws_wpa_eap_new (CE_PAGE (page)->connection, TRUE, FALSE);
1910+ if (!page->security) {
1911+ g_warning ("Could not load 802.1x user interface.");
1912+ return;
1913+ }
1914+
1915+ wireless_security_set_changed_notify (page->security, stuff_changed, page);
1916+ page->security_widget = wireless_security_get_widget (page->security);
1917+ parent = gtk_widget_get_parent (page->security_widget);
1918+ if (parent)
1919+ gtk_container_remove (GTK_CONTAINER (parent), page->security_widget);
1920+
1921+ gtk_switch_set_active (page->enabled, page->initial_have_8021x);
1922+ g_signal_connect (page->enabled, "notify::active", G_CALLBACK (enable_toggled), page);
1923+ gtk_widget_set_sensitive (page->security_widget, page->initial_have_8021x);
1924+
1925+ gtk_size_group_add_widget (page->group, heading);
1926+ wireless_security_add_to_size_group (page->security, page->group);
1927+
1928+ gtk_container_add (GTK_CONTAINER (vbox), page->security_widget);
1929+
1930+}
1931+
1932+CEPage *
1933+ce_page_8021x_security_new (NMConnection *connection,
1934+ NMClient *client)
1935+{
1936+ CEPage8021xSecurity *page;
1937+
1938+ page = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY,
1939+ connection,
1940+ client,
1941+ "/org/gnome/control-center/network/8021x-security-page.ui",
1942+ _("Security")));
1943+
1944+ if (nm_connection_get_setting_802_1x (connection))
1945+ page->initial_have_8021x = TRUE;
1946+
1947+ page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "8021x_switch"));
1948+
1949+ g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL);
1950+
1951+ if (page->initial_have_8021x)
1952+ CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME;
1953+
1954+ return CE_PAGE (page);
1955+}
1956+
1957+static gboolean
1958+validate (CEPage *cepage, NMConnection *connection, GError **error)
1959+{
1960+ CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (cepage);
1961+ gboolean valid = TRUE;
1962+
1963+ if (gtk_switch_get_active (page->enabled)) {
1964+ NMConnection *tmp_connection;
1965+ NMSetting *s_8021x;
1966+
1967+ /* FIXME: get failed property and error out of wireless security objects */
1968+ valid = wireless_security_validate (page->security, error);
1969+ if (valid) {
1970+ NMSetting *s_con;
1971+
1972+ /* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */
1973+ tmp_connection = nm_simple_connection_new ();
1974+ nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ());
1975+
1976+ /* temp connection needs a 'connection' setting too, since most of
1977+ * the EAP methods need the UUID for CA cert ignore stuff.
1978+ */
1979+ s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
1980+ nm_connection_add_setting (tmp_connection, nm_setting_duplicate (s_con));
1981+
1982+ ws_802_1x_fill_connection (page->security, "wpa_eap_auth_combo", tmp_connection);
1983+
1984+ s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
1985+ nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x)));
1986+
1987+ g_object_unref (tmp_connection);
1988+ }
1989+ } else {
1990+ nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
1991+ valid = TRUE;
1992+ }
1993+
1994+ return valid;
1995+}
1996+
1997+static void
1998+ce_page_8021x_security_init (CEPage8021xSecurity *page)
1999+{
2000+}
2001+
2002+static void
2003+dispose (GObject *object)
2004+{
2005+ CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (object);
2006+
2007+ if (page->security) {
2008+ wireless_security_unref (page->security);
2009+ page->security = NULL;
2010+ }
2011+
2012+ g_clear_object (&page->group);
2013+
2014+ G_OBJECT_CLASS (ce_page_8021x_security_parent_class)->dispose (object);
2015+}
2016+
2017+static void
2018+ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class)
2019+{
2020+ GObjectClass *object_class = G_OBJECT_CLASS (security_class);
2021+ CEPageClass *parent_class = CE_PAGE_CLASS (security_class);
2022+
2023+ /* virtual methods */
2024+ object_class->dispose = dispose;
2025+
2026+ parent_class->validate = validate;
2027+}
2028
2029=== added file 'panels/network/connection-editor/ce-page-8021x-security.h'
2030--- panels/network/connection-editor/ce-page-8021x-security.h 1970-01-01 00:00:00 +0000
2031+++ panels/network/connection-editor/ce-page-8021x-security.h 2019-05-01 13:56:52 +0000
2032@@ -0,0 +1,63 @@
2033+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2034+/* NetworkManager Connection editor -- Connection editor for NetworkManager
2035+ *
2036+ * Dan Williams <dcbw@redhat.com>
2037+ *
2038+ * This program is free software; you can redistribute it and/or modify
2039+ * it under the terms of the GNU General Public License as published by
2040+ * the Free Software Foundation; either version 2 of the License, or
2041+ * (at your option) any later version.
2042+ *
2043+ * This program is distributed in the hope that it will be useful,
2044+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2045+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2046+ * GNU General Public License for more details.
2047+ *
2048+ * You should have received a copy of the GNU General Public License along
2049+ * with this program; if not, write to the Free Software Foundation, Inc.,
2050+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2051+ *
2052+ * (C) Copyright 2008 - 2012 Red Hat, Inc.
2053+ */
2054+
2055+#ifndef __CE_PAGE_8021X_SECURITY_H
2056+#define __CE_PAGE_8021X_SECURITY_H
2057+
2058+#include <NetworkManager.h>
2059+#include "wireless-security.h"
2060+
2061+#include <glib.h>
2062+#include <glib-object.h>
2063+
2064+#include "ce-page.h"
2065+
2066+#define CE_TYPE_PAGE_8021X_SECURITY (ce_page_8021x_security_get_type ())
2067+#define CE_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurity))
2068+#define CE_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass))
2069+#define CE_IS_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_8021X_SECURITY))
2070+#define CE_IS_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_8021X_SECURITY))
2071+#define CE_PAGE_8021X_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass))
2072+
2073+typedef struct CEPage8021xSecurity CEPage8021xSecurity;
2074+typedef struct CEPage8021xSecurityClass CEPage8021xSecurityClass;
2075+
2076+struct CEPage8021xSecurity {
2077+ CEPage parent;
2078+
2079+ GtkSwitch *enabled;
2080+ GtkWidget *security_widget;
2081+ WirelessSecurity *security;
2082+ GtkSizeGroup *group;
2083+ gboolean initial_have_8021x;
2084+};
2085+
2086+struct CEPage8021xSecurityClass {
2087+ CEPageClass parent;
2088+};
2089+
2090+GType ce_page_8021x_security_get_type (void);
2091+
2092+CEPage *ce_page_8021x_security_new (NMConnection *connection,
2093+ NMClient *client);
2094+
2095+#endif /* __CE_PAGE_8021X_SECURITY_H */
2096
2097=== added file 'panels/network/connection-editor/ce-page-details.c'
2098--- panels/network/connection-editor/ce-page-details.c 1970-01-01 00:00:00 +0000
2099+++ panels/network/connection-editor/ce-page-details.c 2019-05-01 13:56:52 +0000
2100@@ -0,0 +1,289 @@
2101+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2102+ *
2103+ * Copyright (C) 2012 Red Hat, Inc
2104+ *
2105+ * Licensed under the GNU General Public License Version 2
2106+ *
2107+ * This program is free software; you can redistribute it and/or modify
2108+ * it under the terms of the GNU General Public License as published by
2109+ * the Free Software Foundation; either version 2 of the License, or
2110+ * (at your option) any later version.
2111+ *
2112+ * This program is distributed in the hope that it will be useful,
2113+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2114+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2115+ * GNU General Public License for more details.
2116+ *
2117+ * You should have received a copy of the GNU General Public License
2118+ * along with this program; if not, write to the Free Software
2119+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2120+ */
2121+
2122+#include "config.h"
2123+
2124+#include <glib-object.h>
2125+#include <glib/gi18n.h>
2126+
2127+#include <NetworkManager.h>
2128+
2129+#include "../panel-common.h"
2130+#include "ce-page-details.h"
2131+
2132+G_DEFINE_TYPE (CEPageDetails, ce_page_details, CE_TYPE_PAGE)
2133+
2134+static void
2135+forget_cb (GtkButton *button, CEPageDetails *page)
2136+{
2137+ net_connection_editor_forget (page->editor);
2138+}
2139+
2140+static gchar *
2141+get_ap_security_string (NMAccessPoint *ap)
2142+{
2143+ NM80211ApSecurityFlags wpa_flags, rsn_flags;
2144+ NM80211ApFlags flags;
2145+ GString *str;
2146+
2147+ flags = nm_access_point_get_flags (ap);
2148+ wpa_flags = nm_access_point_get_wpa_flags (ap);
2149+ rsn_flags = nm_access_point_get_rsn_flags (ap);
2150+
2151+ str = g_string_new ("");
2152+ if ((flags & NM_802_11_AP_FLAGS_PRIVACY) &&
2153+ (wpa_flags == NM_802_11_AP_SEC_NONE) &&
2154+ (rsn_flags == NM_802_11_AP_SEC_NONE)) {
2155+ /* TRANSLATORS: this WEP WiFi security */
2156+ g_string_append_printf (str, "%s, ", _("WEP"));
2157+ }
2158+ if (wpa_flags != NM_802_11_AP_SEC_NONE) {
2159+ /* TRANSLATORS: this WPA WiFi security */
2160+ g_string_append_printf (str, "%s, ", _("WPA"));
2161+ }
2162+ if (rsn_flags != NM_802_11_AP_SEC_NONE) {
2163+ /* TRANSLATORS: this WPA WiFi security */
2164+ g_string_append_printf (str, "%s, ", _("WPA2"));
2165+ }
2166+ if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ||
2167+ (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
2168+ /* TRANSLATORS: this Enterprise WiFi security */
2169+ g_string_append_printf (str, "%s, ", _("Enterprise"));
2170+ }
2171+ if (str->len > 0)
2172+ g_string_set_size (str, str->len - 2);
2173+ else {
2174+ g_string_append (str, C_("Wifi security", "None"));
2175+ }
2176+ return g_string_free (str, FALSE);
2177+}
2178+
2179+static void
2180+update_last_used (CEPageDetails *page, NMConnection *connection)
2181+{
2182+ gchar *last_used = NULL;
2183+ GDateTime *now = NULL;
2184+ GDateTime *then = NULL;
2185+ gint days;
2186+ GTimeSpan diff;
2187+ guint64 timestamp;
2188+ NMSettingConnection *s_con;
2189+
2190+ s_con = nm_connection_get_setting_connection (connection);
2191+ if (s_con == NULL)
2192+ goto out;
2193+ timestamp = nm_setting_connection_get_timestamp (s_con);
2194+ if (timestamp == 0) {
2195+ last_used = g_strdup (_("Never"));
2196+ goto out;
2197+ }
2198+
2199+ /* calculate the amount of time that has elapsed */
2200+ now = g_date_time_new_now_utc ();
2201+ then = g_date_time_new_from_unix_utc (timestamp);
2202+
2203+ diff = g_date_time_difference (now, then);
2204+ days = diff / G_TIME_SPAN_DAY;
2205+ if (days == 0)
2206+ last_used = g_strdup (_("Today"));
2207+ else if (days == 1)
2208+ last_used = g_strdup (_("Yesterday"));
2209+ else
2210+ last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days);
2211+out:
2212+ panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", last_used);
2213+ if (now != NULL)
2214+ g_date_time_unref (now);
2215+ if (then != NULL)
2216+ g_date_time_unref (then);
2217+ g_free (last_used);
2218+}
2219+
2220+static void
2221+all_user_changed (GtkToggleButton *b, CEPageDetails *page)
2222+{
2223+ gboolean all_users;
2224+ NMSettingConnection *sc;
2225+
2226+ sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
2227+ all_users = gtk_toggle_button_get_active (b);
2228+
2229+ g_object_set (sc, "permissions", NULL, NULL);
2230+ if (!all_users)
2231+ nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL);
2232+}
2233+
2234+static void
2235+connect_details_page (CEPageDetails *page)
2236+{
2237+ NMSettingConnection *sc;
2238+ GtkWidget *widget;
2239+ guint speed;
2240+ guint strength;
2241+ NMDeviceState state;
2242+ NMAccessPoint *active_ap;
2243+ const gchar *str;
2244+ const gchar *type;
2245+ gboolean device_is_active;
2246+
2247+ if (NM_IS_DEVICE_WIFI (page->device))
2248+ active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (page->device));
2249+ else
2250+ active_ap = NULL;
2251+
2252+ state = page->device ? nm_device_get_state (page->device) : NM_DEVICE_STATE_DISCONNECTED;
2253+
2254+ device_is_active = FALSE;
2255+ speed = 0;
2256+ if (active_ap && page->ap == active_ap && state != NM_DEVICE_STATE_UNAVAILABLE) {
2257+ device_is_active = TRUE;
2258+ if (NM_IS_DEVICE_WIFI (page->device))
2259+ speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000;
2260+ } else if (page->device) {
2261+ NMActiveConnection *ac;
2262+ const gchar *p1, *p2;
2263+
2264+ ac = nm_device_get_active_connection (page->device);
2265+ p1 = ac ? nm_active_connection_get_uuid (ac) : NULL;
2266+ p2 = nm_connection_get_uuid (CE_PAGE (page)->connection);
2267+ if (g_strcmp0 (p1, p2) == 0) {
2268+ device_is_active = TRUE;
2269+ if (NM_IS_DEVICE_WIFI (page->device))
2270+ speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000;
2271+ else if (NM_IS_DEVICE_ETHERNET (page->device))
2272+ speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (page->device));
2273+ }
2274+ }
2275+ if (speed > 0)
2276+ str = g_strdup_printf (_("%d Mb/s"), speed);
2277+ else
2278+ str = NULL;
2279+ panel_set_device_widget_details (CE_PAGE (page)->builder, "speed", str);
2280+ g_clear_pointer (&str, g_free);
2281+
2282+ if (NM_IS_DEVICE_WIFI (page->device))
2283+ str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (page->device));
2284+ else if (NM_IS_DEVICE_ETHERNET (page->device))
2285+ str = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (page->device));
2286+
2287+ panel_set_device_widget_details (CE_PAGE (page)->builder, "mac", str);
2288+
2289+ str = NULL;
2290+ if (device_is_active && active_ap)
2291+ str = get_ap_security_string (active_ap);
2292+ panel_set_device_widget_details (CE_PAGE (page)->builder, "security", str);
2293+ g_clear_pointer (&str, g_free);
2294+
2295+ strength = 0;
2296+ if (page->ap != NULL)
2297+ strength = nm_access_point_get_strength (page->ap);
2298+
2299+ if (strength <= 0)
2300+ str = NULL;
2301+ else if (strength < 20)
2302+ str = C_("Signal strength", "None");
2303+ else if (strength < 40)
2304+ str = C_("Signal strength", "Weak");
2305+ else if (strength < 50)
2306+ str = C_("Signal strength", "Ok");
2307+ else if (strength < 80)
2308+ str = C_("Signal strength", "Good");
2309+ else
2310+ str = C_("Signal strength", "Excellent");
2311+ panel_set_device_widget_details (CE_PAGE (page)->builder, "strength", str);
2312+
2313+ /* set IP entries */
2314+ if (device_is_active)
2315+ panel_set_device_widgets (CE_PAGE (page)->builder, page->device);
2316+ else
2317+ panel_unset_device_widgets (CE_PAGE (page)->builder);
2318+
2319+ if (!device_is_active && CE_PAGE (page)->connection)
2320+ update_last_used (page, CE_PAGE (page)->connection);
2321+ else
2322+ panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", NULL);
2323+
2324+ /* Auto connect check */
2325+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
2326+ "auto_connect_check"));
2327+ sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
2328+ g_object_bind_property (sc, "autoconnect",
2329+ widget, "active",
2330+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
2331+ g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page);
2332+
2333+ /* All users check */
2334+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
2335+ "all_user_check"));
2336+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
2337+ nm_setting_connection_get_num_permissions (sc) == 0);
2338+ g_signal_connect (widget, "toggled",
2339+ G_CALLBACK (all_user_changed), page);
2340+ g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page);
2341+
2342+ /* Forget button */
2343+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_forget"));
2344+ g_signal_connect (widget, "clicked", G_CALLBACK (forget_cb), page);
2345+
2346+ type = nm_setting_connection_get_connection_type (sc);
2347+ if (g_str_equal (type, NM_SETTING_WIRELESS_SETTING_NAME))
2348+ gtk_button_set_label (GTK_BUTTON (widget), _("Forget Connection"));
2349+ else if (g_str_equal (type, NM_SETTING_WIRED_SETTING_NAME))
2350+ gtk_button_set_label (GTK_BUTTON (widget), _("Remove Connection Profile"));
2351+ else if (g_str_equal (type, NM_SETTING_VPN_SETTING_NAME))
2352+ gtk_button_set_label (GTK_BUTTON (widget), _("Remove VPN"));
2353+ else
2354+ gtk_widget_hide (widget);
2355+}
2356+
2357+static void
2358+ce_page_details_init (CEPageDetails *page)
2359+{
2360+}
2361+
2362+static void
2363+ce_page_details_class_init (CEPageDetailsClass *class)
2364+{
2365+}
2366+
2367+CEPage *
2368+ce_page_details_new (NMConnection *connection,
2369+ NMClient *client,
2370+ NMDevice *device,
2371+ NMAccessPoint *ap,
2372+ NetConnectionEditor *editor)
2373+{
2374+ CEPageDetails *page;
2375+
2376+ page = CE_PAGE_DETAILS (ce_page_new (CE_TYPE_PAGE_DETAILS,
2377+ connection,
2378+ client,
2379+ "/org/gnome/control-center/network/details-page.ui",
2380+ _("Details")));
2381+
2382+ page->editor = editor;
2383+ page->device = device;
2384+ page->ap = ap;
2385+
2386+ connect_details_page (page);
2387+
2388+ return CE_PAGE (page);
2389+}
2390
2391=== added file 'panels/network/connection-editor/ce-page-details.h'
2392--- panels/network/connection-editor/ce-page-details.h 1970-01-01 00:00:00 +0000
2393+++ panels/network/connection-editor/ce-page-details.h 2019-05-01 13:56:52 +0000
2394@@ -0,0 +1,68 @@
2395+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2396+ *
2397+ * Copyright (C) 2012 Red Hat, Inc.
2398+ *
2399+ * Licensed under the GNU General Public License Version 2
2400+ *
2401+ * This program is free software; you can redistribute it and/or modify
2402+ * it under the terms of the GNU General Public License as published by
2403+ * the Free Software Foundation; either version 2 of the License, or
2404+ * (at your option) any later version.
2405+ *
2406+ * This program is distributed in the hope that it will be useful,
2407+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2408+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2409+ * GNU General Public License for more details.
2410+ *
2411+ * You should have received a copy of the GNU General Public License
2412+ * along with this program; if not, write to the Free Software
2413+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2414+ */
2415+
2416+#ifndef __CE_PAGE_DETAILS_H
2417+#define __CE_PAGE_DETAILS_H
2418+
2419+#include <glib-object.h>
2420+
2421+#include <gtk/gtk.h>
2422+#include "net-connection-editor.h"
2423+#include "ce-page.h"
2424+
2425+G_BEGIN_DECLS
2426+
2427+#define CE_TYPE_PAGE_DETAILS (ce_page_details_get_type ())
2428+#define CE_PAGE_DETAILS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_DETAILS, CEPageDetails))
2429+#define CE_PAGE_DETAILS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass))
2430+#define CE_IS_PAGE_DETAILS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_DETAILS))
2431+#define CE_IS_PAGE_DETAILS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_DETAILS))
2432+#define CE_PAGE_DETAILS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass))
2433+
2434+typedef struct _CEPageDetails CEPageDetails;
2435+typedef struct _CEPageDetailsClass CEPageDetailsClass;
2436+
2437+struct _CEPageDetails
2438+{
2439+ CEPage parent;
2440+
2441+ NMDevice *device;
2442+ NMAccessPoint *ap;
2443+ NetConnectionEditor *editor;
2444+};
2445+
2446+struct _CEPageDetailsClass
2447+{
2448+ CEPageClass parent_class;
2449+};
2450+
2451+GType ce_page_details_get_type (void);
2452+
2453+CEPage *ce_page_details_new (NMConnection *connection,
2454+ NMClient *client,
2455+ NMDevice *device,
2456+ NMAccessPoint *ap,
2457+ NetConnectionEditor *editor);
2458+
2459+G_END_DECLS
2460+
2461+#endif /* __CE_PAGE_DETAILS_H */
2462+
2463
2464=== added file 'panels/network/connection-editor/ce-page-ethernet.c'
2465--- panels/network/connection-editor/ce-page-ethernet.c 1970-01-01 00:00:00 +0000
2466+++ panels/network/connection-editor/ce-page-ethernet.c 2019-05-01 13:56:52 +0000
2467@@ -0,0 +1,187 @@
2468+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2469+ *
2470+ * Copyright (C) 2012 Red Hat, Inc
2471+ *
2472+ * Licensed under the GNU General Public License Version 2
2473+ *
2474+ * This program is free software; you can redistribute it and/or modify
2475+ * it under the terms of the GNU General Public License as published by
2476+ * the Free Software Foundation; either version 2 of the License, or
2477+ * (at your option) any later version.
2478+ *
2479+ * This program is distributed in the hope that it will be useful,
2480+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2481+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2482+ * GNU General Public License for more details.
2483+ *
2484+ * You should have received a copy of the GNU General Public License
2485+ * along with this program; if not, write to the Free Software
2486+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2487+ */
2488+
2489+#include "config.h"
2490+
2491+#include <glib-object.h>
2492+#include <glib/gi18n.h>
2493+#include <net/if_arp.h>
2494+
2495+#include <NetworkManager.h>
2496+
2497+
2498+#include "ce-page-ethernet.h"
2499+#include "ui-helpers.h"
2500+
2501+G_DEFINE_TYPE (CEPageEthernet, ce_page_ethernet, CE_TYPE_PAGE)
2502+
2503+static void
2504+mtu_changed (GtkSpinButton *mtu, CEPageEthernet *page)
2505+{
2506+ if (gtk_spin_button_get_value_as_int (mtu) == 0)
2507+ gtk_widget_hide (page->mtu_label);
2508+ else
2509+ gtk_widget_show (page->mtu_label);
2510+}
2511+
2512+static void
2513+connect_ethernet_page (CEPageEthernet *page)
2514+{
2515+ NMSettingWired *setting = page->setting_wired;
2516+ int mtu_def;
2517+ char **mac_list;
2518+ const char *s_mac_str;
2519+ const gchar *name;
2520+ const gchar *cloned_mac;
2521+
2522+ name = nm_setting_connection_get_id (page->setting_connection);
2523+ gtk_entry_set_text (page->name, name);
2524+
2525+ /* Device MAC address */
2526+ mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_ETHERNET,
2527+ NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
2528+ s_mac_str = nm_setting_wired_get_mac_address (setting);
2529+ ce_page_setup_mac_combo (page->device_mac, s_mac_str, mac_list);
2530+ g_strfreev (mac_list);
2531+ g_signal_connect_swapped (page->device_mac, "changed", G_CALLBACK (ce_page_changed), page);
2532+
2533+ /* Cloned MAC address */
2534+ cloned_mac = nm_setting_wired_get_cloned_mac_address (setting);
2535+ gtk_entry_set_text (GTK_ENTRY (page->cloned_mac), cloned_mac ? cloned_mac : "");
2536+ g_signal_connect_swapped (page->cloned_mac, "changed", G_CALLBACK (ce_page_changed), page);
2537+
2538+ /* MTU */
2539+ mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRED_MTU);
2540+ g_signal_connect (page->mtu, "output",
2541+ G_CALLBACK (ce_spin_output_with_default),
2542+ GINT_TO_POINTER (mtu_def));
2543+ gtk_spin_button_set_value (page->mtu, (gdouble) nm_setting_wired_get_mtu (setting));
2544+ g_signal_connect (page->mtu, "value-changed",
2545+ G_CALLBACK (mtu_changed), page);
2546+ mtu_changed (page->mtu, page);
2547+
2548+ g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page);
2549+ g_signal_connect_swapped (page->mtu, "value-changed", G_CALLBACK (ce_page_changed), page);
2550+}
2551+
2552+static void
2553+ui_to_setting (CEPageEthernet *page)
2554+{
2555+ gchar *device_mac = NULL;
2556+ gchar *cloned_mac;
2557+ const gchar *text;
2558+ GtkWidget *entry;
2559+
2560+ entry = gtk_bin_get_child (GTK_BIN (page->device_mac));
2561+ if (entry) {
2562+ text = gtk_entry_get_text (GTK_ENTRY (entry));
2563+ device_mac = ce_page_trim_address (text);
2564+ }
2565+ text = gtk_entry_get_text (GTK_ENTRY (entry));
2566+ cloned_mac = ce_page_trim_address (text);
2567+
2568+ g_object_set (page->setting_wired,
2569+ NM_SETTING_WIRED_MAC_ADDRESS, device_mac,
2570+ NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac,
2571+ NM_SETTING_WIRED_MTU, (guint32) gtk_spin_button_get_value_as_int (page->mtu),
2572+ NULL);
2573+
2574+ g_object_set (page->setting_connection,
2575+ NM_SETTING_CONNECTION_ID, gtk_entry_get_text (page->name),
2576+ NULL);
2577+
2578+ g_free (cloned_mac);
2579+ g_free (device_mac);
2580+}
2581+
2582+static gboolean
2583+validate (CEPage *page,
2584+ NMConnection *connection,
2585+ GError **error)
2586+{
2587+ CEPageEthernet *self = CE_PAGE_ETHERNET (page);
2588+ GtkWidget *entry;
2589+ gboolean ret = TRUE;
2590+
2591+ entry = gtk_bin_get_child (GTK_BIN (self->device_mac));
2592+ if (entry) {
2593+ if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) {
2594+ widget_set_error (entry);
2595+ ret = FALSE;
2596+ } else {
2597+ widget_unset_error (entry);
2598+ }
2599+ }
2600+
2601+ if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (self->cloned_mac)))) {
2602+ widget_set_error (GTK_WIDGET (self->cloned_mac));
2603+ ret = FALSE;
2604+ } else {
2605+ widget_unset_error (GTK_WIDGET (self->cloned_mac));
2606+ }
2607+
2608+ if (!ret)
2609+ return ret;
2610+
2611+ ui_to_setting (self);
2612+
2613+ return nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error) &&
2614+ nm_setting_verify (NM_SETTING (self->setting_wired), NULL, error);
2615+}
2616+
2617+static void
2618+ce_page_ethernet_init (CEPageEthernet *page)
2619+{
2620+}
2621+
2622+static void
2623+ce_page_ethernet_class_init (CEPageEthernetClass *class)
2624+{
2625+ CEPageClass *page_class= CE_PAGE_CLASS (class);
2626+
2627+ page_class->validate = validate;
2628+}
2629+
2630+CEPage *
2631+ce_page_ethernet_new (NMConnection *connection,
2632+ NMClient *client)
2633+{
2634+ CEPageEthernet *page;
2635+
2636+ page = CE_PAGE_ETHERNET (ce_page_new (CE_TYPE_PAGE_ETHERNET,
2637+ connection,
2638+ client,
2639+ "/org/gnome/control-center/network/ethernet-page.ui",
2640+ _("Identity")));
2641+
2642+ page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name"));
2643+ page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac"));
2644+ page->cloned_mac = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac"));
2645+ page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu"));
2646+ page->mtu_label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "label_mtu"));
2647+
2648+ page->setting_connection = nm_connection_get_setting_connection (connection);
2649+ page->setting_wired = nm_connection_get_setting_wired (connection);
2650+
2651+ connect_ethernet_page (page);
2652+
2653+ return CE_PAGE (page);
2654+}
2655
2656=== added file 'panels/network/connection-editor/ce-page-ethernet.h'
2657--- panels/network/connection-editor/ce-page-ethernet.h 1970-01-01 00:00:00 +0000
2658+++ panels/network/connection-editor/ce-page-ethernet.h 2019-05-01 13:56:52 +0000
2659@@ -0,0 +1,71 @@
2660+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2661+ *
2662+ * Copyright (C) 2012 Red Hat, Inc.
2663+ *
2664+ * Licensed under the GNU General Public License Version 2
2665+ *
2666+ * This program is free software; you can redistribute it and/or modify
2667+ * it under the terms of the GNU General Public License as published by
2668+ * the Free Software Foundation; either version 2 of the License, or
2669+ * (at your option) any later version.
2670+ *
2671+ * This program is distributed in the hope that it will be useful,
2672+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2673+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2674+ * GNU General Public License for more ethernet.
2675+ *
2676+ * You should have received a copy of the GNU General Public License
2677+ * along with this program; if not, write to the Free Software
2678+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2679+ */
2680+
2681+#ifndef __CE_PAGE_ETHERNET_H
2682+#define __CE_PAGE_ETHERNET_H
2683+
2684+#include <glib-object.h>
2685+
2686+#include <NetworkManager.h>
2687+
2688+#include <gtk/gtk.h>
2689+#include "ce-page.h"
2690+
2691+G_BEGIN_DECLS
2692+
2693+#define CE_TYPE_PAGE_ETHERNET (ce_page_ethernet_get_type ())
2694+#define CE_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernet))
2695+#define CE_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass))
2696+#define CE_IS_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_ETHERNET))
2697+#define CE_IS_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_ETHERNET))
2698+#define CE_PAGE_ETHERNET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass))
2699+
2700+typedef struct _CEPageEthernet CEPageEthernet;
2701+typedef struct _CEPageEthernetClass CEPageEthernetClass;
2702+
2703+struct _CEPageEthernet
2704+{
2705+ CEPage parent;
2706+
2707+ NMSettingConnection *setting_connection;
2708+ NMSettingWired *setting_wired;
2709+
2710+ GtkEntry *name;
2711+ GtkComboBoxText *device_mac;
2712+ GtkEntry *cloned_mac;
2713+ GtkSpinButton *mtu;
2714+ GtkWidget *mtu_label;
2715+};
2716+
2717+struct _CEPageEthernetClass
2718+{
2719+ CEPageClass parent_class;
2720+};
2721+
2722+GType ce_page_ethernet_get_type (void);
2723+
2724+CEPage *ce_page_ethernet_new (NMConnection *connection,
2725+ NMClient *client);
2726+
2727+G_END_DECLS
2728+
2729+#endif /* __CE_PAGE_ETHERNET_H */
2730+
2731
2732=== added file 'panels/network/connection-editor/ce-page-ip4.c'
2733--- panels/network/connection-editor/ce-page-ip4.c 1970-01-01 00:00:00 +0000
2734+++ panels/network/connection-editor/ce-page-ip4.c 2019-05-01 13:56:52 +0000
2735@@ -0,0 +1,907 @@
2736+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2737+ *
2738+ * Copyright (C) 2012 Red Hat, Inc
2739+ *
2740+ * Licensed under the GNU General Public License Version 2
2741+ *
2742+ * This program is free software; you can redistribute it and/or modify
2743+ * it under the terms of the GNU General Public License as published by
2744+ * the Free Software Foundation; either version 2 of the License, or
2745+ * (at your option) any later version.
2746+ *
2747+ * This program is distributed in the hope that it will be useful,
2748+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2749+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2750+ * GNU General Public License for more details.
2751+ *
2752+ * You should have received a copy of the GNU General Public License
2753+ * along with this program; if not, write to the Free Software
2754+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2755+ */
2756+
2757+#include "config.h"
2758+
2759+#include <errno.h>
2760+#include <stdlib.h>
2761+#include <arpa/inet.h>
2762+#include <glib-object.h>
2763+#include <glib/gi18n.h>
2764+#include <NetworkManager.h>
2765+
2766+#include "shell/list-box-helper.h"
2767+#include "ce-page-ip4.h"
2768+#include "ui-helpers.h"
2769+
2770+#define RADIO_IS_ACTIVE(x) (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(CE_PAGE (page)->builder, x))))
2771+
2772+static void ensure_empty_address_row (CEPageIP4 *page);
2773+static void ensure_empty_routes_row (CEPageIP4 *page);
2774+
2775+G_DEFINE_TYPE (CEPageIP4, ce_page_ip4, CE_TYPE_PAGE)
2776+
2777+enum {
2778+ METHOD_COL_NAME,
2779+ METHOD_COL_METHOD
2780+};
2781+
2782+enum {
2783+ IP4_METHOD_AUTO,
2784+ IP4_METHOD_MANUAL,
2785+ IP4_METHOD_LINK_LOCAL,
2786+ IP4_METHOD_SHARED,
2787+ IP4_METHOD_DISABLED
2788+};
2789+
2790+static void
2791+method_changed (GtkToggleButton *radio, CEPageIP4 *page)
2792+{
2793+ gboolean addr_enabled;
2794+ gboolean dns_enabled;
2795+ gboolean routes_enabled;
2796+ GtkWidget *widget;
2797+
2798+ if (RADIO_IS_ACTIVE ("radio_disabled")) {
2799+ addr_enabled = FALSE;
2800+ dns_enabled = FALSE;
2801+ routes_enabled = FALSE;
2802+ } else {
2803+ addr_enabled = RADIO_IS_ACTIVE ("radio_manual");
2804+ dns_enabled = !RADIO_IS_ACTIVE ("radio_local");
2805+ routes_enabled = !RADIO_IS_ACTIVE ("radio_local");
2806+ }
2807+
2808+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
2809+ gtk_widget_set_visible (widget, addr_enabled);
2810+ gtk_widget_set_sensitive (page->dns_entry, dns_enabled);
2811+ gtk_widget_set_sensitive (page->routes_list, routes_enabled);
2812+ gtk_widget_set_sensitive (page->never_default, routes_enabled);
2813+
2814+ ce_page_changed (CE_PAGE (page));
2815+}
2816+
2817+static void
2818+switch_toggled (GObject *object,
2819+ GParamSpec *pspec,
2820+ CEPage *page)
2821+{
2822+ ce_page_changed (page);
2823+}
2824+
2825+static void
2826+update_row_sensitivity (CEPageIP4 *page, GtkWidget *list)
2827+{
2828+ GList *children, *l;
2829+ gint rows = 0, i = 0;
2830+
2831+ children = gtk_container_get_children (GTK_CONTAINER (list));
2832+ for (l = children; l; l = l->next) {
2833+ GtkWidget *row = l->data;
2834+ GtkWidget *button;
2835+
2836+ button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
2837+ if (button != NULL)
2838+ rows++;
2839+ }
2840+ for (l = children; l; l = l->next) {
2841+ GtkWidget *row = l->data;
2842+ GtkWidget *button;
2843+
2844+ button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
2845+ if (button != NULL)
2846+ gtk_widget_set_sensitive (button, rows > 1 && ++i < rows);
2847+ }
2848+ g_list_free (children);
2849+}
2850+
2851+static void
2852+update_row_gateway_sensitivity (CEPageIP4 *page)
2853+{
2854+ GList *children, *l;
2855+ gint rows = 0;
2856+
2857+ children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
2858+ for (l = children; l; l = l->next) {
2859+ GtkWidget *row = l->data;
2860+ GtkWidget *entry;
2861+
2862+ entry = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway"));
2863+
2864+ gtk_widget_set_sensitive (entry, (rows == 0));
2865+
2866+ rows++;
2867+ }
2868+ g_list_free (children);
2869+}
2870+
2871+static void
2872+remove_row (GtkButton *button, CEPageIP4 *page)
2873+{
2874+ GtkWidget *list;
2875+ GtkWidget *row;
2876+ GtkWidget *row_box;
2877+
2878+ row_box = gtk_widget_get_parent (GTK_WIDGET (button));
2879+ row = gtk_widget_get_parent (row_box);
2880+ list = gtk_widget_get_parent (row);
2881+
2882+ gtk_container_remove (GTK_CONTAINER (list), row);
2883+
2884+ ce_page_changed (CE_PAGE (page));
2885+
2886+ update_row_sensitivity (page, list);
2887+ if (list == page->address_list)
2888+ update_row_gateway_sensitivity (page);
2889+}
2890+
2891+static gboolean
2892+validate_row (GtkWidget *row)
2893+{
2894+ GtkWidget *box;
2895+ GList *children, *l;
2896+ gboolean valid;
2897+
2898+ valid = FALSE;
2899+ box = gtk_bin_get_child (GTK_BIN (row));
2900+ children = gtk_container_get_children (GTK_CONTAINER (box));
2901+
2902+ for (l = children; l != NULL; l = l->next) {
2903+ if (!GTK_IS_ENTRY (l->data))
2904+ continue;
2905+
2906+ valid = valid || gtk_entry_get_text_length (l->data) > 0;
2907+ }
2908+
2909+ g_list_free (children);
2910+
2911+ return valid;
2912+}
2913+
2914+static gint
2915+sort_first_last (gconstpointer a, gconstpointer b, gpointer data)
2916+{
2917+ gboolean afirst, bfirst, alast, blast;
2918+
2919+ afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first"));
2920+ bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first"));
2921+ alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last"));
2922+ blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last"));
2923+
2924+ if (afirst)
2925+ return -1;
2926+ if (bfirst)
2927+ return 1;
2928+ if (alast)
2929+ return 1;
2930+ if (blast)
2931+ return -1;
2932+
2933+ return 0;
2934+}
2935+
2936+static void
2937+add_address_row (CEPageIP4 *page,
2938+ const gchar *address,
2939+ const gchar *network,
2940+ const gchar *gateway)
2941+{
2942+ GtkSizeGroup *group;
2943+ GtkWidget *row;
2944+ GtkWidget *row_box;
2945+ GtkWidget *widget;
2946+ GtkWidget *delete_button;
2947+ GtkWidget *image;
2948+
2949+ row = gtk_list_box_row_new ();
2950+
2951+ row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2952+ gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked");
2953+
2954+ widget = gtk_entry_new ();
2955+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
2956+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page);
2957+ g_object_set_data (G_OBJECT (row), "address", widget);
2958+ gtk_entry_set_text (GTK_ENTRY (widget), address);
2959+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
2960+ gtk_widget_set_hexpand (widget, TRUE);
2961+ gtk_container_add (GTK_CONTAINER (row_box), widget);
2962+
2963+ widget = gtk_entry_new ();
2964+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
2965+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page);
2966+ g_object_set_data (G_OBJECT (row), "network", widget);
2967+ gtk_entry_set_text (GTK_ENTRY (widget), network);
2968+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
2969+ gtk_widget_set_hexpand (widget, TRUE);
2970+ gtk_container_add (GTK_CONTAINER (row_box), widget);
2971+
2972+ widget = gtk_entry_new ();
2973+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
2974+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page);
2975+ g_object_set_data (G_OBJECT (row), "gateway", widget);
2976+ gtk_entry_set_text (GTK_ENTRY (widget), gateway ? gateway : "");
2977+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
2978+ gtk_widget_set_hexpand (widget, TRUE);
2979+ gtk_container_add (GTK_CONTAINER (row_box), widget);
2980+
2981+ delete_button = gtk_button_new ();
2982+ gtk_widget_set_sensitive (delete_button, FALSE);
2983+ gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button");
2984+ g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
2985+ image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU);
2986+ atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Address"));
2987+ gtk_button_set_image (GTK_BUTTON (delete_button), image);
2988+ gtk_container_add (GTK_CONTAINER (row_box), delete_button);
2989+ g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
2990+
2991+ group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "address_sizegroup"));
2992+ gtk_size_group_add_widget (group, delete_button);
2993+
2994+ gtk_container_add (GTK_CONTAINER (row), row_box);
2995+ gtk_widget_show_all (row);
2996+ gtk_container_add (GTK_CONTAINER (page->address_list), row);
2997+
2998+ update_row_gateway_sensitivity (page);
2999+ update_row_sensitivity (page, page->address_list);
3000+}
3001+
3002+static void
3003+ensure_empty_address_row (CEPageIP4 *page)
3004+{
3005+ GList *children, *l;
3006+
3007+ children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
3008+ l = children;
3009+
3010+ while (l && l->next)
3011+ l = l->next;
3012+
3013+ /* Add the last, stub row if needed*/
3014+ if (!l || validate_row (l->data))
3015+ add_address_row (page, "", "", "");
3016+
3017+ g_list_free (children);
3018+}
3019+
3020+static void
3021+add_address_section (CEPageIP4 *page)
3022+{
3023+ GtkWidget *widget;
3024+ GtkWidget *list;
3025+ gint i;
3026+
3027+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
3028+
3029+ page->address_list = list = gtk_list_box_new ();
3030+ gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
3031+ gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL);
3032+ gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL);
3033+ gtk_container_add (GTK_CONTAINER (widget), list);
3034+
3035+ for (i = 0; i < nm_setting_ip_config_get_num_addresses (page->setting); i++) {
3036+ NMIPAddress *addr;
3037+ struct in_addr tmp_addr;
3038+ gchar network[INET_ADDRSTRLEN + 1];
3039+
3040+ addr = nm_setting_ip_config_get_address (page->setting, i);
3041+ if (!addr)
3042+ continue;
3043+
3044+ tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip_address_get_prefix (addr));
3045+ (void) inet_ntop (AF_INET, &tmp_addr, &network[0], sizeof (network));
3046+
3047+ add_address_row (page,
3048+ nm_ip_address_get_address (addr),
3049+ network,
3050+ i == 0 ? nm_setting_ip_config_get_gateway (page->setting) : "");
3051+ }
3052+ if (nm_setting_ip_config_get_num_addresses (page->setting) == 0)
3053+ ensure_empty_address_row (page);
3054+
3055+ gtk_widget_show_all (widget);
3056+}
3057+
3058+static void
3059+add_dns_section (CEPageIP4 *page)
3060+{
3061+ GtkEntry *entry;
3062+ GString *string;
3063+ gint i;
3064+
3065+ page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch"));
3066+ gtk_switch_set_active (page->auto_dns, !nm_setting_ip_config_get_ignore_auto_dns (page->setting));
3067+ g_signal_connect (page->auto_dns, "notify::active", G_CALLBACK (switch_toggled), page);
3068+
3069+ page->dns_entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_entry"));
3070+ entry = GTK_ENTRY (page->dns_entry);
3071+ string = g_string_new ("");
3072+
3073+ for (i = 0; i < nm_setting_ip_config_get_num_dns (page->setting); i++) {
3074+ const char *address;
3075+
3076+ address = nm_setting_ip_config_get_dns (page->setting, i);
3077+
3078+ if (i > 0)
3079+ g_string_append (string, ", ");
3080+
3081+ g_string_append (string, address);
3082+ }
3083+
3084+ gtk_entry_set_text (entry, string->str);
3085+
3086+ g_signal_connect_swapped (entry, "notify::text", G_CALLBACK (ce_page_changed), page);
3087+
3088+ g_string_free (string, TRUE);
3089+}
3090+
3091+static void
3092+add_route_row (CEPageIP4 *page,
3093+ const gchar *address,
3094+ const gchar *netmask,
3095+ const gchar *gateway,
3096+ gint metric)
3097+{
3098+ GtkSizeGroup *group;
3099+ GtkWidget *row;
3100+ GtkWidget *row_box;
3101+ GtkWidget *widget;
3102+ GtkWidget *delete_button;
3103+ GtkWidget *image;
3104+
3105+ row = gtk_list_box_row_new ();
3106+
3107+ row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
3108+ gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked");
3109+
3110+ widget = gtk_entry_new ();
3111+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
3112+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
3113+ g_object_set_data (G_OBJECT (row), "address", widget);
3114+ gtk_entry_set_text (GTK_ENTRY (widget), address);
3115+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
3116+ gtk_widget_set_hexpand (widget, TRUE);
3117+ gtk_container_add (GTK_CONTAINER (row_box), widget);
3118+
3119+ widget = gtk_entry_new ();
3120+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
3121+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
3122+ g_object_set_data (G_OBJECT (row), "netmask", widget);
3123+ gtk_entry_set_text (GTK_ENTRY (widget), netmask);
3124+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
3125+ gtk_widget_set_hexpand (widget, TRUE);
3126+ gtk_container_add (GTK_CONTAINER (row_box), widget);
3127+
3128+ widget = gtk_entry_new ();
3129+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
3130+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
3131+ g_object_set_data (G_OBJECT (row), "gateway", widget);
3132+ gtk_entry_set_text (GTK_ENTRY (widget), gateway);
3133+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
3134+ gtk_widget_set_hexpand (widget, TRUE);
3135+ gtk_container_add (GTK_CONTAINER (row_box), widget);
3136+
3137+ widget = gtk_entry_new ();
3138+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
3139+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
3140+ g_object_set_data (G_OBJECT (row), "metric", widget);
3141+ if (metric >= 0) {
3142+ gchar *s = g_strdup_printf ("%d", metric);
3143+ gtk_entry_set_text (GTK_ENTRY (widget), s);
3144+ g_free (s);
3145+ }
3146+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 5);
3147+ gtk_widget_set_hexpand (widget, TRUE);
3148+ gtk_container_add (GTK_CONTAINER (row_box), widget);
3149+
3150+ group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_metric_sizegroup"));
3151+ gtk_size_group_add_widget (group, widget);
3152+
3153+ delete_button = gtk_button_new ();
3154+ gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button");
3155+ g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
3156+ image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU);
3157+ atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route"));
3158+ gtk_button_set_image (GTK_BUTTON (delete_button), image);
3159+ gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER);
3160+ gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER);
3161+ gtk_container_add (GTK_CONTAINER (row_box), delete_button);
3162+ g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
3163+
3164+ group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_sizegroup"));
3165+ gtk_size_group_add_widget (group, delete_button);
3166+
3167+ gtk_container_add (GTK_CONTAINER (row), row_box);
3168+ gtk_widget_show_all (row);
3169+ gtk_container_add (GTK_CONTAINER (page->routes_list), row);
3170+
3171+ update_row_sensitivity (page, page->routes_list);
3172+}
3173+
3174+static void
3175+ensure_empty_routes_row (CEPageIP4 *page)
3176+{
3177+ GList *children, *l;
3178+
3179+ children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
3180+ l = children;
3181+
3182+ while (l && l->next)
3183+ l = l->next;
3184+
3185+ /* Add the last, stub row if needed*/
3186+ if (!l || validate_row (l->data))
3187+ add_route_row (page, "", "", "", -1);
3188+
3189+ g_list_free (children);
3190+}
3191+
3192+static void
3193+add_routes_section (CEPageIP4 *page)
3194+{
3195+ GtkWidget *widget;
3196+ GtkWidget *list;
3197+ gint i;
3198+
3199+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
3200+
3201+ page->routes_list = list = gtk_list_box_new ();
3202+ gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
3203+ gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL);
3204+ gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL);
3205+ gtk_container_add (GTK_CONTAINER (widget), list);
3206+ page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
3207+ gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting));
3208+ g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page);
3209+
3210+
3211+ for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) {
3212+ NMIPRoute *route;
3213+ struct in_addr tmp_addr;
3214+ gchar netmask[INET_ADDRSTRLEN + 1];
3215+
3216+ route = nm_setting_ip_config_get_route (page->setting, i);
3217+ if (!route)
3218+ continue;
3219+
3220+ tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip_route_get_prefix (route));
3221+ (void) inet_ntop (AF_INET, &tmp_addr, &netmask[0], sizeof (netmask));
3222+
3223+ add_route_row (page,
3224+ nm_ip_route_get_dest (route),
3225+ netmask,
3226+ nm_ip_route_get_next_hop (route),
3227+ nm_ip_route_get_metric (route));
3228+ }
3229+ if (nm_setting_ip_config_get_num_routes (page->setting) == 0)
3230+ ensure_empty_routes_row (page);
3231+
3232+ gtk_widget_show_all (widget);
3233+}
3234+
3235+enum
3236+{
3237+ RADIO_AUTOMATIC,
3238+ RADIO_LOCAL,
3239+ RADIO_MANUAL,
3240+ RADIO_DISABLED,
3241+ N_RADIO
3242+};
3243+
3244+static void
3245+connect_ip4_page (CEPageIP4 *page)
3246+{
3247+ GtkToggleButton *radios[N_RADIO];
3248+ GtkWidget *content;
3249+ const gchar *str_method;
3250+ gboolean disabled;
3251+ guint method, i;
3252+
3253+ add_address_section (page);
3254+ add_dns_section (page);
3255+ add_routes_section (page);
3256+
3257+ page->disabled = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_disabled"));
3258+
3259+ str_method = nm_setting_ip_config_get_method (page->setting);
3260+ disabled = g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0;
3261+ gtk_toggle_button_set_active (page->disabled, disabled);
3262+ g_signal_connect_swapped (page->disabled, "notify::active", G_CALLBACK (ce_page_changed), page);
3263+ content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content"));
3264+ g_object_bind_property (page->disabled, "active",
3265+ content, "sensitive",
3266+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
3267+
3268+ method = IP4_METHOD_AUTO;
3269+ if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) {
3270+ method = IP4_METHOD_LINK_LOCAL;
3271+ } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) {
3272+ method = IP4_METHOD_MANUAL;
3273+ } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) {
3274+ method = IP4_METHOD_SHARED;
3275+ } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) {
3276+ method = IP4_METHOD_DISABLED;
3277+ }
3278+
3279+ page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check"));
3280+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default),
3281+ nm_setting_ip_config_get_never_default (page->setting));
3282+ g_signal_connect_swapped (page->never_default, "toggled", G_CALLBACK (ce_page_changed), page);
3283+
3284+ /* Connect radio buttons */
3285+ radios[RADIO_AUTOMATIC] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_automatic"));
3286+ radios[RADIO_LOCAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_local"));
3287+ radios[RADIO_MANUAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_manual"));
3288+ radios[RADIO_DISABLED] = page->disabled;
3289+
3290+ for (i = RADIO_AUTOMATIC; i < RADIO_DISABLED; i++)
3291+ g_signal_connect (radios[i], "toggled", G_CALLBACK (method_changed), page);
3292+
3293+ switch (method) {
3294+ case IP4_METHOD_AUTO:
3295+ gtk_toggle_button_set_active (radios[RADIO_AUTOMATIC], TRUE);
3296+ break;
3297+ case IP4_METHOD_LINK_LOCAL:
3298+ gtk_toggle_button_set_active (radios[RADIO_LOCAL], TRUE);
3299+ break;
3300+ case IP4_METHOD_MANUAL:
3301+ gtk_toggle_button_set_active (radios[RADIO_MANUAL], TRUE);
3302+ break;
3303+ case IP4_METHOD_DISABLED:
3304+ gtk_toggle_button_set_active (radios[RADIO_DISABLED], TRUE);
3305+ break;
3306+ default:
3307+ break;
3308+ }
3309+
3310+ method_changed (NULL, page);
3311+}
3312+
3313+static gboolean
3314+parse_netmask (const char *str, guint32 *prefix)
3315+{
3316+ struct in_addr tmp_addr;
3317+ glong tmp_prefix;
3318+
3319+ errno = 0;
3320+
3321+ /* Is it a prefix? */
3322+ if (!strchr (str, '.')) {
3323+ tmp_prefix = strtol (str, NULL, 10);
3324+ if (!errno && tmp_prefix >= 0 && tmp_prefix <= 32) {
3325+ *prefix = tmp_prefix;
3326+ return TRUE;
3327+ }
3328+ }
3329+
3330+ /* Is it a netmask? */
3331+ if (inet_pton (AF_INET, str, &tmp_addr) > 0) {
3332+ *prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr);
3333+ return TRUE;
3334+ }
3335+
3336+ return FALSE;
3337+}
3338+
3339+static gboolean
3340+ui_to_setting (CEPageIP4 *page)
3341+{
3342+ const gchar *method;
3343+ gboolean ignore_auto_dns;
3344+ gboolean ignore_auto_routes;
3345+ gboolean never_default;
3346+ GPtrArray *addresses = NULL;
3347+ GPtrArray *dns_servers = NULL;
3348+ GPtrArray *routes = NULL;
3349+ GStrv dns_addresses = NULL;
3350+ GList *children, *l;
3351+ gboolean ret = TRUE;
3352+ const char *default_gateway = NULL;
3353+ gchar *dns_text = NULL;
3354+ guint i;
3355+
3356+ if (gtk_toggle_button_get_active (page->disabled)) {
3357+ method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
3358+ } else {
3359+ if (RADIO_IS_ACTIVE ("radio_automatic"))
3360+ method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
3361+ else if (RADIO_IS_ACTIVE ("radio_local"))
3362+ method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL;
3363+ else if (RADIO_IS_ACTIVE ("radio_manual"))
3364+ method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
3365+ }
3366+
3367+ addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
3368+ if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL))
3369+ children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
3370+ else
3371+ children = NULL;
3372+
3373+ for (l = children; l; l = l->next) {
3374+ GtkWidget *row = l->data;
3375+ GtkEntry *entry;
3376+ GtkEntry *gateway_entry;
3377+ const gchar *text_address;
3378+ const gchar *text_netmask;
3379+ const gchar *text_gateway = "";
3380+ NMIPAddress *addr;
3381+ guint32 prefix;
3382+
3383+ entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
3384+ if (!entry)
3385+ continue;
3386+
3387+ text_address = gtk_entry_get_text (entry);
3388+ text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "network")));
3389+ gateway_entry = g_object_get_data (G_OBJECT (row), "gateway");
3390+ if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry)))
3391+ text_gateway = gtk_entry_get_text (gateway_entry);
3392+
3393+ if (!*text_address && !*text_netmask && !*text_gateway) {
3394+ /* ignore empty rows */
3395+ widget_unset_error (GTK_WIDGET (entry));
3396+ widget_unset_error (g_object_get_data (G_OBJECT (row), "network"));
3397+ widget_unset_error (GTK_WIDGET (gateway_entry));
3398+ continue;
3399+ }
3400+
3401+ if (!nm_utils_ipaddr_valid (AF_INET, text_address)) {
3402+ widget_set_error (GTK_WIDGET (entry));
3403+ ret = FALSE;
3404+ } else {
3405+ widget_unset_error (GTK_WIDGET (entry));
3406+ }
3407+
3408+ if (!parse_netmask (text_netmask, &prefix)) {
3409+ widget_set_error (g_object_get_data (G_OBJECT (row), "network"));
3410+ ret = FALSE;
3411+ } else {
3412+ widget_unset_error (g_object_get_data (G_OBJECT (row), "network"));
3413+ }
3414+
3415+ if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry)) &&
3416+ *text_gateway &&
3417+ !nm_utils_ipaddr_valid (AF_INET, text_gateway)) {
3418+ widget_set_error (g_object_get_data (G_OBJECT (row), "gateway"));
3419+ ret = FALSE;
3420+ } else {
3421+ widget_unset_error (GTK_WIDGET (gateway_entry));
3422+ if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry)) && *text_gateway) {
3423+ g_assert (default_gateway == NULL);
3424+ default_gateway = text_gateway;
3425+ }
3426+ }
3427+
3428+ if (!ret)
3429+ continue;
3430+
3431+ addr = nm_ip_address_new (AF_INET, text_address, prefix, NULL);
3432+ if (addr)
3433+ g_ptr_array_add (addresses, addr);
3434+
3435+ if (!l || !l->next)
3436+ ensure_empty_address_row (page);
3437+ }
3438+ g_list_free (children);
3439+
3440+ if (addresses->len == 0) {
3441+ g_ptr_array_free (addresses, TRUE);
3442+ addresses = NULL;
3443+ }
3444+
3445+ dns_servers = g_ptr_array_new_with_free_func (g_free);
3446+ dns_text = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (page->dns_entry))));
3447+ if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) ||
3448+ g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL))
3449+ dns_addresses = g_strsplit_set (dns_text, ", ", -1);
3450+ else
3451+ dns_addresses = NULL;
3452+
3453+ for (i = 0; dns_addresses && dns_addresses[i]; i++) {
3454+ const gchar *text;
3455+
3456+ text = dns_addresses[i];
3457+
3458+ if (!text || !*text)
3459+ continue;
3460+
3461+ if (!nm_utils_ipaddr_valid (AF_INET, text)) {
3462+ g_ptr_array_remove_range (dns_servers, 0, dns_servers->len);
3463+ widget_set_error (page->dns_entry);
3464+ ret = FALSE;
3465+ break;
3466+ } else {
3467+ widget_unset_error (page->dns_entry);
3468+ g_ptr_array_add (dns_servers, g_strdup (text));
3469+ }
3470+ }
3471+ g_clear_pointer (&dns_addresses, g_strfreev);
3472+
3473+ if (dns_servers->len == 0) {
3474+ g_ptr_array_free (dns_servers, TRUE);
3475+ dns_servers = NULL;
3476+ } else {
3477+ g_ptr_array_add (dns_servers, NULL);
3478+ }
3479+
3480+ routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref);
3481+ if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) ||
3482+ g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL))
3483+ children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
3484+ else
3485+ children = NULL;
3486+
3487+ for (l = children; l; l = l->next) {
3488+ GtkWidget *row = l->data;
3489+ GtkEntry *entry;
3490+ const gchar *text_address;
3491+ const gchar *text_netmask;
3492+ const gchar *text_gateway;
3493+ const gchar *text_metric;
3494+ gint64 metric;
3495+ guint32 netmask;
3496+ NMIPRoute *route;
3497+
3498+ entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
3499+ if (!entry)
3500+ continue;
3501+
3502+ text_address = gtk_entry_get_text (entry);
3503+ text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "netmask")));
3504+ text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
3505+ text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric")));
3506+
3507+ if (!*text_address && !*text_netmask && !*text_gateway && !*text_metric) {
3508+ /* ignore empty rows */
3509+ continue;
3510+ }
3511+
3512+ if (text_address && !nm_utils_ipaddr_valid (AF_INET, text_address)) {
3513+ widget_set_error (GTK_WIDGET (entry));
3514+ ret = FALSE;
3515+ } else {
3516+ widget_unset_error (GTK_WIDGET (entry));
3517+ }
3518+
3519+ if (!parse_netmask (text_netmask, &netmask)) {
3520+ widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask")));
3521+ ret = FALSE;
3522+ } else {
3523+ widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask")));
3524+ }
3525+
3526+ if (text_gateway && !nm_utils_ipaddr_valid (AF_INET, text_gateway)) {
3527+ widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway")));
3528+ ret = FALSE;
3529+ } else {
3530+ widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway")));
3531+ }
3532+
3533+ metric = -1;
3534+ if (*text_metric) {
3535+ errno = 0;
3536+ metric = g_ascii_strtoull (text_metric, NULL, 10);
3537+ if (errno || metric < 0 || metric > G_MAXUINT32) {
3538+ widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric")));
3539+ ret = FALSE;
3540+ } else {
3541+ widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric")));
3542+ }
3543+ } else {
3544+ widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric")));
3545+ }
3546+
3547+ if (!ret)
3548+ continue;
3549+
3550+ route = nm_ip_route_new (AF_INET, text_address, netmask, text_gateway, metric, NULL);
3551+ if (route)
3552+ g_ptr_array_add (routes, route);
3553+
3554+ if (!l || !l->next)
3555+ ensure_empty_routes_row (page);
3556+ }
3557+ g_list_free (children);
3558+
3559+ if (routes->len == 0) {
3560+ g_ptr_array_free (routes, TRUE);
3561+ routes = NULL;
3562+ }
3563+
3564+ if (!ret)
3565+ goto out;
3566+
3567+ ignore_auto_dns = !gtk_switch_get_active (page->auto_dns);
3568+ ignore_auto_routes = !gtk_switch_get_active (page->auto_routes);
3569+ never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default));
3570+
3571+ g_object_set (page->setting,
3572+ NM_SETTING_IP_CONFIG_METHOD, method,
3573+ NM_SETTING_IP_CONFIG_ADDRESSES, addresses,
3574+ NM_SETTING_IP_CONFIG_GATEWAY, default_gateway,
3575+ NM_SETTING_IP_CONFIG_DNS, dns_servers ? dns_servers->pdata : NULL,
3576+ NM_SETTING_IP_CONFIG_ROUTES, routes,
3577+ NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
3578+ NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
3579+ NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default,
3580+ NULL);
3581+
3582+out:
3583+ if (addresses)
3584+ g_ptr_array_free (addresses, TRUE);
3585+
3586+ if (dns_servers)
3587+ g_ptr_array_free (dns_servers, TRUE);
3588+
3589+ if (routes)
3590+ g_ptr_array_free (routes, TRUE);
3591+
3592+ g_clear_pointer (&dns_text, g_free);
3593+
3594+ return ret;
3595+}
3596+
3597+static gboolean
3598+validate (CEPage *page,
3599+ NMConnection *connection,
3600+ GError **error)
3601+{
3602+ if (!ui_to_setting (CE_PAGE_IP4 (page)))
3603+ return FALSE;
3604+
3605+ return nm_setting_verify (NM_SETTING (CE_PAGE_IP4 (page)->setting), NULL, error);
3606+}
3607+
3608+static void
3609+ce_page_ip4_init (CEPageIP4 *page)
3610+{
3611+}
3612+
3613+static void
3614+ce_page_ip4_class_init (CEPageIP4Class *class)
3615+{
3616+ CEPageClass *page_class= CE_PAGE_CLASS (class);
3617+
3618+ page_class->validate = validate;
3619+}
3620+
3621+CEPage *
3622+ce_page_ip4_new (NMConnection *connection,
3623+ NMClient *client)
3624+{
3625+ CEPageIP4 *page;
3626+
3627+ page = CE_PAGE_IP4 (ce_page_new (CE_TYPE_PAGE_IP4,
3628+ connection,
3629+ client,
3630+ "/org/gnome/control-center/network/ip4-page.ui",
3631+ _("IPv4")));
3632+
3633+ page->setting = nm_connection_get_setting_ip4_config (connection);
3634+ if (!page->setting) {
3635+ page->setting = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ());
3636+ nm_connection_add_setting (connection, NM_SETTING (page->setting));
3637+ }
3638+
3639+ connect_ip4_page (page);
3640+
3641+ return CE_PAGE (page);
3642+}
3643
3644=== added file 'panels/network/connection-editor/ce-page-ip4.h'
3645--- panels/network/connection-editor/ce-page-ip4.h 1970-01-01 00:00:00 +0000
3646+++ panels/network/connection-editor/ce-page-ip4.h 2019-05-01 13:56:52 +0000
3647@@ -0,0 +1,70 @@
3648+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3649+ *
3650+ * Copyright (C) 2012 Red Hat, Inc.
3651+ *
3652+ * Licensed under the GNU General Public License Version 2
3653+ *
3654+ * This program is free software; you can redistribute it and/or modify
3655+ * it under the terms of the GNU General Public License as published by
3656+ * the Free Software Foundation; either version 2 of the License, or
3657+ * (at your option) any later version.
3658+ *
3659+ * This program is distributed in the hope that it will be useful,
3660+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3661+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3662+ * GNU General Public License for more ip4.
3663+ *
3664+ * You should have received a copy of the GNU General Public License
3665+ * along with this program; if not, write to the Free Software
3666+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3667+ */
3668+
3669+#ifndef __CE_PAGE_IP4_H
3670+#define __CE_PAGE_IP4_H
3671+
3672+#include <glib-object.h>
3673+
3674+#include <gtk/gtk.h>
3675+#include "ce-page.h"
3676+
3677+G_BEGIN_DECLS
3678+
3679+#define CE_TYPE_PAGE_IP4 (ce_page_ip4_get_type ())
3680+#define CE_PAGE_IP4(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP4, CEPageIP4))
3681+#define CE_PAGE_IP4_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP4, CEPageIP4Class))
3682+#define CE_IS_PAGE_IP4(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP4))
3683+#define CE_IS_PAGE_IP4_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP4))
3684+#define CE_PAGE_IP4_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP4, CEPageIP4Class))
3685+
3686+typedef struct _CEPageIP4 CEPageIP4;
3687+typedef struct _CEPageIP4Class CEPageIP4Class;
3688+
3689+struct _CEPageIP4
3690+{
3691+ CEPage parent;
3692+
3693+ NMSettingIPConfig *setting;
3694+
3695+ GtkToggleButton *disabled;
3696+ GtkWidget *address_list;
3697+ GtkSwitch *auto_dns;
3698+ GtkWidget *dns_entry;
3699+ GtkSwitch *auto_routes;
3700+ GtkWidget *routes_list;
3701+ GtkWidget *never_default;
3702+};
3703+
3704+struct _CEPageIP4Class
3705+{
3706+ CEPageClass parent_class;
3707+};
3708+
3709+GType ce_page_ip4_get_type (void);
3710+
3711+CEPage *ce_page_ip4_new (NMConnection *connection,
3712+ NMClient *client);
3713+
3714+G_END_DECLS
3715+
3716+#endif /* __CE_PAGE_IP4_H */
3717+
3718
3719=== added file 'panels/network/connection-editor/ce-page-ip6.c'
3720--- panels/network/connection-editor/ce-page-ip6.c 1970-01-01 00:00:00 +0000
3721+++ panels/network/connection-editor/ce-page-ip6.c 2019-05-01 13:56:52 +0000
3722@@ -0,0 +1,838 @@
3723+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3724+ *
3725+ * Copyright (C) 2012 Red Hat, Inc
3726+ *
3727+ * Licensed under the GNU General Public License Version 2
3728+ *
3729+ * This program is free software; you can redistribute it and/or modify
3730+ * it under the terms of the GNU General Public License as published by
3731+ * the Free Software Foundation; either version 2 of the License, or
3732+ * (at your option) any later version.
3733+ *
3734+ * This program is distributed in the hope that it will be useful,
3735+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3736+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3737+ * GNU General Public License for more details.
3738+ *
3739+ * You should have received a copy of the GNU General Public License
3740+ * along with this program; if not, write to the Free Software
3741+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3742+ */
3743+
3744+#include "config.h"
3745+
3746+#include <errno.h>
3747+#include <stdlib.h>
3748+#include <arpa/inet.h>
3749+#include <glib-object.h>
3750+#include <glib/gi18n.h>
3751+#include <NetworkManager.h>
3752+
3753+#include "shell/list-box-helper.h"
3754+#include "ce-page-ip6.h"
3755+#include "ui-helpers.h"
3756+
3757+#define RADIO_IS_ACTIVE(x) (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(CE_PAGE (page)->builder, x))))
3758+
3759+static void ensure_empty_address_row (CEPageIP6 *page);
3760+static void ensure_empty_routes_row (CEPageIP6 *page);
3761+
3762+G_DEFINE_TYPE (CEPageIP6, ce_page_ip6, CE_TYPE_PAGE)
3763+
3764+enum {
3765+ METHOD_COL_NAME,
3766+ METHOD_COL_METHOD
3767+};
3768+
3769+enum {
3770+ IP6_METHOD_AUTO,
3771+ IP6_METHOD_DHCP,
3772+ IP6_METHOD_MANUAL,
3773+ IP6_METHOD_LINK_LOCAL,
3774+ IP6_METHOD_SHARED,
3775+ IP6_METHOD_IGNORE
3776+};
3777+
3778+static void
3779+method_changed (GtkToggleButton *button, CEPageIP6 *page)
3780+{
3781+ gboolean addr_enabled;
3782+ gboolean dns_enabled;
3783+ gboolean routes_enabled;
3784+ GtkWidget *widget;
3785+
3786+ if (RADIO_IS_ACTIVE ("radio_disabled")) {
3787+ addr_enabled = FALSE;
3788+ dns_enabled = FALSE;
3789+ routes_enabled = FALSE;
3790+ } else {
3791+ addr_enabled = RADIO_IS_ACTIVE ("radio_manual");
3792+ dns_enabled = !RADIO_IS_ACTIVE ("radio_local");
3793+ routes_enabled = !RADIO_IS_ACTIVE ("radio_local");
3794+ }
3795+
3796+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
3797+ gtk_widget_set_visible (widget, addr_enabled);
3798+ gtk_widget_set_sensitive (page->dns_entry, dns_enabled);
3799+ gtk_widget_set_sensitive (page->routes_list, routes_enabled);
3800+ gtk_widget_set_sensitive (page->never_default, routes_enabled);
3801+
3802+ ce_page_changed (CE_PAGE (page));
3803+}
3804+
3805+static void
3806+switch_toggled (GObject *object,
3807+ GParamSpec *pspec,
3808+ CEPage *page)
3809+{
3810+ ce_page_changed (page);
3811+}
3812+
3813+static void
3814+update_row_sensitivity (CEPageIP6 *page, GtkWidget *list)
3815+{
3816+ GList *children, *l;
3817+ gint rows = 0, i = 0;
3818+
3819+ children = gtk_container_get_children (GTK_CONTAINER (list));
3820+ for (l = children; l; l = l->next) {
3821+ GtkWidget *row = l->data;
3822+ GtkWidget *button;
3823+
3824+ button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
3825+ if (button != NULL)
3826+ rows++;
3827+ }
3828+ for (l = children; l; l = l->next) {
3829+ GtkWidget *row = l->data;
3830+ GtkWidget *button;
3831+
3832+ button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
3833+ if (button != NULL)
3834+ gtk_widget_set_sensitive (button, rows > 1 && ++i < rows);
3835+ }
3836+ g_list_free (children);
3837+}
3838+
3839+static void
3840+remove_row (GtkButton *button, CEPageIP6 *page)
3841+{
3842+ GtkWidget *row;
3843+ GtkWidget *row_box;
3844+ GtkWidget *list;
3845+
3846+ row_box = gtk_widget_get_parent (GTK_WIDGET (button));
3847+ row = gtk_widget_get_parent (row_box);
3848+ list = gtk_widget_get_parent (row);
3849+
3850+ gtk_container_remove (GTK_CONTAINER (list), row);
3851+
3852+ ce_page_changed (CE_PAGE (page));
3853+
3854+ update_row_sensitivity (page, list);
3855+}
3856+
3857+static gboolean
3858+validate_row (GtkWidget *row)
3859+{
3860+ GtkWidget *box;
3861+ GList *children, *l;
3862+ gboolean valid;
3863+
3864+ valid = FALSE;
3865+ box = gtk_bin_get_child (GTK_BIN (row));
3866+ children = gtk_container_get_children (GTK_CONTAINER (box));
3867+
3868+ for (l = children; l != NULL; l = l->next) {
3869+ if (!GTK_IS_ENTRY (l->data))
3870+ continue;
3871+
3872+ valid = valid || gtk_entry_get_text_length (l->data) > 0;
3873+ }
3874+
3875+ g_list_free (children);
3876+
3877+ return valid;
3878+}
3879+
3880+static gint
3881+sort_first_last (gconstpointer a, gconstpointer b, gpointer data)
3882+{
3883+ gboolean afirst, bfirst, alast, blast;
3884+
3885+ afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first"));
3886+ bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first"));
3887+ alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last"));
3888+ blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last"));
3889+
3890+ if (afirst)
3891+ return -1;
3892+ if (bfirst)
3893+ return 1;
3894+ if (alast)
3895+ return 1;
3896+ if (blast)
3897+ return -1;
3898+
3899+ return 0;
3900+}
3901+
3902+static void
3903+add_address_row (CEPageIP6 *page,
3904+ const gchar *address,
3905+ const gchar *network,
3906+ const gchar *gateway)
3907+{
3908+ GtkSizeGroup *group;
3909+ GtkWidget *row;
3910+ GtkWidget *row_box;
3911+ GtkWidget *widget;
3912+ GtkWidget *delete_button;
3913+ GtkWidget *image;
3914+
3915+ row = gtk_list_box_row_new ();
3916+
3917+ row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
3918+ gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked");
3919+
3920+ widget = gtk_entry_new ();
3921+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
3922+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page);
3923+ g_object_set_data (G_OBJECT (row), "address", widget);
3924+ gtk_entry_set_text (GTK_ENTRY (widget), address);
3925+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
3926+ gtk_widget_set_hexpand (widget, TRUE);
3927+ gtk_container_add (GTK_CONTAINER (row_box), widget);
3928+
3929+ widget = gtk_entry_new ();
3930+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
3931+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page);
3932+ g_object_set_data (G_OBJECT (row), "prefix", widget);
3933+ gtk_entry_set_text (GTK_ENTRY (widget), network);
3934+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
3935+ gtk_widget_set_hexpand (widget, TRUE);
3936+ gtk_container_add (GTK_CONTAINER (row_box), widget);
3937+
3938+ widget = gtk_entry_new ();
3939+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
3940+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page);
3941+ g_object_set_data (G_OBJECT (row), "gateway", widget);
3942+ gtk_entry_set_text (GTK_ENTRY (widget), gateway ? gateway : "");
3943+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
3944+ gtk_widget_set_hexpand (widget, TRUE);
3945+ gtk_container_add (GTK_CONTAINER (row_box), widget);
3946+
3947+ delete_button = gtk_button_new ();
3948+ gtk_widget_set_sensitive (delete_button, FALSE);
3949+ gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button");
3950+ g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
3951+ image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU);
3952+ atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Address"));
3953+ gtk_button_set_image (GTK_BUTTON (delete_button), image);
3954+ gtk_container_add (GTK_CONTAINER (row_box), delete_button);
3955+ g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
3956+
3957+ group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "address_sizegroup"));
3958+ gtk_size_group_add_widget (group, delete_button);
3959+
3960+ gtk_container_add (GTK_CONTAINER (row), row_box);
3961+ gtk_widget_show_all (row);
3962+ gtk_container_add (GTK_CONTAINER (page->address_list), row);
3963+
3964+ update_row_sensitivity (page, page->address_list);
3965+}
3966+
3967+static void
3968+ensure_empty_address_row (CEPageIP6 *page)
3969+{
3970+ GList *children, *l;
3971+
3972+ children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
3973+ l = children;
3974+
3975+ while (l && l->next)
3976+ l = l->next;
3977+
3978+ /* Add the last, stub row if needed*/
3979+ if (!l || validate_row (l->data))
3980+ add_address_row (page, "", "", "");
3981+
3982+ g_list_free (children);
3983+}
3984+
3985+static void
3986+add_address_section (CEPageIP6 *page)
3987+{
3988+ GtkWidget *widget;
3989+ GtkWidget *list;
3990+ gint i;
3991+
3992+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
3993+
3994+ page->address_list = list = gtk_list_box_new ();
3995+ gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
3996+ gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL);
3997+ gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL);
3998+ gtk_container_add (GTK_CONTAINER (widget), list);
3999+
4000+ for (i = 0; i < nm_setting_ip_config_get_num_addresses (page->setting); i++) {
4001+ NMIPAddress *addr;
4002+ char *netmask;
4003+
4004+ addr = nm_setting_ip_config_get_address (page->setting, i);
4005+ netmask = g_strdup_printf ("%u", nm_ip_address_get_prefix (addr));
4006+ add_address_row (page, nm_ip_address_get_address (addr), netmask,
4007+ i == 0 ? nm_setting_ip_config_get_gateway (page->setting) : NULL);
4008+ g_free (netmask);
4009+ }
4010+ if (nm_setting_ip_config_get_num_addresses (page->setting) == 0)
4011+ ensure_empty_address_row (page);
4012+
4013+ gtk_widget_show_all (widget);
4014+}
4015+
4016+static void
4017+add_dns_section (CEPageIP6 *page)
4018+{
4019+ GtkEntry *entry;
4020+ GString *string;
4021+ gint i;
4022+
4023+ page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch"));
4024+ gtk_switch_set_active (page->auto_dns, !nm_setting_ip_config_get_ignore_auto_dns (page->setting));
4025+ g_signal_connect (page->auto_dns, "notify::active", G_CALLBACK (switch_toggled), page);
4026+
4027+ page->dns_entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_entry"));
4028+ entry = GTK_ENTRY (page->dns_entry);
4029+ string = g_string_new ("");
4030+
4031+ for (i = 0; i < nm_setting_ip_config_get_num_dns (page->setting); i++) {
4032+ const char *address;
4033+
4034+ address = nm_setting_ip_config_get_dns (page->setting, i);
4035+
4036+ if (i > 0)
4037+ g_string_append (string, ", ");
4038+
4039+ g_string_append (string, address);
4040+
4041+ }
4042+
4043+ gtk_entry_set_text (entry, string->str);
4044+
4045+ g_signal_connect_swapped (page->dns_entry, "notify::text", G_CALLBACK (ce_page_changed), page);
4046+
4047+ g_string_free (string, TRUE);
4048+}
4049+
4050+static void
4051+add_route_row (CEPageIP6 *page,
4052+ const gchar *address,
4053+ const gchar *prefix,
4054+ const gchar *gateway,
4055+ const gchar *metric)
4056+{
4057+ GtkSizeGroup *group;
4058+ GtkWidget *row;
4059+ GtkWidget *row_box;
4060+ GtkWidget *widget;
4061+ GtkWidget *delete_button;
4062+ GtkWidget *image;
4063+
4064+ row = gtk_list_box_row_new ();
4065+
4066+ row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4067+ gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked");
4068+
4069+ widget = gtk_entry_new ();
4070+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
4071+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
4072+ g_object_set_data (G_OBJECT (row), "address", widget);
4073+ gtk_entry_set_text (GTK_ENTRY (widget), address);
4074+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
4075+ gtk_widget_set_hexpand (widget, TRUE);
4076+ gtk_container_add (GTK_CONTAINER (row_box), widget);
4077+
4078+ widget = gtk_entry_new ();
4079+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
4080+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
4081+ g_object_set_data (G_OBJECT (row), "prefix", widget);
4082+ gtk_entry_set_text (GTK_ENTRY (widget), prefix ? prefix : "");
4083+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
4084+ gtk_widget_set_hexpand (widget, TRUE);
4085+ gtk_container_add (GTK_CONTAINER (row_box), widget);
4086+
4087+ widget = gtk_entry_new ();
4088+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
4089+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
4090+ g_object_set_data (G_OBJECT (row), "gateway", widget);
4091+ gtk_entry_set_text (GTK_ENTRY (widget), gateway);
4092+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 16);
4093+ gtk_widget_set_hexpand (widget, TRUE);
4094+ gtk_container_add (GTK_CONTAINER (row_box), widget);
4095+
4096+ widget = gtk_entry_new ();
4097+ g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
4098+ g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page);
4099+ g_object_set_data (G_OBJECT (row), "metric", widget);
4100+ gtk_entry_set_text (GTK_ENTRY (widget), metric ? metric : "");
4101+ gtk_entry_set_width_chars (GTK_ENTRY (widget), 5);
4102+ gtk_widget_set_hexpand (widget, TRUE);
4103+ gtk_container_add (GTK_CONTAINER (row_box), widget);
4104+
4105+ group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_metric_sizegroup"));
4106+ gtk_size_group_add_widget (group, widget);
4107+
4108+ delete_button = gtk_button_new ();
4109+ gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button");
4110+ g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
4111+ image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU);
4112+ atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route"));
4113+ gtk_button_set_image (GTK_BUTTON (delete_button), image);
4114+ gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER);
4115+ gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER);
4116+ gtk_container_add (GTK_CONTAINER (row_box), delete_button);
4117+ g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
4118+
4119+ group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_sizegroup"));
4120+ gtk_size_group_add_widget (group, delete_button);
4121+
4122+ gtk_container_add (GTK_CONTAINER (row), row_box);
4123+ gtk_widget_show_all (row);
4124+ gtk_container_add (GTK_CONTAINER (page->routes_list), row);
4125+
4126+ update_row_sensitivity (page, page->routes_list);
4127+}
4128+
4129+static void
4130+ensure_empty_routes_row (CEPageIP6 *page)
4131+{
4132+ GList *children, *l;
4133+
4134+ children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
4135+ l = children;
4136+
4137+ while (l && l->next)
4138+ l = l->next;
4139+
4140+ /* Add the last, stub row if needed*/
4141+ if (!l || validate_row (l->data))
4142+ add_route_row (page, "", NULL, "", NULL);
4143+
4144+ g_list_free (children);
4145+}
4146+
4147+static void
4148+add_empty_route_row (CEPageIP6 *page)
4149+{
4150+ add_route_row (page, "", NULL, "", NULL);
4151+}
4152+
4153+static void
4154+add_routes_section (CEPageIP6 *page)
4155+{
4156+ GtkWidget *widget;
4157+ GtkWidget *list;
4158+ gint i;
4159+
4160+ widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
4161+
4162+ page->routes_list = list = gtk_list_box_new ();
4163+ gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE);
4164+ gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL);
4165+ gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL);
4166+ gtk_container_add (GTK_CONTAINER (widget), list);
4167+ page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
4168+ gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting));
4169+ g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page);
4170+
4171+ for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) {
4172+ NMIPRoute *route;
4173+ char *prefix, *metric;
4174+
4175+ route = nm_setting_ip_config_get_route (page->setting, i);
4176+ prefix = g_strdup_printf ("%u", nm_ip_route_get_prefix (route));
4177+ metric = g_strdup_printf ("%u", (guint32) MIN (0, nm_ip_route_get_metric (route)));
4178+ add_route_row (page, nm_ip_route_get_dest (route),
4179+ prefix,
4180+ nm_ip_route_get_next_hop (route),
4181+ metric);
4182+ g_free (prefix);
4183+ g_free (metric);
4184+ }
4185+ if (nm_setting_ip_config_get_num_routes (page->setting) == 0)
4186+ add_empty_route_row (page);
4187+
4188+ gtk_widget_show_all (widget);
4189+}
4190+
4191+enum
4192+{
4193+ RADIO_AUTOMATIC,
4194+ RADIO_DHCP,
4195+ RADIO_LOCAL,
4196+ RADIO_MANUAL,
4197+ RADIO_DISABLED,
4198+ N_RADIO
4199+};
4200+
4201+static void
4202+connect_ip6_page (CEPageIP6 *page)
4203+{
4204+ GtkToggleButton *radios[N_RADIO];
4205+ GtkWidget *content;
4206+ const gchar *str_method;
4207+ gboolean disabled;
4208+ guint method, i;
4209+
4210+ add_address_section (page);
4211+ add_dns_section (page);
4212+ add_routes_section (page);
4213+
4214+ page->disabled = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_disabled"));
4215+
4216+ str_method = nm_setting_ip_config_get_method (page->setting);
4217+ disabled = g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0;
4218+ gtk_toggle_button_set_active (page->disabled, disabled);
4219+ g_signal_connect_swapped (page->disabled, "notify::active", G_CALLBACK (ce_page_changed), page);
4220+ content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content"));
4221+ g_object_bind_property (page->disabled, "active",
4222+ content, "sensitive",
4223+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
4224+
4225+ method = IP6_METHOD_AUTO;
4226+ if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) {
4227+ method = IP6_METHOD_DHCP;
4228+ } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) {
4229+ method = IP6_METHOD_LINK_LOCAL;
4230+ } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) {
4231+ method = IP6_METHOD_MANUAL;
4232+ } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) {
4233+ method = IP6_METHOD_SHARED;
4234+ } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) {
4235+ method = IP6_METHOD_IGNORE;
4236+ }
4237+
4238+ page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check"));
4239+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default),
4240+ nm_setting_ip_config_get_never_default (page->setting));
4241+ g_signal_connect_swapped (page->never_default, "toggled", G_CALLBACK (ce_page_changed), page);
4242+
4243+
4244+ /* Connect radio buttons */
4245+ radios[RADIO_AUTOMATIC] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_automatic"));
4246+ radios[RADIO_DHCP] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_dhcp"));
4247+ radios[RADIO_LOCAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_local"));
4248+ radios[RADIO_MANUAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_manual"));
4249+ radios[RADIO_DISABLED] = page->disabled;
4250+
4251+ for (i = RADIO_AUTOMATIC; i < RADIO_DISABLED; i++)
4252+ g_signal_connect (radios[i], "toggled", G_CALLBACK (method_changed), page);
4253+
4254+ switch (method) {
4255+ case IP6_METHOD_AUTO:
4256+ gtk_toggle_button_set_active (radios[RADIO_AUTOMATIC], TRUE);
4257+ break;
4258+ case IP6_METHOD_DHCP:
4259+ gtk_toggle_button_set_active (radios[RADIO_DHCP], TRUE);
4260+ break;
4261+ case IP6_METHOD_LINK_LOCAL:
4262+ gtk_toggle_button_set_active (radios[RADIO_LOCAL], TRUE);
4263+ break;
4264+ case IP6_METHOD_MANUAL:
4265+ gtk_toggle_button_set_active (radios[RADIO_MANUAL], TRUE);
4266+ break;
4267+ case IP6_METHOD_IGNORE:
4268+ gtk_toggle_button_set_active (radios[RADIO_DISABLED], TRUE);
4269+ break;
4270+ default:
4271+ break;
4272+ }
4273+
4274+ method_changed (NULL, page);
4275+}
4276+
4277+static gboolean
4278+ui_to_setting (CEPageIP6 *page)
4279+{
4280+ const gchar *method;
4281+ gboolean ignore_auto_dns;
4282+ gboolean ignore_auto_routes;
4283+ gboolean never_default;
4284+ GList *children, *l;
4285+ gboolean ret = TRUE;
4286+ GStrv dns_addresses = NULL;
4287+ gchar *dns_text = NULL;
4288+ guint i;
4289+
4290+ if (gtk_toggle_button_get_active (page->disabled)) {
4291+ method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
4292+ } else {
4293+ if (RADIO_IS_ACTIVE ("radio_manual")) {
4294+ method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
4295+ } else if (RADIO_IS_ACTIVE ("radio_local")) {
4296+ method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
4297+ } else if (RADIO_IS_ACTIVE ("radio_dhcp")) {
4298+ method = NM_SETTING_IP6_CONFIG_METHOD_DHCP;
4299+ } else if (RADIO_IS_ACTIVE ("radio_automatic")) {
4300+ method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
4301+ }
4302+ }
4303+
4304+ nm_setting_ip_config_clear_addresses (page->setting);
4305+ if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
4306+ children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
4307+ } else {
4308+ g_object_set (G_OBJECT (page->setting),
4309+ NM_SETTING_IP_CONFIG_GATEWAY, NULL,
4310+ NULL);
4311+ children = NULL;
4312+ }
4313+
4314+ for (l = children; l; l = l->next) {
4315+ GtkWidget *row = l->data;
4316+ GtkEntry *entry;
4317+ const gchar *text_address;
4318+ const gchar *text_prefix;
4319+ const gchar *text_gateway;
4320+ guint32 prefix;
4321+ gchar *end;
4322+ NMIPAddress *addr;
4323+ gboolean have_gateway = FALSE;
4324+
4325+ entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
4326+ if (!entry)
4327+ continue;
4328+
4329+ text_address = gtk_entry_get_text (entry);
4330+ text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix")));
4331+ text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
4332+
4333+ if (!*text_address && !*text_prefix && !*text_gateway) {
4334+ /* ignore empty rows */
4335+ widget_unset_error (GTK_WIDGET (entry));
4336+ widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
4337+ widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
4338+ continue;
4339+ }
4340+
4341+ if (!text_address || !nm_utils_ipaddr_valid (AF_INET6, text_address)) {
4342+ widget_set_error (GTK_WIDGET (entry));
4343+ ret = FALSE;
4344+ } else {
4345+ widget_unset_error (GTK_WIDGET (entry));
4346+ }
4347+
4348+ prefix = strtoul (text_prefix, &end, 10);
4349+ if (!end || *end || prefix == 0 || prefix > 128) {
4350+ widget_set_error (g_object_get_data (G_OBJECT (row), "prefix"));
4351+ ret = FALSE;
4352+ } else {
4353+ widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
4354+ }
4355+
4356+ if (text_gateway && !nm_utils_ipaddr_valid (AF_INET6, text_gateway)) {
4357+ widget_set_error (g_object_get_data (G_OBJECT (row), "gateway"));
4358+ ret = FALSE;
4359+ } else {
4360+ widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
4361+ have_gateway = TRUE;
4362+ }
4363+
4364+ if (!ret)
4365+ continue;
4366+
4367+ addr = nm_ip_address_new (AF_INET6, text_address, prefix, NULL);
4368+ if (have_gateway)
4369+ g_object_set (G_OBJECT (page->setting),
4370+ NM_SETTING_IP_CONFIG_GATEWAY, text_gateway,
4371+ NULL);
4372+ nm_setting_ip_config_add_address (page->setting, addr);
4373+
4374+ if (!l || !l->next)
4375+ ensure_empty_address_row (page);
4376+ }
4377+ g_list_free (children);
4378+
4379+ nm_setting_ip_config_clear_dns (page->setting);
4380+ dns_text = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (page->dns_entry))));
4381+
4382+ if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) ||
4383+ g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) ||
4384+ g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
4385+ dns_addresses = g_strsplit_set (dns_text, ", ", -1);
4386+ else
4387+ dns_addresses = NULL;
4388+
4389+ for (i = 0; dns_addresses && dns_addresses[i]; i++) {
4390+ const gchar *text;
4391+ struct in6_addr tmp_addr;
4392+
4393+ text = dns_addresses[i];
4394+
4395+ if (!text || !*text)
4396+ continue;
4397+
4398+ if (inet_pton (AF_INET6, text, &tmp_addr) <= 0) {
4399+ g_clear_pointer (&dns_addresses, g_strfreev);
4400+ widget_set_error (page->dns_entry);
4401+ ret = FALSE;
4402+ break;
4403+ } else {
4404+ widget_unset_error (page->dns_entry);
4405+ nm_setting_ip_config_add_dns (page->setting, text);
4406+ }
4407+ }
4408+
4409+ nm_setting_ip_config_clear_routes (page->setting);
4410+ if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) ||
4411+ g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) ||
4412+ g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL))
4413+ children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
4414+ else
4415+ children = NULL;
4416+
4417+ for (l = children; l; l = l->next) {
4418+ GtkWidget *row = l->data;
4419+ GtkEntry *entry;
4420+ const gchar *text_address;
4421+ const gchar *text_prefix;
4422+ const gchar *text_gateway;
4423+ const gchar *text_metric;
4424+ guint32 prefix, metric;
4425+ gchar *end;
4426+ NMIPRoute *route;
4427+
4428+ entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
4429+ if (!entry)
4430+ continue;
4431+
4432+ text_address = gtk_entry_get_text (entry);
4433+ text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix")));
4434+ text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
4435+ text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric")));
4436+
4437+ if (!*text_address && !*text_prefix && !*text_gateway && !*text_metric) {
4438+ /* ignore empty rows */
4439+ widget_unset_error (GTK_WIDGET (entry));
4440+ widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
4441+ widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
4442+ widget_unset_error (g_object_get_data (G_OBJECT (row), "metric"));
4443+ continue;
4444+ }
4445+
4446+ if (!nm_utils_ipaddr_valid (AF_INET6, text_address)) {
4447+ widget_set_error (GTK_WIDGET (entry));
4448+ ret = FALSE;
4449+ } else {
4450+ widget_unset_error (GTK_WIDGET (entry));
4451+ }
4452+
4453+ prefix = strtoul (text_prefix, &end, 10);
4454+ if (!end || *end || prefix == 0 || prefix > 128) {
4455+ widget_set_error (g_object_get_data (G_OBJECT (row), "prefix"));
4456+ ret = FALSE;
4457+ } else {
4458+ widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix"));
4459+ }
4460+
4461+ if (!nm_utils_ipaddr_valid (AF_INET6, text_gateway)) {
4462+ widget_set_error (g_object_get_data (G_OBJECT (row), "gateway"));
4463+ ret = FALSE;
4464+ } else {
4465+ widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway"));
4466+ }
4467+
4468+ metric = 0;
4469+ if (*text_metric) {
4470+ errno = 0;
4471+ metric = strtoul (text_metric, NULL, 10);
4472+ if (errno) {
4473+ widget_set_error (g_object_get_data (G_OBJECT (row), "metric"));
4474+ ret = FALSE;
4475+ } else {
4476+ widget_unset_error (g_object_get_data (G_OBJECT (row), "metric"));
4477+ }
4478+ } else {
4479+ widget_unset_error (g_object_get_data (G_OBJECT (row), "metric"));
4480+ }
4481+
4482+ if (!ret)
4483+ continue;
4484+
4485+ route = nm_ip_route_new (AF_INET6, text_address, prefix, text_gateway, metric, NULL);
4486+ nm_setting_ip_config_add_route (page->setting, route);
4487+ nm_ip_route_unref (route);
4488+
4489+ if (!l || !l->next)
4490+ ensure_empty_routes_row (page);
4491+ }
4492+ g_list_free (children);
4493+
4494+ if (!ret)
4495+ goto out;
4496+
4497+ ignore_auto_dns = !gtk_switch_get_active (page->auto_dns);
4498+ ignore_auto_routes = !gtk_switch_get_active (page->auto_routes);
4499+ never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default));
4500+
4501+ g_object_set (page->setting,
4502+ NM_SETTING_IP_CONFIG_METHOD, method,
4503+ NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
4504+ NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
4505+ NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default,
4506+ NULL);
4507+
4508+out:
4509+ g_clear_pointer (&dns_addresses, g_strfreev);
4510+ g_clear_pointer (&dns_text, g_free);
4511+
4512+ return ret;
4513+}
4514+
4515+static gboolean
4516+validate (CEPage *page,
4517+ NMConnection *connection,
4518+ GError **error)
4519+{
4520+ if (!ui_to_setting (CE_PAGE_IP6 (page)))
4521+ return FALSE;
4522+
4523+ return nm_setting_verify (NM_SETTING (CE_PAGE_IP6 (page)->setting), NULL, error);
4524+}
4525+
4526+static void
4527+ce_page_ip6_init (CEPageIP6 *page)
4528+{
4529+}
4530+
4531+static void
4532+ce_page_ip6_class_init (CEPageIP6Class *class)
4533+{
4534+ CEPageClass *page_class= CE_PAGE_CLASS (class);
4535+
4536+ page_class->validate = validate;
4537+}
4538+
4539+CEPage *
4540+ce_page_ip6_new (NMConnection *connection,
4541+ NMClient *client)
4542+{
4543+ CEPageIP6 *page;
4544+
4545+ page = CE_PAGE_IP6 (ce_page_new (CE_TYPE_PAGE_IP6,
4546+ connection,
4547+ client,
4548+ "/org/gnome/control-center/network/ip6-page.ui",
4549+ _("IPv6")));
4550+
4551+ page->setting = nm_connection_get_setting_ip6_config (connection);
4552+ if (!page->setting) {
4553+ page->setting = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ());
4554+ nm_connection_add_setting (connection, NM_SETTING (page->setting));
4555+ }
4556+
4557+ connect_ip6_page (page);
4558+
4559+ return CE_PAGE (page);
4560+}
4561
4562=== added file 'panels/network/connection-editor/ce-page-ip6.h'
4563--- panels/network/connection-editor/ce-page-ip6.h 1970-01-01 00:00:00 +0000
4564+++ panels/network/connection-editor/ce-page-ip6.h 2019-05-01 13:56:52 +0000
4565@@ -0,0 +1,70 @@
4566+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
4567+ *
4568+ * Copyright (C) 2012 Red Hat, Inc.
4569+ *
4570+ * Licensed under the GNU General Public License Version 2
4571+ *
4572+ * This program is free software; you can redistribute it and/or modify
4573+ * it under the terms of the GNU General Public License as published by
4574+ * the Free Software Foundation; either version 2 of the License, or
4575+ * (at your option) any later version.
4576+ *
4577+ * This program is distributed in the hope that it will be useful,
4578+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4579+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4580+ * GNU General Public License for more ip6.
4581+ *
4582+ * You should have received a copy of the GNU General Public License
4583+ * along with this program; if not, write to the Free Software
4584+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
4585+ */
4586+
4587+#ifndef __CE_PAGE_IP6_H
4588+#define __CE_PAGE_IP6_H
4589+
4590+#include <glib-object.h>
4591+
4592+#include <gtk/gtk.h>
4593+#include "ce-page.h"
4594+
4595+G_BEGIN_DECLS
4596+
4597+#define CE_TYPE_PAGE_IP6 (ce_page_ip6_get_type ())
4598+#define CE_PAGE_IP6(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP6, CEPageIP6))
4599+#define CE_PAGE_IP6_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP6, CEPageIP6Class))
4600+#define CE_IS_PAGE_IP6(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP6))
4601+#define CE_IS_PAGE_IP6_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP6))
4602+#define CE_PAGE_IP6_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP6, CEPageIP6Class))
4603+
4604+typedef struct _CEPageIP6 CEPageIP6;
4605+typedef struct _CEPageIP6Class CEPageIP6Class;
4606+
4607+struct _CEPageIP6
4608+{
4609+ CEPage parent;
4610+
4611+ NMSettingIPConfig *setting;
4612+
4613+ GtkToggleButton *disabled;
4614+ GtkWidget *address_list;
4615+ GtkSwitch *auto_dns;
4616+ GtkWidget *dns_entry;
4617+ GtkSwitch *auto_routes;
4618+ GtkWidget *routes_list;
4619+ GtkWidget *never_default;
4620+};
4621+
4622+struct _CEPageIP6Class
4623+{
4624+ CEPageClass parent_class;
4625+};
4626+
4627+GType ce_page_ip6_get_type (void);
4628+
4629+CEPage *ce_page_ip6_new (NMConnection *connection,
4630+ NMClient *client);
4631+
4632+G_END_DECLS
4633+
4634+#endif /* __CE_PAGE_IP6_H */
4635+
4636
4637=== added file 'panels/network/connection-editor/ce-page-security.c'
4638--- panels/network/connection-editor/ce-page-security.c 1970-01-01 00:00:00 +0000
4639+++ panels/network/connection-editor/ce-page-security.c 2019-05-01 13:56:52 +0000
4640@@ -0,0 +1,467 @@
4641+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
4642+ *
4643+ * Copyright (C) 2012 Red Hat, Inc
4644+ *
4645+ * Licensed under the GNU General Public License Version 2
4646+ *
4647+ * This program is free software; you can redistribute it and/or modify
4648+ * it under the terms of the GNU General Public License as published by
4649+ * the Free Software Foundation; either version 2 of the License, or
4650+ * (at your option) any later version.
4651+ *
4652+ * This program is distributed in the hope that it will be useful,
4653+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4654+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4655+ * GNU General Public License for more details.
4656+ *
4657+ * You should have received a copy of the GNU General Public License
4658+ * along with this program; if not, write to the Free Software
4659+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
4660+ */
4661+
4662+#include "config.h"
4663+
4664+#include <glib-object.h>
4665+#include <glib/gi18n.h>
4666+
4667+#include <NetworkManager.h>
4668+
4669+#include "wireless-security.h"
4670+#include "ce-page-security.h"
4671+
4672+G_DEFINE_TYPE (CEPageSecurity, ce_page_security, CE_TYPE_PAGE)
4673+
4674+enum {
4675+ S_NAME_COLUMN,
4676+ S_SEC_COLUMN,
4677+ S_ADHOC_VALID_COLUMN
4678+};
4679+
4680+static gboolean
4681+find_proto (NMSettingWirelessSecurity *sec, const char *item)
4682+{
4683+ guint32 i;
4684+
4685+ for (i = 0; i < nm_setting_wireless_security_get_num_protos (sec); i++) {
4686+ if (!strcmp (item, nm_setting_wireless_security_get_proto (sec, i)))
4687+ return TRUE;
4688+ }
4689+ return FALSE;
4690+}
4691+
4692+static NMUtilsSecurityType
4693+get_default_type_for_security (NMSettingWirelessSecurity *sec)
4694+{
4695+ const char *key_mgmt, *auth_alg;
4696+
4697+ g_return_val_if_fail (sec != NULL, NMU_SEC_NONE);
4698+
4699+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (sec);
4700+ auth_alg = nm_setting_wireless_security_get_auth_alg (sec);
4701+
4702+ /* No IEEE 802.1x */
4703+ if (!strcmp (key_mgmt, "none"))
4704+ return NMU_SEC_STATIC_WEP;
4705+
4706+ if (!strcmp (key_mgmt, "ieee8021x")) {
4707+ if (auth_alg && !strcmp (auth_alg, "leap"))
4708+ return NMU_SEC_LEAP;
4709+ return NMU_SEC_DYNAMIC_WEP;
4710+ }
4711+
4712+ if ( !strcmp (key_mgmt, "wpa-none")
4713+ || !strcmp (key_mgmt, "wpa-psk")) {
4714+ if (find_proto (sec, "rsn"))
4715+ return NMU_SEC_WPA2_PSK;
4716+ else if (find_proto (sec, "wpa"))
4717+ return NMU_SEC_WPA_PSK;
4718+ else
4719+ return NMU_SEC_WPA_PSK;
4720+ }
4721+
4722+ if (!strcmp (key_mgmt, "wpa-eap")) {
4723+ if (find_proto (sec, "rsn"))
4724+ return NMU_SEC_WPA2_ENTERPRISE;
4725+ else if (find_proto (sec, "wpa"))
4726+ return NMU_SEC_WPA_ENTERPRISE;
4727+ else
4728+ return NMU_SEC_WPA_ENTERPRISE;
4729+ }
4730+
4731+ return NMU_SEC_INVALID;
4732+}
4733+
4734+static WirelessSecurity *
4735+security_combo_get_active (CEPageSecurity *page)
4736+{
4737+ GtkTreeIter iter;
4738+ GtkTreeModel *model;
4739+ WirelessSecurity *sec = NULL;
4740+
4741+ model = gtk_combo_box_get_model (page->security_combo);
4742+ gtk_combo_box_get_active_iter (page->security_combo, &iter);
4743+ gtk_tree_model_get (model, &iter, S_SEC_COLUMN, &sec, -1);
4744+
4745+ return sec;
4746+}
4747+
4748+static void
4749+wsec_size_group_clear (GtkSizeGroup *group)
4750+{
4751+ GSList *children;
4752+ GSList *iter;
4753+
4754+ g_return_if_fail (group != NULL);
4755+
4756+ children = gtk_size_group_get_widgets (group);
4757+ for (iter = children; iter; iter = g_slist_next (iter))
4758+ gtk_size_group_remove_widget (group, GTK_WIDGET (iter->data));
4759+}
4760+
4761+static void
4762+security_combo_changed (GtkComboBox *combo,
4763+ gpointer user_data)
4764+{
4765+ CEPageSecurity *page = CE_PAGE_SECURITY (user_data);
4766+ GtkWidget *vbox;
4767+ GList *l, *children;
4768+ WirelessSecurity *sec;
4769+
4770+ wsec_size_group_clear (page->group);
4771+
4772+ vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox"));
4773+ children = gtk_container_get_children (GTK_CONTAINER (vbox));
4774+ for (l = children; l; l = l->next) {
4775+ gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (l->data));
4776+ }
4777+
4778+ sec = security_combo_get_active (page);
4779+ if (sec) {
4780+ GtkWidget *sec_widget;
4781+ GtkWidget *parent;
4782+
4783+ sec_widget = wireless_security_get_widget (sec);
4784+ g_assert (sec_widget);
4785+ parent = gtk_widget_get_parent (sec_widget);
4786+ if (parent)
4787+ gtk_container_remove (GTK_CONTAINER (parent), sec_widget);
4788+
4789+ gtk_size_group_add_widget (page->group, page->security_heading);
4790+ wireless_security_add_to_size_group (sec, page->group);
4791+
4792+ gtk_container_add (GTK_CONTAINER (vbox), sec_widget);
4793+ wireless_security_unref (sec);
4794+ }
4795+
4796+ ce_page_changed (CE_PAGE (page));
4797+}
4798+
4799+static void
4800+stuff_changed_cb (WirelessSecurity *sec, gpointer user_data)
4801+{
4802+ ce_page_changed (CE_PAGE (user_data));
4803+}
4804+
4805+static void
4806+add_security_item (CEPageSecurity *page,
4807+ WirelessSecurity *sec,
4808+ GtkListStore *model,
4809+ GtkTreeIter *iter,
4810+ const char *text,
4811+ gboolean adhoc_valid)
4812+{
4813+ wireless_security_set_changed_notify (sec, stuff_changed_cb, page);
4814+ gtk_list_store_append (model, iter);
4815+ gtk_list_store_set (model, iter,
4816+ S_NAME_COLUMN, text,
4817+ S_SEC_COLUMN, sec,
4818+ S_ADHOC_VALID_COLUMN, adhoc_valid,
4819+ -1);
4820+ wireless_security_unref (sec);
4821+}
4822+
4823+static void
4824+set_sensitive (GtkCellLayout *cell_layout,
4825+ GtkCellRenderer *cell,
4826+ GtkTreeModel *tree_model,
4827+ GtkTreeIter *iter,
4828+ gpointer data)
4829+{
4830+ gboolean *adhoc = data;
4831+ gboolean sensitive = TRUE, adhoc_valid = TRUE;
4832+
4833+ gtk_tree_model_get (tree_model, iter, S_ADHOC_VALID_COLUMN, &adhoc_valid, -1);
4834+ if (*adhoc && !adhoc_valid)
4835+ sensitive = FALSE;
4836+
4837+ g_object_set (cell, "sensitive", sensitive, NULL);
4838+}
4839+
4840+static void
4841+finish_setup (CEPageSecurity *page)
4842+{
4843+ NMConnection *connection = CE_PAGE (page)->connection;
4844+ NMSettingWireless *sw;
4845+ NMSettingWirelessSecurity *sws;
4846+ gboolean is_adhoc = FALSE;
4847+ GtkListStore *sec_model;
4848+ GtkTreeIter iter;
4849+ const gchar *mode;
4850+ guint32 dev_caps = 0;
4851+ NMUtilsSecurityType default_type = NMU_SEC_NONE;
4852+ int active = -1;
4853+ int item = 0;
4854+ GtkComboBox *combo;
4855+ GtkCellRenderer *renderer;
4856+
4857+ sw = nm_connection_get_setting_wireless (connection);
4858+ g_assert (sw);
4859+
4860+ page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4861+
4862+ page->security_heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec"));
4863+ page->security_combo = combo = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_sec"));
4864+
4865+ dev_caps = NM_WIFI_DEVICE_CAP_CIPHER_WEP40
4866+ | NM_WIFI_DEVICE_CAP_CIPHER_WEP104
4867+ | NM_WIFI_DEVICE_CAP_CIPHER_TKIP
4868+ | NM_WIFI_DEVICE_CAP_CIPHER_CCMP
4869+ | NM_WIFI_DEVICE_CAP_WPA
4870+ | NM_WIFI_DEVICE_CAP_RSN;
4871+
4872+ mode = nm_setting_wireless_get_mode (sw);
4873+ if (mode && !strcmp (mode, "adhoc"))
4874+ is_adhoc = TRUE;
4875+ page->adhoc = is_adhoc;
4876+
4877+ sws = nm_connection_get_setting_wireless_security (connection);
4878+ if (sws)
4879+ default_type = get_default_type_for_security (sws);
4880+
4881+ sec_model = gtk_list_store_new (3, G_TYPE_STRING, WIRELESS_TYPE_SECURITY, G_TYPE_BOOLEAN);
4882+
4883+ if (nm_utils_security_valid (NMU_SEC_NONE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
4884+ gtk_list_store_insert_with_values (sec_model, &iter, -1,
4885+ S_NAME_COLUMN, C_("Wi-Fi/Ethernet security", "None"),
4886+ S_ADHOC_VALID_COLUMN, TRUE,
4887+ -1);
4888+ if (default_type == NMU_SEC_NONE)
4889+ active = item;
4890+ item++;
4891+ }
4892+
4893+ if (nm_utils_security_valid (NMU_SEC_STATIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
4894+ WirelessSecurityWEPKey *ws_wep;
4895+ NMWepKeyType wep_type = NM_WEP_KEY_TYPE_KEY;
4896+
4897+ if (default_type == NMU_SEC_STATIC_WEP) {
4898+ sws = nm_connection_get_setting_wireless_security (connection);
4899+ if (sws)
4900+ wep_type = nm_setting_wireless_security_get_wep_key_type (sws);
4901+ if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN)
4902+ wep_type = NM_WEP_KEY_TYPE_KEY;
4903+ }
4904+
4905+ ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_KEY, FALSE, FALSE);
4906+ if (ws_wep) {
4907+ add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model,
4908+ &iter, _("WEP 40/128-bit Key (Hex or ASCII)"),
4909+ TRUE);
4910+ if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_KEY))
4911+ active = item;
4912+ item++;
4913+ }
4914+
4915+ ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_PASSPHRASE, FALSE, FALSE);
4916+ if (ws_wep) {
4917+ add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model,
4918+ &iter, _("WEP 128-bit Passphrase"), TRUE);
4919+ if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE))
4920+ active = item;
4921+ item++;
4922+ }
4923+ }
4924+
4925+ if (nm_utils_security_valid (NMU_SEC_LEAP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
4926+ WirelessSecurityLEAP *ws_leap;
4927+
4928+ ws_leap = ws_leap_new (connection, FALSE);
4929+ if (ws_leap) {
4930+ add_security_item (page, WIRELESS_SECURITY (ws_leap), sec_model,
4931+ &iter, _("LEAP"), FALSE);
4932+ if ((active < 0) && (default_type == NMU_SEC_LEAP))
4933+ active = item;
4934+ item++;
4935+ }
4936+ }
4937+
4938+ if (nm_utils_security_valid (NMU_SEC_DYNAMIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
4939+ WirelessSecurityDynamicWEP *ws_dynamic_wep;
4940+
4941+ ws_dynamic_wep = ws_dynamic_wep_new (connection, TRUE, FALSE);
4942+ if (ws_dynamic_wep) {
4943+ add_security_item (page, WIRELESS_SECURITY (ws_dynamic_wep), sec_model,
4944+ &iter, _("Dynamic WEP (802.1x)"), FALSE);
4945+ if ((active < 0) && (default_type == NMU_SEC_DYNAMIC_WEP))
4946+ active = item;
4947+ item++;
4948+ }
4949+ }
4950+
4951+ if (nm_utils_security_valid (NMU_SEC_WPA_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0) ||
4952+ nm_utils_security_valid (NMU_SEC_WPA2_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
4953+ WirelessSecurityWPAPSK *ws_wpa_psk;
4954+
4955+ ws_wpa_psk = ws_wpa_psk_new (connection, FALSE);
4956+ if (ws_wpa_psk) {
4957+ add_security_item (page, WIRELESS_SECURITY (ws_wpa_psk), sec_model,
4958+ &iter, _("WPA & WPA2 Personal"), FALSE);
4959+ if ((active < 0) && ((default_type == NMU_SEC_WPA_PSK) || (default_type == NMU_SEC_WPA2_PSK)))
4960+ active = item;
4961+ item++;
4962+ }
4963+ }
4964+
4965+ if (nm_utils_security_valid (NMU_SEC_WPA_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0) ||
4966+ nm_utils_security_valid (NMU_SEC_WPA2_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
4967+ WirelessSecurityWPAEAP *ws_wpa_eap;
4968+
4969+ ws_wpa_eap = ws_wpa_eap_new (connection, TRUE, FALSE);
4970+ if (ws_wpa_eap) {
4971+ add_security_item (page, WIRELESS_SECURITY (ws_wpa_eap), sec_model,
4972+ &iter, _("WPA & WPA2 Enterprise"), FALSE);
4973+ if ((active < 0) && ((default_type == NMU_SEC_WPA_ENTERPRISE) || (default_type == NMU_SEC_WPA2_ENTERPRISE)))
4974+ active = item;
4975+ item++;
4976+ }
4977+ }
4978+
4979+ gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sec_model));
4980+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
4981+
4982+ renderer = gtk_cell_renderer_text_new ();
4983+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
4984+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", S_NAME_COLUMN, NULL);
4985+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_sensitive, &page->adhoc, NULL);
4986+
4987+ gtk_combo_box_set_active (combo, active < 0 ? 0 : (guint32) active);
4988+ g_object_unref (G_OBJECT (sec_model));
4989+
4990+ page->security_combo = combo;
4991+
4992+ security_combo_changed (combo, page);
4993+ g_signal_connect (combo, "changed",
4994+ G_CALLBACK (security_combo_changed), page);
4995+}
4996+
4997+static gboolean
4998+validate (CEPage *page,
4999+ NMConnection *connection,
5000+ GError **error)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches