Merge lp:~donadigo/switchboard-plug-networking/vpn into lp:~elementary-pantheon/switchboard-plug-networking/trunk
- vpn
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Danielle Foré | ||||||||
Approved revision: | 273 | ||||||||
Merged at revision: | 272 | ||||||||
Proposed branch: | lp:~donadigo/switchboard-plug-networking/vpn | ||||||||
Merge into: | lp:~elementary-pantheon/switchboard-plug-networking/trunk | ||||||||
Diff against target: |
1380 lines (+794/-108) 19 files modified
src/CMakeLists.txt (+4/-0) src/Plug.vala (+20/-20) src/Utils.vala (+0/-10) src/Widgets/Device/DeviceItem.vala (+5/-8) src/Widgets/Device/DevicePage.vala (+5/-7) src/Widgets/DeviceList.vala (+37/-14) src/Widgets/EtherInterface.vala (+4/-4) src/Widgets/HotspotInterface.vala (+2/-3) src/Widgets/Page.vala (+30/-11) src/Widgets/Proxy/ProxyPage.vala (+1/-2) src/Widgets/SettingsButton.vala (+41/-0) src/Widgets/VPNInfoBox.vala (+153/-0) src/Widgets/VPNPage.vala (+327/-0) src/Widgets/WifiInterface.vala (+8/-10) src/common/Utils.vala (+7/-1) src/common/Widgets/AbstractWifiInterface.vala (+0/-1) src/common/Widgets/NMVisualizer.vala (+25/-13) src/common/Widgets/VPNMenuItem.vala (+121/-0) src/common/Widgets/WifiMenuItem.vala (+4/-4) |
||||||||
To merge this branch: | bzr merge lp:~donadigo/switchboard-plug-networking/vpn | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Danielle Foré | ux | Needs Fixing | |
Corentin Noël | code | Pending | |
Review via email: mp+300922@code.launchpad.net |
Commit message
- Fix bug #1440563: "Configure VPN".
- Fix bug #1579183: "Ignore virtual network hardware".
- Minor code clean ups.
Description of the change
Fixes bug #1440563: "Configure VPN" and bug #1579183: "Ignore virtual network hardware".
This branch adds VPN support, mainly for adding / displaying / editing and removing VPN connections from the plug. It makes use of the connection editor provided from Gnome which is already present in "Advanced settings" of devices. Then it updates the plug with new information as it's being changed.
Also it prevents virtual devices from showing now, which is an common update from:
https:/
There are also some code clean ups but they are rather minor.
Danielle Foré (danrabbit) wrote : | # |
* Please use the icon "network-vpn", not "network-
* Since we can't select in the list without activating, let's remove the "-" icon for now
Adam Bieńkowski (donadigo) wrote : | # |
Updated.
Danielle Foré (danrabbit) wrote : | # |
can you put the status back on VPN? I know it looks weird right now, but that's an icons bug and there's a report for it.
- 272. By Adam Bieńkowski
-
Add back the VPN status icon
- 273. By Adam Bieńkowski
-
Revert VPNPage strings from the last commit
Preview Diff
1 | === modified file 'src/CMakeLists.txt' |
2 | --- src/CMakeLists.txt 2015-12-07 16:07:16 +0000 |
3 | +++ src/CMakeLists.txt 2016-07-26 21:06:49 +0000 |
4 | @@ -27,11 +27,15 @@ |
5 | Widgets/Proxy/ProxyExceptionsPage.vala |
6 | Widgets/Proxy/ProxyPage.vala |
7 | Widgets/InfoBox.vala |
8 | + Widgets/SettingsButton.vala |
9 | + Widgets/VPNPage.vala |
10 | + Widgets/VPNInfoBox.vala |
11 | Widgets/Footer.vala |
12 | Widgets/InfoScreen.vala |
13 | Widgets/Hotspot/HotspotDialog.vala |
14 | common/Utils.vala |
15 | common/Widgets/WifiMenuItem.vala |
16 | + common/Widgets/VPNMenuItem.vala |
17 | common/Widgets/AbstractWifiInterface.vala |
18 | common/Widgets/AbstractEtherInterface.vala |
19 | common/Widgets/AbstractHotspotInterface.vala |
20 | |
21 | === modified file 'src/Plug.vala' |
22 | --- src/Plug.vala 2016-06-27 20:16:52 +0000 |
23 | +++ src/Plug.vala 2016-07-26 21:06:49 +0000 |
24 | @@ -41,19 +41,21 @@ |
25 | private Widgets.DeviceList device_list; |
26 | private Widgets.Footer footer; |
27 | private Widgets.InfoScreen no_devices; |
28 | - |
29 | + |
30 | protected override void add_interface (WidgetNMInterface widget_interface) { |
31 | - device_list.add_device_to_list (widget_interface); |
32 | + device_list.add_iface_to_list (widget_interface); |
33 | |
34 | select_first (); |
35 | show_all (); |
36 | } |
37 | |
38 | protected override void remove_interface (WidgetNMInterface widget_interface) { |
39 | - device_list.remove_device_from_list (widget_interface.device); |
40 | + device_list.remove_iface_from_list (widget_interface); |
41 | + |
42 | if (content.get_visible_child () == widget_interface) { |
43 | + var row = device_list.get_selected_row (); |
44 | int index = device_list.get_selected_row ().get_index (); |
45 | - if (index >= 0) { |
46 | + if (row != null && row.get_index () >= 0) { |
47 | device_list.get_row_at_index (index).activate (); |
48 | } else { |
49 | select_first (); |
50 | @@ -64,6 +66,14 @@ |
51 | show_all (); |
52 | } |
53 | |
54 | + protected override void add_connection (NM.RemoteConnection connection) { |
55 | + device_list.add_connection (connection); |
56 | + } |
57 | + |
58 | + protected override void remove_connection (NM.RemoteConnection connection) { |
59 | + device_list.remove_connection (connection); |
60 | + } |
61 | + |
62 | private void select_first () { |
63 | device_list.select_first_item (); |
64 | } |
65 | @@ -100,7 +110,7 @@ |
66 | sidebar.pack_start (scrolled_window, true, true); |
67 | sidebar.pack_start (footer, false, false); |
68 | |
69 | - paned.pack1 (sidebar, true, true); |
70 | + paned.pack1 (sidebar, false, false); |
71 | paned.pack2 (content, true, false); |
72 | paned.set_position (240); |
73 | |
74 | @@ -115,13 +125,14 @@ |
75 | /* Main function to connect all the signals */ |
76 | private void connect_signals () { |
77 | device_list.row_activated.connect ((row) => { |
78 | - if (content.get_children ().find (((Widgets.DeviceItem)row).page) == null) { |
79 | - content.add (((Widgets.DeviceItem) row).page); |
80 | + var page = ((Widgets.DeviceItem)row).page; |
81 | + if (content.get_children ().find (page) == null) { |
82 | + content.add (page); |
83 | } |
84 | |
85 | - content.visible_child = ((Widgets.DeviceItem)row).page; |
86 | + content.visible_child = page; |
87 | }); |
88 | - |
89 | + |
90 | device_list.show_no_devices.connect ((show) => { |
91 | scrolled_window.sensitive = !show; |
92 | if (show) { |
93 | @@ -142,17 +153,6 @@ |
94 | } |
95 | }); |
96 | } |
97 | - |
98 | - /*private void show_error_dialog () { |
99 | - var error_dialog = new Gtk.MessageDialog (null, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, " "); |
100 | - error_dialog.text = _("Could not enable device: there are no available |
101 | -connections for this device."); |
102 | - error_dialog.deletable = false; |
103 | - error_dialog.show_all (); |
104 | - error_dialog.response.connect ((response_id) => { |
105 | - error_dialog.destroy (); |
106 | - }); |
107 | - }*/ |
108 | } |
109 | |
110 | public class Plug : Switchboard.Plug { |
111 | |
112 | === modified file 'src/Utils.vala' |
113 | --- src/Utils.vala 2016-06-06 21:45:31 +0000 |
114 | +++ src/Utils.vala 2016-07-26 21:06:49 +0000 |
115 | @@ -184,16 +184,6 @@ |
116 | INVALID |
117 | } |
118 | |
119 | - public static Gtk.Button get_advanced_button_from_device (NM.Device? device, string title = _("Advanced Settings…")) { |
120 | - var details_btn = new Gtk.Button.with_label (title); |
121 | - details_btn.clicked.connect (() => { |
122 | - new Granite.Services.SimpleCommand ("/usr/bin", |
123 | - "nm-connection-editor --edit=" + device.get_active_connection ().get_uuid ()).run (); |
124 | - }); |
125 | - |
126 | - return details_btn; |
127 | - } |
128 | - |
129 | public static string state_to_string (NM.DeviceState state) { |
130 | switch (state) { |
131 | case NM.DeviceState.ACTIVATED: |
132 | |
133 | === modified file 'src/Widgets/Device/DeviceItem.vala' |
134 | --- src/Widgets/Device/DeviceItem.vala 2016-02-12 15:09:30 +0000 |
135 | +++ src/Widgets/Device/DeviceItem.vala 2016-07-26 21:06:49 +0000 |
136 | @@ -21,7 +21,7 @@ |
137 | public class DeviceItem : Gtk.ListBoxRow { |
138 | public NM.Device? device = null; |
139 | private NM.RemoteSettings? nm_settings = null; |
140 | - public Gtk.Box? page = null; |
141 | + public Gtk.Widget? page = null; |
142 | public Utils.ItemType type; |
143 | |
144 | public Gtk.Label row_description; |
145 | @@ -134,6 +134,7 @@ |
146 | case Network.State.CONNECTED_WIFI_GOOD: |
147 | case Network.State.CONNECTED_WIFI_EXCELLENT: |
148 | case Network.State.CONNECTED_WIRED: |
149 | + case Network.State.CONNECTED_VPN: |
150 | status_image.icon_name = "user-available"; |
151 | break; |
152 | case Network.State.DISCONNECTED: |
153 | @@ -141,20 +142,16 @@ |
154 | break; |
155 | case Network.State.FAILED_WIRED: |
156 | case Network.State.FAILED_WIFI: |
157 | + case Network.State.FAILED_VPN: |
158 | status_image.icon_name = "user-busy"; |
159 | break; |
160 | - /*case NM.DeviceState.UNMANAGED: |
161 | - status_image.icon_name = "user-invisible"; |
162 | - break;*/ |
163 | default: |
164 | status_image.icon_name = "user-away"; |
165 | break; |
166 | } |
167 | |
168 | row_description.label = Common.Utils.network_state_to_string (state); |
169 | - } |
170 | - |
171 | - if (custom_mode != Utils.CustomMode.INVALID) { |
172 | + } else if (custom_mode != Utils.CustomMode.INVALID) { |
173 | switch (custom_mode) { |
174 | case Utils.CustomMode.PROXY_NONE: |
175 | row_description.label = _("Disabled"); |
176 | @@ -169,7 +166,7 @@ |
177 | status_image.icon_name = "user-available"; |
178 | break; |
179 | } |
180 | - } |
181 | + } |
182 | |
183 | row_description.label = "<span font_size='small'>" + row_description.label + "</span>"; |
184 | } |
185 | |
186 | === modified file 'src/Widgets/Device/DevicePage.vala' |
187 | --- src/Widgets/Device/DevicePage.vala 2016-02-12 15:09:30 +0000 |
188 | +++ src/Widgets/Device/DevicePage.vala 2016-07-26 21:06:49 +0000 |
189 | @@ -18,11 +18,10 @@ |
190 | */ |
191 | |
192 | namespace Network.Widgets { |
193 | - public class DevicePage : Network.WidgetNMInterface { |
194 | + public class DevicePage : WidgetNMInterface { |
195 | |
196 | public DevicePage (NM.Client client, NM.RemoteSettings settings, NM.Device device) { |
197 | - info_box = new InfoBox.from_device (device); |
198 | - this.init (device, info_box); |
199 | + this.init (device); |
200 | |
201 | bottom_revealer.transition_type = Gtk.RevealerTransitionType.NONE; |
202 | |
203 | @@ -30,7 +29,7 @@ |
204 | display_title = Utils.type_to_string (device.get_device_type ()); |
205 | |
206 | var details_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); |
207 | - details_box.pack_end (Utils.get_advanced_button_from_device (device), false, false, 0); |
208 | + details_box.pack_end (new SettingsButton.from_device (device), false, false, 0); |
209 | |
210 | update (); |
211 | |
212 | @@ -42,14 +41,13 @@ |
213 | } |
214 | |
215 | public DevicePage.from_owner (DeviceItem? owner) { |
216 | - info_box = new InfoBox.from_owner (owner); |
217 | - this.init (owner.get_item_device (), info_box); |
218 | + this.init (owner.get_item_device ()); |
219 | |
220 | this.icon_name = owner.get_item_icon_name (); |
221 | display_title = Utils.type_to_string (device.get_device_type ()); |
222 | |
223 | var details_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); |
224 | - details_box.pack_start (Utils.get_advanced_button_from_device (device), false, false, 0); |
225 | + details_box.pack_start (new SettingsButton.from_device (device), false, false, 0); |
226 | |
227 | update (); |
228 | |
229 | |
230 | === modified file 'src/Widgets/DeviceList.vala' |
231 | --- src/Widgets/DeviceList.vala 2016-02-12 15:09:30 +0000 |
232 | +++ src/Widgets/DeviceList.vala 2016-07-26 21:06:49 +0000 |
233 | @@ -24,6 +24,7 @@ |
234 | private Gtk.Label virtual_l; |
235 | private Gtk.Label devices_l; |
236 | private DeviceItem proxy; |
237 | + private DeviceItem vpn; |
238 | |
239 | public DeviceList () { |
240 | virtual_l = new Gtk.Label (_("Virtual")); |
241 | @@ -42,21 +43,15 @@ |
242 | bool show = (get_children ().length () > 0); |
243 | this.show_no_devices (!show); |
244 | this.add_proxy (); |
245 | + this.add_vpn (); |
246 | } |
247 | |
248 | - public void add_device_to_list (WidgetNMInterface iface) { |
249 | - DeviceItem item; |
250 | + public void add_iface_to_list (WidgetNMInterface iface) { |
251 | + DeviceItem item; |
252 | if (iface is AbstractWifiInterface) { |
253 | - item = new DeviceItem.from_interface (iface, "network-wireless"); |
254 | + item = new DeviceItem.from_interface (iface, "network-wireless"); |
255 | } else if (iface is AbstractHotspotInterface) { |
256 | item = new DeviceItem.from_interface (iface, "network-wireless-hotspot"); |
257 | - item.no_show_all = true; |
258 | - iface.device.state_changed.connect ((state) => { |
259 | - item.visible = (state != NM.DeviceState.UNAVAILABLE |
260 | - && state != NM.DeviceState.UNMANAGED |
261 | - && state != NM.DeviceState.UNKNOWN); |
262 | - }); |
263 | - |
264 | item.type = Utils.ItemType.VIRTUAL; |
265 | } else { |
266 | if (iface.device.get_iface ().has_prefix ("usb")) { |
267 | @@ -70,17 +65,37 @@ |
268 | show_all (); |
269 | } |
270 | |
271 | - public void remove_device_from_list (NM.Device device) { |
272 | + public void remove_iface_from_list (WidgetNMInterface iface) { |
273 | foreach (Gtk.Widget _list_item in get_children ()) { |
274 | var list_item = (DeviceItem)_list_item; |
275 | - if (list_item.device == device) { |
276 | + if (list_item.page == iface) { |
277 | remove_row_from_list (list_item); |
278 | } |
279 | } |
280 | } |
281 | |
282 | + public void add_connection (NM.RemoteConnection connection) { |
283 | + switch (connection.get_connection_type ()) { |
284 | + case NM.SettingVpn.SETTING_NAME: |
285 | + ((VPNPage)vpn.page).add_connection (connection); |
286 | + break; |
287 | + default: |
288 | + break; |
289 | + } |
290 | + } |
291 | + |
292 | + public void remove_connection (NM.RemoteConnection connection) { |
293 | + switch (connection.get_connection_type ()) { |
294 | + case NM.SettingVpn.SETTING_NAME: |
295 | + ((VPNPage)vpn.page).remove_connection (connection); |
296 | + break; |
297 | + default: |
298 | + break; |
299 | + } |
300 | + } |
301 | + |
302 | public void remove_row_from_list (DeviceItem item) { |
303 | - this.remove (item); |
304 | + this.remove (item); |
305 | show_all (); |
306 | } |
307 | |
308 | @@ -91,7 +106,15 @@ |
309 | |
310 | this.add (proxy); |
311 | } |
312 | - |
313 | + |
314 | + private void add_vpn () { |
315 | + vpn = new DeviceItem (_("VPN"), "", "network-vpn"); |
316 | + vpn.page = new VPNPage (vpn); |
317 | + vpn.type = Utils.ItemType.VIRTUAL; |
318 | + |
319 | + this.add (vpn); |
320 | + } |
321 | + |
322 | public void select_first_item () { |
323 | this.get_row_at_index (0).activate (); |
324 | } |
325 | |
326 | === modified file 'src/Widgets/EtherInterface.vala' |
327 | --- src/Widgets/EtherInterface.vala 2016-07-19 08:02:20 +0000 |
328 | +++ src/Widgets/EtherInterface.vala 2016-07-26 21:06:49 +0000 |
329 | @@ -18,13 +18,13 @@ |
330 | */ |
331 | |
332 | namespace Network.Widgets { |
333 | - public class EtherInterface : Network.AbstractEtherInterface { |
334 | + public class EtherInterface : AbstractEtherInterface { |
335 | private Gtk.Revealer top_revealer; |
336 | |
337 | public EtherInterface (NM.Client client, NM.RemoteSettings settings, NM.Device device) { |
338 | - info_box = new InfoBox.from_device (device); |
339 | + this.init (device); |
340 | + |
341 | info_box.halign = Gtk.Align.CENTER; |
342 | - this.init (device, info_box); |
343 | |
344 | this.icon_name = "network-wired"; |
345 | |
346 | @@ -34,7 +34,7 @@ |
347 | top_revealer.add (info_box); |
348 | |
349 | var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); |
350 | - button_box.pack_end (Utils.get_advanced_button_from_device (device), false, false, 0); |
351 | + button_box.pack_end (new SettingsButton.from_device (device), false, false, 0); |
352 | |
353 | bottom_box.add (button_box); |
354 | |
355 | |
356 | === modified file 'src/Widgets/HotspotInterface.vala' |
357 | --- src/Widgets/HotspotInterface.vala 2016-02-12 15:09:30 +0000 |
358 | +++ src/Widgets/HotspotInterface.vala 2016-07-26 21:06:49 +0000 |
359 | @@ -30,15 +30,14 @@ |
360 | public HotspotInterface (WifiInterface _root_iface) { |
361 | root_iface = _root_iface; |
362 | nm_settings = _root_iface.get_nm_settings (); |
363 | - info_box = new InfoBox.from_device (root_iface.device); |
364 | - this.init (root_iface.device, info_box); |
365 | + this.init (root_iface.device); |
366 | |
367 | this.icon_name = "network-wireless-hotspot"; |
368 | |
369 | hotspot_revealer = new Gtk.Revealer (); |
370 | hotspot_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN; |
371 | |
372 | - hotspot_settings_btn = Utils.get_advanced_button_from_device (device, _("Hotspot Settings…")); |
373 | + hotspot_settings_btn = new SettingsButton.from_device (device, _("Hotspot Settings…")); |
374 | |
375 | var hinfo_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); |
376 | |
377 | |
378 | === modified file 'src/Widgets/Page.vala' |
379 | --- src/Widgets/Page.vala 2016-06-06 21:45:31 +0000 |
380 | +++ src/Widgets/Page.vala 2016-07-26 21:06:49 +0000 |
381 | @@ -34,7 +34,19 @@ |
382 | |
383 | set { |
384 | _icon_name = value; |
385 | - device_img.icon_name = _icon_name; |
386 | + device_img.icon_name = value; |
387 | + } |
388 | + } |
389 | + |
390 | + private string _title; |
391 | + public string title { |
392 | + get { |
393 | + return _title; |
394 | + } |
395 | + |
396 | + set { |
397 | + _title = value; |
398 | + device_label.label = value; |
399 | } |
400 | } |
401 | |
402 | @@ -57,16 +69,13 @@ |
403 | bottom_revealer.add (bottom_box); |
404 | } |
405 | |
406 | - public void init (NM.Device _device, Widgets.InfoBox _info_box) { |
407 | + public void init (NM.Device? _device) { |
408 | this.device = _device; |
409 | - this.info_box = _info_box; |
410 | - info_box.margin_end = 16; |
411 | - info_box.info_changed.connect (update); |
412 | - |
413 | - device_img = new Gtk.Image.from_icon_name (_icon_name, Gtk.IconSize.DIALOG); |
414 | + |
415 | + device_img = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DIALOG); |
416 | device_img.pixel_size = 48; |
417 | |
418 | - device_label = new Gtk.Label (Utils.type_to_string (device.get_device_type ())); |
419 | + device_label = new Gtk.Label (null); |
420 | device_label.ellipsize = Pango.EllipsizeMode.MIDDLE; |
421 | device_label.get_style_context ().add_class ("h2"); |
422 | |
423 | @@ -76,6 +85,14 @@ |
424 | |
425 | control_switch.notify["active"].connect (control_switch_activated); |
426 | |
427 | + if (device != null) { |
428 | + this.info_box = new InfoBox.from_device (device); |
429 | + info_box.margin_end = 16; |
430 | + info_box.info_changed.connect (update); |
431 | + |
432 | + title = Utils.type_to_string (device.get_device_type ()); |
433 | + } |
434 | + |
435 | control_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12); |
436 | control_box.pack_start (device_img, false, false, 0); |
437 | control_box.pack_start (device_label, false, false, 0); |
438 | @@ -86,9 +103,11 @@ |
439 | } |
440 | |
441 | public virtual void update () { |
442 | - string sent_bytes, received_bytes; |
443 | - this.get_activity_information (device.get_iface (), out sent_bytes, out received_bytes); |
444 | - info_box.update_activity (sent_bytes, received_bytes); |
445 | + if (info_box != null) { |
446 | + string sent_bytes, received_bytes; |
447 | + this.get_activity_information (device.get_iface (), out sent_bytes, out received_bytes); |
448 | + info_box.update_activity (sent_bytes, received_bytes); |
449 | + } |
450 | |
451 | update_switch (); |
452 | |
453 | |
454 | === modified file 'src/Widgets/Proxy/ProxyPage.vala' |
455 | --- src/Widgets/Proxy/ProxyPage.vala 2016-02-12 15:09:30 +0000 |
456 | +++ src/Widgets/Proxy/ProxyPage.vala 2016-07-26 21:06:49 +0000 |
457 | @@ -42,7 +42,6 @@ |
458 | stackswitcher.stack = stack; |
459 | |
460 | proxy_settings.changed.connect (update_mode); |
461 | - |
462 | update_mode (); |
463 | |
464 | this.add (stackswitcher); |
465 | @@ -52,7 +51,7 @@ |
466 | stack.visible_child = configuration_page; |
467 | } |
468 | |
469 | - public void update_mode () { |
470 | + private void update_mode () { |
471 | var mode = Utils.CustomMode.INVALID; |
472 | switch (proxy_settings.mode) { |
473 | case "none": |
474 | |
475 | === added file 'src/Widgets/SettingsButton.vala' |
476 | --- src/Widgets/SettingsButton.vala 1970-01-01 00:00:00 +0000 |
477 | +++ src/Widgets/SettingsButton.vala 2016-07-26 21:06:49 +0000 |
478 | @@ -0,0 +1,41 @@ |
479 | +/*- |
480 | + * Copyright (c) 2015-2016 elementary LLC. |
481 | + * |
482 | + * This program is free software: you can redistribute it and/or modify |
483 | + * it under the terms of the GNU Lesser General Public License as published by |
484 | + * the Free Software Foundation, either version 2.1 of the License, or |
485 | + * (at your option) any later version. |
486 | + * |
487 | + * This program is distributed in the hope that it will be useful, |
488 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
489 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
490 | + * GNU Lesser General Public License for more details. |
491 | + * |
492 | + * You should have received a copy of the GNU Lesser General Public License |
493 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
494 | + * |
495 | + * Authored by: Adam Bieńkowski <donadigos159@gmail.com> |
496 | + */ |
497 | + |
498 | + namespace Network.Widgets { |
499 | + public class SettingsButton : Gtk.Button { |
500 | + private string uuid = ""; |
501 | + |
502 | + construct { |
503 | + clicked.connect (() => { |
504 | + new Granite.Services.SimpleCommand ("/usr/bin", |
505 | + "nm-connection-editor --edit=%s".printf (uuid)).run (); |
506 | + }); |
507 | + } |
508 | + |
509 | + public SettingsButton.from_device (NM.Device device, string title = _("Advanced Settings…")) { |
510 | + label = title; |
511 | + uuid = device.get_active_connection ().get_uuid (); |
512 | + } |
513 | + |
514 | + public SettingsButton.from_connection (NM.Connection connection, string title = _("Advanced Settings…")) { |
515 | + label = title; |
516 | + uuid = connection.get_uuid (); |
517 | + } |
518 | + } |
519 | +} |
520 | \ No newline at end of file |
521 | |
522 | === added file 'src/Widgets/VPNInfoBox.vala' |
523 | --- src/Widgets/VPNInfoBox.vala 1970-01-01 00:00:00 +0000 |
524 | +++ src/Widgets/VPNInfoBox.vala 2016-07-26 21:06:49 +0000 |
525 | @@ -0,0 +1,153 @@ |
526 | +/*- |
527 | + * Copyright (c) 2015-2016 elementary LLC. |
528 | + * |
529 | + * This program is free software: you can redistribute it and/or modify |
530 | + * it under the terms of the GNU Lesser General Public License as published by |
531 | + * the Free Software Foundation, either version 2.1 of the License, or |
532 | + * (at your option) any later version. |
533 | + * |
534 | + * This program is distributed in the hope that it will be useful, |
535 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
536 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
537 | + * GNU Lesser General Public License for more details. |
538 | + * |
539 | + * You should have received a copy of the GNU Lesser General Public License |
540 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
541 | + * |
542 | + * Authored by: Adam Bieńkowski <donadigos159@gmail.com> |
543 | + */ |
544 | + |
545 | +namespace Network.Widgets { |
546 | + public class VPNInfoBox : Gtk.Grid { |
547 | + private NM.RemoteConnection? connection = null; |
548 | + private string service_type; |
549 | + |
550 | + private Gtk.Label type; |
551 | + private Gtk.Label gateway; |
552 | + private Gtk.Label username; |
553 | + private Gtk.Label password; |
554 | + |
555 | + public VPNInfoBox () { |
556 | + column_spacing = 12; |
557 | + row_spacing = 6; |
558 | + |
559 | + var type_head = new Gtk.Label (_("VPN Type:")); |
560 | + type_head.halign = Gtk.Align.END; |
561 | + |
562 | + var gateway_head = new Gtk.Label (_("Gateway:")); |
563 | + gateway_head.halign = Gtk.Align.END; |
564 | + |
565 | + var username_head = new Gtk.Label (_("Username:")); |
566 | + username_head.halign = Gtk.Align.END; |
567 | + |
568 | + var password_head = new Gtk.Label (_("Password:")); |
569 | + password_head.halign = Gtk.Align.END; |
570 | + |
571 | + type = new Gtk.Label (""); |
572 | + type.selectable = true; |
573 | + type.xalign = 0; |
574 | + type.no_show_all = true; |
575 | + |
576 | + gateway = new Gtk.Label (""); |
577 | + gateway.selectable = true; |
578 | + gateway.xalign = 0; |
579 | + gateway.no_show_all = true; |
580 | + |
581 | + username = new Gtk.Label (""); |
582 | + username.selectable = true; |
583 | + username.xalign = 0; |
584 | + username.no_show_all = true; |
585 | + |
586 | + password = new Gtk.Label (""); |
587 | + password.selectable = true; |
588 | + password.xalign = 0; |
589 | + password_head.no_show_all = true; |
590 | + |
591 | + attach (type_head, 0, 0); |
592 | + attach_next_to (type, type_head, Gtk.PositionType.RIGHT); |
593 | + |
594 | + attach_next_to (gateway_head, type_head, Gtk.PositionType.BOTTOM); |
595 | + attach_next_to (gateway, gateway_head, Gtk.PositionType.RIGHT); |
596 | + |
597 | + attach_next_to (username_head, gateway_head, Gtk.PositionType.BOTTOM); |
598 | + attach_next_to (username, username_head, Gtk.PositionType.RIGHT); |
599 | + |
600 | + attach_next_to (password_head, username_head, Gtk.PositionType.BOTTOM); |
601 | + attach_next_to (password, password_head, Gtk.PositionType.RIGHT); |
602 | + } |
603 | + |
604 | + public void set_connection (NM.RemoteConnection _connection) { |
605 | + connection = _connection; |
606 | + connection.changed.connect (update_status); |
607 | + update_status (); |
608 | + } |
609 | + |
610 | + // From https://github.com/GNOME/gnome-control-center/blob/master/panels/network/net-vpn.c |
611 | + private string get_key_group_username () { |
612 | + switch (service_type) { |
613 | + case "openvpn": |
614 | + case "openconnect": |
615 | + return "username"; |
616 | + case "vpnc": |
617 | + return "Xauth username"; |
618 | + case "pptp": |
619 | + return "user"; |
620 | + case "openswan": |
621 | + return "leftxauthusername"; |
622 | + } |
623 | + |
624 | + return ""; |
625 | + } |
626 | + |
627 | + private string get_key_group_password () { |
628 | + if (service_type == "vpnc") { |
629 | + return "Xauth password"; |
630 | + } |
631 | + |
632 | + return ""; |
633 | + } |
634 | + |
635 | + private string get_key_gateway () { |
636 | + switch (service_type) { |
637 | + case "openvpn": |
638 | + return "remote"; |
639 | + case "vpnc": |
640 | + return "IPSec gateway"; |
641 | + case "pptp": |
642 | + case "openconnect": |
643 | + return "gateway"; |
644 | + case "openswan": |
645 | + return "right"; |
646 | + } |
647 | + |
648 | + return ""; |
649 | + } |
650 | + |
651 | + |
652 | + private string get_service_type () { |
653 | + var setting_vpn = connection.get_setting_vpn (); |
654 | + string service_type = setting_vpn.get_service_type (); |
655 | + string[] arr = service_type.split ("."); |
656 | + return arr[arr.length - 1]; |
657 | + } |
658 | + |
659 | + public void update_status () { |
660 | + if (connection == null) { |
661 | + return; |
662 | + } |
663 | + |
664 | + service_type = get_service_type (); |
665 | + |
666 | + var setting_vpn = connection.get_setting_vpn (); |
667 | + type.label = get_service_type (); |
668 | + gateway.label = setting_vpn.get_data_item (get_key_gateway ()); |
669 | + username.label = setting_vpn.get_data_item (get_key_group_username ()); |
670 | + password.label = setting_vpn.get_data_item (get_key_group_password ()); |
671 | + |
672 | + type.visible = type.label != ""; |
673 | + gateway.visible = gateway.label != ""; |
674 | + username.visible = username.label != ""; |
675 | + password.visible = password.label != ""; |
676 | + } |
677 | + } |
678 | +} |
679 | \ No newline at end of file |
680 | |
681 | === added file 'src/Widgets/VPNPage.vala' |
682 | --- src/Widgets/VPNPage.vala 1970-01-01 00:00:00 +0000 |
683 | +++ src/Widgets/VPNPage.vala 2016-07-26 21:06:49 +0000 |
684 | @@ -0,0 +1,327 @@ |
685 | +/*- |
686 | + * Copyright (c) 2015-2016 elementary LLC. |
687 | + * |
688 | + * This program is free software: you can redistribute it and/or modify |
689 | + * it under the terms of the GNU Lesser General Public License as published by |
690 | + * the Free Software Foundation, either version 2.1 of the License, or |
691 | + * (at your option) any later version. |
692 | + * |
693 | + * This program is distributed in the hope that it will be useful, |
694 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
695 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
696 | + * GNU Lesser General Public License for more details. |
697 | + * |
698 | + * You should have received a copy of the GNU Lesser General Public License |
699 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
700 | + * |
701 | + * Authored by: Adam Bieńkowski <donadigos159@gmail.com> |
702 | + */ |
703 | + |
704 | +using Network.Widgets; |
705 | + |
706 | +namespace Network { |
707 | + public class VPNPage : WidgetNMInterface { |
708 | + private DeviceItem owner; |
709 | + private NM.VPNConnection? active_connection = null; |
710 | + private VPNMenuItem? active_vpn_item = null; |
711 | + |
712 | + private Gtk.Frame connected_frame; |
713 | + private Gtk.ListBox vpn_list; |
714 | + private VPNInfoBox vpn_info_box; |
715 | + private VPNMenuItem blank_item; |
716 | + private Gtk.ScrolledWindow scrolled; |
717 | + private Gtk.Box? connected_box = null; |
718 | + private Gtk.Button? disconnect_btn; |
719 | + private Gtk.Button? settings_btn; |
720 | + private Gtk.ToggleButton? info_btn; |
721 | + private Gtk.Revealer top_revealer; |
722 | + private Gtk.Popover popover; |
723 | + |
724 | + public VPNPage (DeviceItem _owner) { |
725 | + owner = _owner; |
726 | + |
727 | + this.init (null); |
728 | + this.title = "Virtual Private Network"; |
729 | + this.icon_name = "network-vpn"; |
730 | + |
731 | + this.spacing = 0; |
732 | + control_box.margin_bottom = 12; |
733 | + |
734 | + vpn_info_box = new VPNInfoBox (); |
735 | + |
736 | + popover = new Gtk.Popover (info_btn); |
737 | + popover.position = Gtk.PositionType.BOTTOM; |
738 | + popover.add (vpn_info_box); |
739 | + popover.hide.connect (() => { |
740 | + info_btn.active = false; |
741 | + }); |
742 | + |
743 | + connected_frame = new Gtk.Frame (null); |
744 | + connected_frame.override_background_color (0, { 255, 255, 255, 255 }); |
745 | + |
746 | + top_revealer = new Gtk.Revealer (); |
747 | + top_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN; |
748 | + top_revealer.add (connected_frame); |
749 | + |
750 | + var no_connections_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); |
751 | + no_connections_box.visible = true; |
752 | + no_connections_box.valign = Gtk.Align.CENTER; |
753 | + |
754 | + var no_connections_label = new Gtk.Label (_("No VPN Connections")); |
755 | + no_connections_label.valign = Gtk.Align.CENTER; |
756 | + no_connections_label.wrap = true; |
757 | + no_connections_label.wrap_mode = Pango.WrapMode.WORD_CHAR; |
758 | + no_connections_label.max_width_chars = 30; |
759 | + no_connections_label.justify = Gtk.Justification.CENTER; |
760 | + no_connections_label.get_style_context ().add_class ("h2"); |
761 | + |
762 | + var second_label = new Gtk.Label (_("Add a new VPN connection to begin.")); |
763 | + second_label.valign = Gtk.Align.CENTER; |
764 | + second_label.wrap = true; |
765 | + second_label.wrap_mode = Pango.WrapMode.WORD_CHAR; |
766 | + second_label.max_width_chars = 30; |
767 | + second_label.justify = Gtk.Justification.CENTER; |
768 | + |
769 | + no_connections_box.add (no_connections_label); |
770 | + no_connections_box.add (second_label); |
771 | + no_connections_box.show_all (); |
772 | + |
773 | + vpn_list = new Gtk.ListBox (); |
774 | + vpn_list.activate_on_single_click = false; |
775 | + vpn_list.visible = true; |
776 | + vpn_list.set_placeholder (no_connections_box); |
777 | + |
778 | + var toolbar = new Gtk.Toolbar (); |
779 | + toolbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR); |
780 | + toolbar.icon_size = Gtk.IconSize.SMALL_TOOLBAR; |
781 | + |
782 | + var add_button = new Gtk.ToolButton (new Gtk.Image.from_icon_name ("list-add-symbolic", Gtk.IconSize.SMALL_TOOLBAR), null); |
783 | + add_button.tooltip_text = _("Add VPN Connection…"); |
784 | + add_button.clicked.connect (() => { |
785 | + add_button.sensitive = false; |
786 | + var command = new Granite.Services.SimpleCommand ("/usr/bin", |
787 | + "nm-connection-editor --create --type=vpn"); |
788 | + command.done.connect ((exit) => { |
789 | + if (exit != 0) { |
790 | + var dialog = new Gtk.MessageDialog (null, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, _("Failed to run Connection Editor.")); |
791 | + dialog.run (); |
792 | + dialog.destroy (); |
793 | + } |
794 | + |
795 | + add_button.sensitive = true; |
796 | + }); |
797 | + |
798 | + command.run (); |
799 | + }); |
800 | + |
801 | + toolbar.add (add_button); |
802 | + |
803 | + blank_item = new VPNMenuItem.blank (); |
804 | + |
805 | + scrolled = new Gtk.ScrolledWindow (null, null); |
806 | + scrolled.expand = true; |
807 | + scrolled.add (vpn_list); |
808 | + |
809 | + var list_root = new Gtk.Grid (); |
810 | + list_root.attach (scrolled, 0, 0, 1, 1); |
811 | + list_root.attach (toolbar, 0, 1, 1, 1); |
812 | + |
813 | + var main_frame = new Gtk.Frame (null); |
814 | + main_frame.margin_bottom = 24; |
815 | + main_frame.margin_top = 12; |
816 | + main_frame.vexpand = true; |
817 | + main_frame.override_background_color (0, { 255, 255, 255, 255 }); |
818 | + main_frame.add (list_root); |
819 | + |
820 | + control_switch.no_show_all = true; |
821 | + control_switch.visible = false; |
822 | + |
823 | + this.add (top_revealer); |
824 | + this.add (main_frame); |
825 | + this.add (bottom_revealer); |
826 | + this.show_all (); |
827 | + |
828 | + client.notify["active-connections"].connect (update_active_connection); |
829 | + update (); |
830 | + } |
831 | + |
832 | + protected override void update () { |
833 | + update_active_connection (); |
834 | + |
835 | + bool sensitive = false; |
836 | + VPNMenuItem? item = null; |
837 | + if (active_connection != null) { |
838 | + switch (active_connection.get_vpn_state ()) { |
839 | + case NM.VPNConnectionState.UNKNOWN: |
840 | + case NM.VPNConnectionState.DISCONNECTED: |
841 | + state = State.DISCONNECTED; |
842 | + break; |
843 | + case NM.VPNConnectionState.PREPARE: |
844 | + case NM.VPNConnectionState.IP_CONFIG_GET: |
845 | + case NM.VPNConnectionState.CONNECT: |
846 | + state = State.CONNECTING_VPN; |
847 | + item = get_item_by_uuid (active_connection.get_uuid ()); |
848 | + item.state = state; |
849 | + break; |
850 | + case NM.VPNConnectionState.FAILED: |
851 | + state = State.FAILED_VPN; |
852 | + break; |
853 | + case NM.VPNConnectionState.ACTIVATED: |
854 | + state = State.CONNECTED_VPN; |
855 | + item = get_item_by_uuid (active_connection.get_uuid ()); |
856 | + item.state = state; |
857 | + sensitive = true; |
858 | + break; |
859 | + } |
860 | + } else { |
861 | + state = State.DISCONNECTED; |
862 | + } |
863 | + |
864 | + if (item == null) { |
865 | + top_revealer.set_reveal_child (false); |
866 | + blank_item.set_active (true); |
867 | + |
868 | + if (active_vpn_item != null) { |
869 | + active_vpn_item.no_show_all = false; |
870 | + active_vpn_item.visible = true; |
871 | + active_vpn_item.state = state; |
872 | + } |
873 | + } else { |
874 | + top_revealer.set_reveal_child (true); |
875 | + if (connected_frame != null && connected_frame.get_child () != null) { |
876 | + connected_frame.get_child ().destroy (); |
877 | + } |
878 | + |
879 | + connected_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); |
880 | + item.no_show_all = true; |
881 | + item.visible = false; |
882 | + |
883 | + var top_item = new VPNMenuItem (item.connection, null); |
884 | + top_item.hide_icons (false); |
885 | + |
886 | + connected_box.add (top_item); |
887 | + |
888 | + disconnect_btn = new Gtk.Button.with_label (_("Disconnect")); |
889 | + disconnect_btn.get_style_context ().add_class ("destructive-action"); |
890 | + disconnect_btn.clicked.connect (vpn_deactivate_cb); |
891 | + |
892 | + settings_btn = new SettingsButton.from_connection (item.connection, _("Settings…")); |
893 | + |
894 | + info_btn = new Gtk.ToggleButton (); |
895 | + info_btn.margin_top = info_btn.margin_bottom = 6; |
896 | + info_btn.get_style_context ().add_class ("flat"); |
897 | + info_btn.image = new Gtk.Image.from_icon_name ("view-more-symbolic", Gtk.IconSize.SMALL_TOOLBAR); |
898 | + |
899 | + vpn_info_box.set_connection (item.connection); |
900 | + |
901 | + popover.relative_to = info_btn; |
902 | + |
903 | + info_btn.toggled.connect (() => { |
904 | + popover.visible = info_btn.get_active (); |
905 | + }); |
906 | + |
907 | + var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); |
908 | + button_box.homogeneous = true; |
909 | + button_box.margin = 6; |
910 | + button_box.pack_end (disconnect_btn, false, false, 0); |
911 | + button_box.pack_end (settings_btn, false, false, 0); |
912 | + button_box.show_all (); |
913 | + |
914 | + connected_box.pack_end (button_box, false, false, 0); |
915 | + connected_box.pack_end (info_btn, false, false, 0); |
916 | + connected_frame.add (connected_box); |
917 | + |
918 | + connected_box.show_all (); |
919 | + connected_frame.show_all (); |
920 | + |
921 | + if (disconnect_btn != null) { |
922 | + disconnect_btn.sensitive = sensitive; |
923 | + } |
924 | + |
925 | + if (settings_btn != null) { |
926 | + settings_btn.sensitive = sensitive; |
927 | + } |
928 | + |
929 | + if (info_btn != null) { |
930 | + info_btn.sensitive = sensitive; |
931 | + } |
932 | + } |
933 | + |
934 | + owner.switch_status (Utils.CustomMode.INVALID, state); |
935 | + update_switch (); |
936 | + } |
937 | + |
938 | + protected override void update_switch () { |
939 | + |
940 | + } |
941 | + |
942 | + protected override void control_switch_activated () { |
943 | + |
944 | + } |
945 | + |
946 | + public void add_connection (NM.RemoteConnection connection) { |
947 | + var item = new VPNMenuItem (connection, get_previous_menu_item ()); |
948 | + item.user_action.connect (vpn_activate_cb); |
949 | + |
950 | + vpn_list.add (item); |
951 | + update (); |
952 | + this.show_all (); |
953 | + } |
954 | + |
955 | + public void remove_connection (NM.RemoteConnection connection) { |
956 | + var item = get_item_by_uuid (connection.get_uuid ()); |
957 | + item.destroy (); |
958 | + } |
959 | + |
960 | + private VPNMenuItem? get_item_by_uuid (string uuid) { |
961 | + VPNMenuItem? item = null; |
962 | + foreach (var child in vpn_list.get_children ()) { |
963 | + var _item = (VPNMenuItem)child; |
964 | + if (_item.connection != null && _item.connection.get_uuid () == uuid && item == null) { |
965 | + item = (VPNMenuItem)child; |
966 | + } |
967 | + } |
968 | + |
969 | + return item; |
970 | + } |
971 | + |
972 | + private VPNMenuItem? get_previous_menu_item () { |
973 | + var children = vpn_list.get_children (); |
974 | + if (children.length () == 0) { |
975 | + return blank_item; |
976 | + } |
977 | + |
978 | + return (VPNMenuItem)children.last ().data; |
979 | + } |
980 | + |
981 | + private void update_active_connection () { |
982 | + active_connection = null; |
983 | + |
984 | + client.get_active_connections ().foreach ((ac) => { |
985 | + if (ac.get_vpn () && active_connection == null) { |
986 | + active_connection = (NM.VPNConnection)ac; |
987 | + active_connection.vpn_state_changed.connect (update); |
988 | + } |
989 | + }); |
990 | + } |
991 | + |
992 | + private void vpn_activate_cb (VPNMenuItem item) { |
993 | + active_vpn_item = item; |
994 | + foreach (var child in vpn_list.get_children ()) { |
995 | + ((VPNMenuItem)child).hide_icons (); |
996 | + } |
997 | + |
998 | + update (); |
999 | + client.activate_connection (item.connection, null, null, null); |
1000 | + } |
1001 | + |
1002 | + private void vpn_deactivate_cb () { |
1003 | + update_active_connection (); |
1004 | + if (active_connection == null) { |
1005 | + return; |
1006 | + } |
1007 | + |
1008 | + client.deactivate_connection (active_connection); |
1009 | + } |
1010 | + } |
1011 | +} |
1012 | \ No newline at end of file |
1013 | |
1014 | === modified file 'src/Widgets/WifiInterface.vala' |
1015 | --- src/Widgets/WifiInterface.vala 2016-07-03 17:45:10 +0000 |
1016 | +++ src/Widgets/WifiInterface.vala 2016-07-26 21:06:49 +0000 |
1017 | @@ -27,16 +27,16 @@ |
1018 | protected Gtk.Box hotspot_mode_box; |
1019 | protected Gtk.Box? connected_box = null; |
1020 | protected Gtk.Revealer top_revealer; |
1021 | - protected Gtk.Button disconnect_btn; |
1022 | - protected Gtk.Button settings_btn; |
1023 | - protected Gtk.Button hidden_btn; |
1024 | + protected Gtk.Button? disconnect_btn; |
1025 | + protected Gtk.Button? settings_btn; |
1026 | + protected Gtk.Button? hidden_btn; |
1027 | protected Gtk.ToggleButton info_btn; |
1028 | protected Gtk.Popover popover; |
1029 | |
1030 | - public WifiInterface (NM.Client nm_client, NM.RemoteSettings settings, NM.Device _device) { |
1031 | - info_box = new InfoBox.from_device (_device); |
1032 | + public WifiInterface (NM.Client nm_client, NM.RemoteSettings settings, NM.Device device) { |
1033 | + this.init (device); |
1034 | + |
1035 | info_box.margin = 12; |
1036 | - this.init (_device, info_box); |
1037 | |
1038 | popover = new Gtk.Popover (info_btn); |
1039 | popover.position = Gtk.PositionType.BOTTOM; |
1040 | @@ -151,9 +151,7 @@ |
1041 | } |
1042 | |
1043 | disconnect_btn = settings_btn = null; |
1044 | - } |
1045 | - |
1046 | - else if (wifi_device.get_active_access_point () != null && active_wifi_item != old_active) { |
1047 | + } else if (wifi_device.get_active_access_point () != null && active_wifi_item != old_active) { |
1048 | |
1049 | if (old_active != null) { |
1050 | old_active.no_show_all = false; |
1051 | @@ -179,7 +177,7 @@ |
1052 | device.disconnect (null); |
1053 | }); |
1054 | |
1055 | - settings_btn = Utils.get_advanced_button_from_device (wifi_device, _("Settings…")); |
1056 | + settings_btn = new SettingsButton.from_device (wifi_device, _("Settings…")); |
1057 | settings_btn.sensitive = (device.get_state () == NM.DeviceState.ACTIVATED); |
1058 | |
1059 | info_btn = new Gtk.ToggleButton (); |
1060 | |
1061 | === modified file 'src/common/Utils.vala' |
1062 | --- src/common/Utils.vala 2016-06-06 21:45:31 +0000 |
1063 | +++ src/common/Utils.vala 2016-07-26 21:06:49 +0000 |
1064 | @@ -19,6 +19,7 @@ |
1065 | DISCONNECTED, |
1066 | WIRED_UNPLUGGED, |
1067 | CONNECTED_WIRED, |
1068 | + CONNECTED_VPN, |
1069 | CONNECTED_WIFI, |
1070 | CONNECTED_WIFI_WEAK, |
1071 | CONNECTED_WIFI_OK, |
1072 | @@ -26,8 +27,10 @@ |
1073 | CONNECTED_WIFI_EXCELLENT, |
1074 | CONNECTING_WIFI, |
1075 | CONNECTING_WIRED, |
1076 | + CONNECTING_VPN, |
1077 | FAILED_WIRED, |
1078 | - FAILED_WIFI |
1079 | + FAILED_WIFI, |
1080 | + FAILED_VPN |
1081 | } |
1082 | |
1083 | namespace Network.Common.Utils { |
1084 | @@ -41,12 +44,15 @@ |
1085 | case Network.State.CONNECTED_WIFI_GOOD: |
1086 | case Network.State.CONNECTED_WIFI_EXCELLENT: |
1087 | case Network.State.CONNECTED_WIRED: |
1088 | + case Network.State.CONNECTED_VPN: |
1089 | return _("Connected"); |
1090 | case Network.State.FAILED_WIRED: |
1091 | case Network.State.FAILED_WIFI: |
1092 | + case Network.State.FAILED_VPN: |
1093 | return _("Failed"); |
1094 | case Network.State.CONNECTING_WIFI: |
1095 | case Network.State.CONNECTING_WIRED: |
1096 | + case Network.State.CONNECTING_VPN: |
1097 | return _("Connecting"); |
1098 | case Network.State.WIRED_UNPLUGGED: |
1099 | return _("Cable unplugged"); |
1100 | |
1101 | === modified file 'src/common/Widgets/AbstractWifiInterface.vala' |
1102 | --- src/common/Widgets/AbstractWifiInterface.vala 2016-02-12 17:40:30 +0000 |
1103 | +++ src/common/Widgets/AbstractWifiInterface.vala 2016-07-26 21:06:49 +0000 |
1104 | @@ -172,7 +172,6 @@ |
1105 | |
1106 | update (); |
1107 | } |
1108 | - |
1109 | } |
1110 | |
1111 | void update_active_ap () { |
1112 | |
1113 | === modified file 'src/common/Widgets/NMVisualizer.vala' |
1114 | --- src/common/Widgets/NMVisualizer.vala 2015-12-19 16:34:47 +0000 |
1115 | +++ src/common/Widgets/NMVisualizer.vala 2016-07-26 21:06:49 +0000 |
1116 | @@ -31,13 +31,15 @@ |
1117 | /* Monitor network manager */ |
1118 | nm_client = new NM.Client (); |
1119 | nm_settings = new NM.RemoteSettings (null); |
1120 | + nm_settings.new_connection.connect (new_connection_cb); |
1121 | |
1122 | nm_client.device_added.connect (device_added_cb); |
1123 | nm_client.device_removed.connect (device_removed_cb); |
1124 | |
1125 | var devices = nm_client.get_devices (); |
1126 | - for (var i = 0; i < devices.length; i++) |
1127 | + for (var i = 0; i < devices.length; i++) { |
1128 | device_added_cb (devices.get (i)); |
1129 | + } |
1130 | |
1131 | show_all(); |
1132 | } |
1133 | @@ -45,6 +47,8 @@ |
1134 | protected abstract void build_ui (); |
1135 | protected abstract void add_interface (WidgetNMInterface widget_interface); |
1136 | protected abstract void remove_interface (WidgetNMInterface widget_interface); |
1137 | + protected abstract void add_connection (NM.RemoteConnection connection); |
1138 | + protected abstract void remove_connection (NM.RemoteConnection connection); |
1139 | |
1140 | void device_removed_cb (NM.Device device) { |
1141 | foreach (var widget_interface in network_interface) { |
1142 | @@ -66,8 +70,7 @@ |
1143 | var type = iface.get_type ().name (); |
1144 | if (count_type.has_key (type)) { |
1145 | count_type[type] = count_type[type] + 1; |
1146 | - } |
1147 | - else { |
1148 | + } else { |
1149 | count_type[type] = 1; |
1150 | } |
1151 | } |
1152 | @@ -78,7 +81,21 @@ |
1153 | } |
1154 | } |
1155 | |
1156 | + void new_connection_cb (Object obj) { |
1157 | + var connection = (NM.RemoteConnection)obj; |
1158 | + connection.removed.connect (() => { |
1159 | + remove_connection (connection); |
1160 | + }); |
1161 | + |
1162 | + add_connection (connection); |
1163 | + } |
1164 | + |
1165 | private void device_added_cb (NM.Device device) { |
1166 | + if (device.get_iface ().has_prefix ("vmnet") || |
1167 | + device.get_iface ().has_prefix ("lo")) { |
1168 | + return; |
1169 | + } |
1170 | + |
1171 | WidgetNMInterface? widget_interface = null; |
1172 | #if PLUG_NETWORK |
1173 | WidgetNMInterface? hotspot_interface = null; |
1174 | @@ -87,7 +104,7 @@ |
1175 | if (device is NM.DeviceWifi) { |
1176 | widget_interface = new WifiInterface (nm_client, nm_settings, device); |
1177 | #if PLUG_NETWORK |
1178 | - hotspot_interface = new HotspotInterface((WifiInterface)widget_interface); |
1179 | + hotspot_interface = new HotspotInterface ((WifiInterface)widget_interface); |
1180 | #endif |
1181 | |
1182 | debug ("Wifi interface added"); |
1183 | @@ -110,22 +127,18 @@ |
1184 | if (hotspot_interface != null) { |
1185 | // Implementation call |
1186 | network_interface.append (hotspot_interface); |
1187 | - add_interface(hotspot_interface); |
1188 | + add_interface (hotspot_interface); |
1189 | hotspot_interface.notify["state"].connect(update_state); |
1190 | - |
1191 | } |
1192 | #endif |
1193 | |
1194 | update_interfaces_names (); |
1195 | - |
1196 | - |
1197 | - update_all(); |
1198 | - |
1199 | - show_all(); |
1200 | + update_all (); |
1201 | + show_all (); |
1202 | } |
1203 | |
1204 | void update_all () { |
1205 | - foreach(var inter in network_interface) { |
1206 | + foreach (var inter in network_interface) { |
1207 | inter.update (); |
1208 | } |
1209 | } |
1210 | @@ -140,5 +153,4 @@ |
1211 | |
1212 | state = next_state; |
1213 | } |
1214 | - |
1215 | } |
1216 | |
1217 | === added file 'src/common/Widgets/VPNMenuItem.vala' |
1218 | --- src/common/Widgets/VPNMenuItem.vala 1970-01-01 00:00:00 +0000 |
1219 | +++ src/common/Widgets/VPNMenuItem.vala 2016-07-26 21:06:49 +0000 |
1220 | @@ -0,0 +1,121 @@ |
1221 | +/* |
1222 | + * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel) |
1223 | + * |
1224 | + * This program is free software: you can redistribute it and/or modify |
1225 | + * it under the terms of the GNU Library General Public License as published by |
1226 | + * the Free Software Foundation, either version 2.1 of the License, or |
1227 | + * (at your option) any later version. |
1228 | + * |
1229 | + * This program is distributed in the hope that it will be useful, |
1230 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1231 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1232 | + * GNU Library General Public License for more details. |
1233 | + * |
1234 | + * You should have received a copy of the GNU Library General Public License |
1235 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1236 | + */ |
1237 | + |
1238 | +public class Network.VPNMenuItem : Gtk.ListBoxRow { |
1239 | + public signal void user_action(); |
1240 | + public NM.RemoteConnection? connection; |
1241 | + |
1242 | + public Network.State state { get; set; default = Network.State.DISCONNECTED; } |
1243 | + |
1244 | + Gtk.RadioButton radio_button; |
1245 | + Gtk.Spinner spinner; |
1246 | + Gtk.Image error_img; |
1247 | + Gtk.Button remove_button; |
1248 | + |
1249 | + public VPNMenuItem (NM.RemoteConnection _connection, VPNMenuItem? previous = null) { |
1250 | + connection = _connection; |
1251 | + |
1252 | + var main_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); |
1253 | + main_box.margin_start = main_box.margin_end = 6; |
1254 | + radio_button = new Gtk.RadioButton(null); |
1255 | + if (previous != null) radio_button.set_group (previous.get_group ()); |
1256 | + |
1257 | + radio_button.button_release_event.connect ( (b, ev) => { |
1258 | + user_action(); |
1259 | + return false; |
1260 | + }); |
1261 | + |
1262 | + error_img = new Gtk.Image.from_icon_name ("process-error-symbolic", Gtk.IconSize.MENU); |
1263 | + error_img.set_tooltip_text (_("This Virtual Private Network could not be connected to.")); |
1264 | + |
1265 | + spinner = new Gtk.Spinner(); |
1266 | + spinner.visible = false; |
1267 | + spinner.no_show_all = !spinner.visible; |
1268 | + |
1269 | + remove_button = new Gtk.Button.from_icon_name ("user-trash-symbolic", Gtk.IconSize.MENU); |
1270 | + remove_button.get_style_context ().add_class ("flat"); |
1271 | + remove_button.clicked.connect (() => { |
1272 | + connection.delete (null); |
1273 | + }); |
1274 | + |
1275 | + main_box.pack_start (radio_button, true, true); |
1276 | + main_box.pack_start (spinner, false, false); |
1277 | + main_box.pack_start (error_img, false, false); |
1278 | + main_box.pack_start (remove_button, false, false); |
1279 | + |
1280 | + notify["state"].connect (update); |
1281 | + radio_button.notify["active"].connect (update); |
1282 | + this.add (main_box); |
1283 | + this.get_style_context ().add_class ("menuitem"); |
1284 | + |
1285 | + connection.changed.connect (update); |
1286 | + update (); |
1287 | + } |
1288 | + |
1289 | + /** |
1290 | + * Only used for an item which is not displayed: hacky way to have no radio button selected. |
1291 | + **/ |
1292 | + public VPNMenuItem.blank () { |
1293 | + radio_button = new Gtk.RadioButton(null); |
1294 | + } |
1295 | + |
1296 | + unowned SList get_group () { |
1297 | + return radio_button.get_group(); |
1298 | + } |
1299 | + |
1300 | + public void set_active (bool active) { |
1301 | + radio_button.set_active (active); |
1302 | + } |
1303 | + |
1304 | + private void update () { |
1305 | + radio_button.label = connection.get_id (); |
1306 | + |
1307 | + switch (state) { |
1308 | + case State.FAILED_VPN: |
1309 | + show_item(error_img); |
1310 | + break; |
1311 | + case State.CONNECTING_VPN: |
1312 | + show_item(spinner); |
1313 | + break; |
1314 | + default: |
1315 | + hide_icons (); |
1316 | + break; |
1317 | + } |
1318 | + } |
1319 | + |
1320 | + public void hide_icons (bool show_remove_button = true) { |
1321 | +#if PLUG_NETWORK |
1322 | + hide_item (error_img); |
1323 | + hide_item (spinner); |
1324 | + |
1325 | + if (!show_remove_button) { |
1326 | + hide_item (remove_button); |
1327 | + } |
1328 | +#endif |
1329 | + } |
1330 | + |
1331 | + void show_item(Gtk.Widget w) { |
1332 | + w.visible = true; |
1333 | + w.no_show_all = !w.visible; |
1334 | + } |
1335 | + |
1336 | + void hide_item(Gtk.Widget w) { |
1337 | + w.visible = false; |
1338 | + w.no_show_all = !w.visible; |
1339 | + w.hide(); |
1340 | + } |
1341 | +} |
1342 | \ No newline at end of file |
1343 | |
1344 | === modified file 'src/common/Widgets/WifiMenuItem.vala' |
1345 | --- src/common/Widgets/WifiMenuItem.vala 2015-08-07 12:58:10 +0000 |
1346 | +++ src/common/Widgets/WifiMenuItem.vala 2016-07-26 21:06:49 +0000 |
1347 | @@ -24,7 +24,7 @@ |
1348 | } |
1349 | } |
1350 | |
1351 | - public Network.State state { get; set; default=Network.State.DISCONNECTED; } |
1352 | + public Network.State state { get; set; default = Network.State.DISCONNECTED; } |
1353 | |
1354 | public uint8 strength { |
1355 | get { |
1356 | @@ -95,6 +95,8 @@ |
1357 | radio_button.notify["active"].connect (update); |
1358 | this.add (main_box); |
1359 | this.get_style_context ().add_class ("menuitem"); |
1360 | + |
1361 | + update (); |
1362 | } |
1363 | |
1364 | /** |
1365 | @@ -168,7 +170,7 @@ |
1366 | show_icons = false; |
1367 | hide_item (error_img); |
1368 | hide_item (lock_img); |
1369 | - hide_item (img_strength); |
1370 | + hide_item (img_strength); |
1371 | #endif |
1372 | } |
1373 | |
1374 | @@ -208,7 +210,5 @@ |
1375 | |
1376 | return _ap.length() > 0; |
1377 | } |
1378 | - |
1379 | - |
1380 | } |
1381 |
I think Corentin had a nicer design for adding and managing VPNs. Maybe we can get him to share his sketches from the snappy sprint in #UX or upload his WIP branch. But the basics were that we followed the design for the Wireless section where you have one section "VPN" and then you manage the connections inside of that section.