Merge lp:~donadigo/switchboard-plug-networking/common-rewrite into lp:~elementary-pantheon/switchboard-plug-networking/trunk

Proposed by Adam Bieńkowski
Status: Needs review
Proposed branch: lp:~donadigo/switchboard-plug-networking/common-rewrite
Merge into: lp:~elementary-pantheon/switchboard-plug-networking/trunk
Diff against target: 5097 lines (+2200/-2108)
35 files modified
src/CMakeLists.txt (+21/-17)
src/Plug.vala (+45/-45)
src/Utils.vala (+0/-251)
src/Widgets/Device/DeviceItem.vala (+37/-28)
src/Widgets/Device/DevicePage.vala (+4/-5)
src/Widgets/DeviceList.vala (+31/-25)
src/Widgets/EthernetView.vala (+11/-8)
src/Widgets/Hotspot/HotspotDialog.vala (+0/-227)
src/Widgets/HotspotView.vala (+38/-50)
src/Widgets/InfoBox.vala (+10/-10)
src/Widgets/Page.vala (+18/-22)
src/Widgets/Proxy/ProxyView.vala (+13/-13)
src/Widgets/VPNView.vala (+29/-42)
src/Widgets/View.vala (+159/-0)
src/Widgets/WiFiView.vala (+38/-116)
src/common/Utils.vala (+0/-63)
src/common/Widgets/AbstractEtherInterface.vala (+0/-77)
src/common/Widgets/AbstractHotspotInterface.vala (+0/-40)
src/common/Widgets/AbstractWifiInterface.vala (+0/-371)
src/common/Widgets/NMVisualizer.vala (+0/-156)
src/common/Widgets/VPNMenuItem.vala (+0/-121)
src/common/Widgets/WidgetNMInterface.vala (+0/-58)
src/common/Widgets/WifiMenuItem.vala (+0/-214)
src/common/rfkill.vala (+0/-149)
src/shared/Abstract/AbstractEthernetView.vala (+71/-0)
src/shared/Abstract/AbstractHotspotView.vala (+45/-0)
src/shared/Abstract/AbstractView.vala (+34/-0)
src/shared/Abstract/AbstractWiFiView.vala (+345/-0)
src/shared/HotspotDialog.vala (+226/-0)
src/shared/PlaceholderLabel.vala (+34/-0)
src/shared/RFKill.vala (+168/-0)
src/shared/Utils.vala (+385/-0)
src/shared/VPNMenuItem.vala (+112/-0)
src/shared/ViewManager.vala (+144/-0)
src/shared/WifiMenuItem.vala (+182/-0)
To merge this branch: bzr merge lp:~donadigo/switchboard-plug-networking/common-rewrite
Reviewer Review Type Date Requested Status
Zisu Andrei (community) Needs Fixing
kay van der Zander (community) Needs Fixing
xapantu Pending
Review via email: mp+302207@code.launchpad.net

Commit message

* Complete common code rewrite.

Description of the change

This is almost a complete rewrite of a "common" code which is a code which is a base for this plug and network indicator.

"Common" code is now named "shared".

The changes are made to the naming of the classes and methods, code style and there are a few additions to the common API itself.

All of the classes that need to be implemented are now in the "shared/Abstract" folder.

Classes are now named "Abstract[DeviceType]View" instead of "Abstract[DeviceType]Interface"
"NMVisualizer" class has been renamed to "ViewManager".

The classes are now inheriting Gtk.Bin instead of hardcoding each widget for the projects.
I moved Hotspot and WiFi utilities to the shared Utils class for easier access from the indicator.

Everything should be working as it worked before, there are no additional features introduced in this branch.

This branch needs extensive testing before it can get merged (at least two reviews for UI / function testing).

Obviously this most probably won't make into Loki since there is so many changes introduced.

To post a comment you must log in.
Revision history for this message
kay van der Zander (kay20) wrote :

see diff comments.

please use smaller functions instead of 40+lines in a update function.

don't duplicade code

anduse proper get set functions instead of those ugly property implementation

review: Needs Fixing
291. By Adam Bieńkowski

Update the branch with suggestions from kay

Revision history for this message
Adam Bieńkowski (donadigo) wrote :

kay20: I did fix some of your issues, but not all of them, because I do not agree with them, and the elementary code-style has changed so:

- We don't use "this" anymore. It's used for the case where you have a property and you want to assign it from the parameter like this:
this.a = a;

- I don't agree there should be white lines between the variable creation and checking it for something, simply because it looks for me better and actually holds the concept that this assignment is now verified.

- I moved the portions of the code to shorter methods, however I still couldn't make them all, because they use a lot of variables they depend on and if I would make them into smaller methods, these would need to have parameters, but I agree into moving the code to smaller methods, this branch isn't just place for this.

Revision history for this message
Zisu Andrei (matzipan) wrote :

Some comments inline.

I'm not familiarised with the network plug, so I'm not aware of all the subtleties but I did not notice anything fundamentally wrong.

Ideally, changes like this should be done in smaller merges in the future.

review: Needs Fixing
Revision history for this message
Zisu Andrei (matzipan) wrote :

There are also some merge commits.

review: Needs Fixing
292. By Adam Bieńkowski

Address issues from Andrei

Revision history for this message
Adam Bieńkowski (donadigo) wrote :

matzipan: I addressed all your issues, except the label styling and unmanaged state of NetworkManager. These should probably be done in a different branch, the code you're seeing is just copied and refactored into more elegant code structure.

Revision history for this message
Zisu Andrei (matzipan) wrote :

Whoops. Meant to say there are some merge conflicts and ended up saying there are some merge commits.

review: Needs Fixing
293. By Adam Bieńkowski

Resolve conflicts and merge trunk

294. By Adam Bieńkowski

Restore, rename, and modify deleted files

Unmerged revisions

294. By Adam Bieńkowski

Restore, rename, and modify deleted files

293. By Adam Bieńkowski

Resolve conflicts and merge trunk

292. By Adam Bieńkowski

Address issues from Andrei

291. By Adam Bieńkowski

Update the branch with suggestions from kay

290. By Adam Bieńkowski

Almost completely rewrite common code

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/CMakeLists.txt'
2--- src/CMakeLists.txt 2016-10-25 13:34:45 +0000
3+++ src/CMakeLists.txt 2016-11-20 19:56:12 +0000
4@@ -10,38 +10,42 @@
5 include (ValaVersion)
6 ensure_vala_version ("0.22.0" MINIMUM)
7
8+set (SHARED_SOURCES
9+ shared/ViewManager.vala
10+ shared/Utils.vala
11+ shared/RFKill.vala
12+ shared/WifiMenuItem.vala
13+ shared/VPNMenuItem.vala
14+ shared/PlaceholderLabel.vala
15+ shared/HotspotDialog.vala
16+ shared/Abstract/AbstractWiFiView.vala
17+ shared/Abstract/AbstractEthernetView.vala
18+ shared/Abstract/AbstractHotspotView.vala
19+ shared/Abstract/AbstractView.vala
20+)
21+
22 include (ValaPrecompile)
23 # Add all your vala files and requires packages to the List below to include them in the build
24 vala_precompile (VALA_C ${CMAKE_PROJECT_NAME}
25 Plug.vala
26- Utils.vala
27 Settings/ProxySettings.vala
28- Widgets/Page.vala
29+ Widgets/View.vala
30 Widgets/DeviceList.vala
31 Widgets/Device/DeviceItem.vala
32 Widgets/Device/DevicePage.vala
33- Widgets/WifiInterface.vala
34- Widgets/EtherInterface.vala
35- Widgets/HotspotInterface.vala
36+ Widgets/WiFiView.vala
37+ Widgets/EthernetView.vala
38+ Widgets/HotspotView.vala
39 Widgets/Proxy/ProxyConfigurationPage.vala
40 Widgets/Proxy/ProxyExceptionsPage.vala
41- Widgets/Proxy/ProxyPage.vala
42+ Widgets/Proxy/ProxyView.vala
43 Widgets/InfoBox.vala
44 Widgets/SettingsButton.vala
45- Widgets/VPNPage.vala
46+ Widgets/VPNView.vala
47 Widgets/VPNInfoBox.vala
48 Widgets/Footer.vala
49 Widgets/InfoScreen.vala
50- Widgets/Hotspot/HotspotDialog.vala
51- common/Utils.vala
52- common/Widgets/WifiMenuItem.vala
53- common/Widgets/VPNMenuItem.vala
54- common/Widgets/AbstractWifiInterface.vala
55- common/Widgets/AbstractEtherInterface.vala
56- common/Widgets/AbstractHotspotInterface.vala
57- common/rfkill.vala
58- common/Widgets/NMVisualizer.vala
59- common/Widgets/WidgetNMInterface.vala
60+ ${SHARED_SOURCES}
61 ${CMAKE_CURRENT_BINARY_DIR}/config.vala
62 PACKAGES
63 gtk+-3.0
64
65=== modified file 'src/Plug.vala'
66--- src/Plug.vala 2016-07-24 22:04:55 +0000
67+++ src/Plug.vala 2016-11-20 19:56:12 +0000
68@@ -33,52 +33,16 @@
69 namespace Network {
70 public static Plug plug;
71
72- public class MainBox : Network.Widgets.NMVisualizer {
73+ public class Widgets.MainBox : ViewManager {
74 private NM.Device current_device = null;
75 private Gtk.Stack content;
76 private Gtk.ScrolledWindow scrolled_window;
77- private WidgetNMInterface page;
78+ private AbstractView page;
79 private Widgets.DeviceList device_list;
80 private Widgets.Footer footer;
81 private Widgets.InfoScreen no_devices;
82
83- protected override void add_interface (WidgetNMInterface widget_interface) {
84- device_list.add_iface_to_list (widget_interface);
85-
86- select_first ();
87- show_all ();
88- }
89-
90- protected override void remove_interface (WidgetNMInterface widget_interface) {
91- device_list.remove_iface_from_list (widget_interface);
92-
93- if (content.get_visible_child () == widget_interface) {
94- var row = device_list.get_selected_row ();
95- int index = device_list.get_selected_row ().get_index ();
96- if (row != null && row.get_index () >= 0) {
97- device_list.get_row_at_index (index).activate ();
98- } else {
99- select_first ();
100- }
101- }
102-
103- content.remove (widget_interface);
104- show_all ();
105- }
106-
107- protected override void add_connection (NM.RemoteConnection connection) {
108- device_list.add_connection (connection);
109- }
110-
111- protected override void remove_connection (NM.RemoteConnection connection) {
112- device_list.remove_connection (connection);
113- }
114-
115- private void select_first () {
116- device_list.select_first_item ();
117- }
118-
119- protected override void build_ui () {
120+ construct {
121 var paned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL);
122 paned.width_request = 250;
123
124@@ -116,10 +80,46 @@
125
126 connect_signals ();
127
128- var main_grid = new Gtk.Grid ();
129- main_grid.add (paned);
130- main_grid.show_all ();
131- add (main_grid);
132+ add (paned);
133+ show_all ();
134+
135+ populate ();
136+ }
137+
138+ protected override void add_view (AbstractView view) {
139+ device_list.add_view_to_list (view);
140+
141+ select_first ();
142+ show_all ();
143+ }
144+
145+ protected override void remove_view (AbstractView view) {
146+ device_list.remove_view_from_list (view);
147+
148+ if (content.get_visible_child () == view) {
149+ var row = device_list.get_selected_row ();
150+ int index = device_list.get_selected_row ().get_index ();
151+ if (row != null && row.get_index () >= 0) {
152+ device_list.get_row_at_index (index).activate ();
153+ } else {
154+ select_first ();
155+ }
156+ }
157+
158+ content.remove (view);
159+ show_all ();
160+ }
161+
162+ protected override void add_connection (NM.RemoteConnection connection) {
163+ device_list.add_connection (connection);
164+ }
165+
166+ protected override void remove_connection (NM.RemoteConnection connection) {
167+ device_list.remove_connection (connection);
168+ }
169+
170+ private void select_first () {
171+ device_list.select_first_item ();
172 }
173
174 /* Main function to connect all the signals */
175@@ -156,7 +156,7 @@
176 }
177
178 public class Plug : Switchboard.Plug {
179- MainBox? main_box = null;
180+ Widgets.MainBox? main_box = null;
181 public Plug () {
182 Object (category: Category.NETWORK,
183 code_name: Build.PLUGCODENAME,
184@@ -168,7 +168,7 @@
185
186 public override Gtk.Widget get_widget () {
187 if (main_box == null) {
188- main_box = new MainBox ();
189+ main_box = new Widgets.MainBox ();
190 }
191
192 return main_box;
193
194=== removed file 'src/Utils.vala'
195--- src/Utils.vala 2016-07-21 22:42:00 +0000
196+++ src/Utils.vala 1970-01-01 00:00:00 +0000
197@@ -1,251 +0,0 @@
198-/*-
199- * Copyright (c) 2015-2016 elementary LLC.
200- *
201- * This program is free software: you can redistribute it and/or modify
202- * it under the terms of the GNU Lesser General Public License as published by
203- * the Free Software Foundation, either version 2.1 of the License, or
204- * (at your option) any later version.
205- *
206- * This program is distributed in the hope that it will be useful,
207- * but WITHOUT ANY WARRANTY; without even the implied warranty of
208- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
209- * GNU Lesser General Public License for more details.
210- *
211- * You should have received a copy of the GNU Lesser General Public License
212- * along with this program. If not, see <http://www.gnu.org/licenses/>.
213- *
214- * Authored by: Adam Bieńkowski <donadigos159@gmail.com>
215- */
216-
217-namespace Network {
218- public const string UNKNOWN_STR = (_("Unknown"));
219-
220- public class Utils {
221- public class Hotspot {
222- public delegate void UpdateSecretCallback ();
223-
224- public static void activate_hotspot (NM.DeviceWifi wifi_device,
225- ByteArray ssid,
226- string key,
227- NM.Connection? selected) {
228- if (selected != null) {
229- client.activate_connection (selected, wifi_device, null, null);
230- return;
231- }
232-
233- var hotspot_c = new NM.Connection ();
234-
235- var setting_connection = new NM.SettingConnection ();
236- setting_connection.@set (NM.SettingConnection.TYPE, "802-11-wireless");
237- setting_connection.@set (NM.SettingConnection.ID, "Hotspot");
238- setting_connection.autoconnect = false;
239- hotspot_c.add_setting (setting_connection);
240-
241- var setting_wireless = new NM.SettingWireless ();
242-
243- string? mode = null;
244- var caps = wifi_device.get_capabilities ();
245- if ((caps & NM.DeviceWifiCapabilities.AP) != 0) {
246- mode = NM.SettingWireless.MODE_AP;
247- } else {
248- mode = NM.SettingWireless.MODE_ADHOC;
249- }
250-
251- setting_wireless.mode = mode;
252- setting_wireless.security = "802-11-wireless-security";
253-
254- hotspot_c.add_setting (setting_wireless);
255-
256- var ip4_setting = new NM.SettingIP4Config ();
257- ip4_setting.method = "shared";
258- hotspot_c.add_setting (ip4_setting);
259-
260- setting_wireless.@set (NM.SettingWireless.SSID, ssid);
261-
262- var setting_wireless_security = new NM.SettingWirelessSecurity ();
263-
264- if (mode == NM.SettingWireless.MODE_AP) {
265- if ((caps & NM.DeviceWifiCapabilities.RSN) != 0) {
266- set_wpa_key (setting_wireless_security, key);
267- setting_wireless_security.add_proto ("rsn");
268- setting_wireless_security.add_pairwise ("ccmp");
269- setting_wireless_security.add_group ("ccmp");
270- } else if ((caps & NM.DeviceWifiCapabilities.WPA) != 0) {
271- set_wpa_key (setting_wireless_security, key);
272- setting_wireless_security.add_proto ("wpa");
273- setting_wireless_security.add_pairwise ("tkip");
274- setting_wireless_security.add_group ("tkip");
275- } else {
276- set_wep_key (setting_wireless_security, key);
277- }
278- } else {
279- set_wep_key (setting_wireless_security, key);
280- }
281-
282- hotspot_c.add_setting (setting_wireless_security);
283- client.add_and_activate_connection (hotspot_c,
284- wifi_device,
285- null,
286- finish_connection_cb);
287- }
288-
289- public static void update_secrets (NM.RemoteConnection connection, UpdateSecretCallback callback) {
290- connection.get_secrets (connection.get_setting_wireless ().get_security (), ((_connection, secrets, error) => {
291- var setting_wireless = _connection.get_setting_wireless ();
292- try {
293- _connection.update_secrets (setting_wireless.get_security (), secrets);
294- } catch (Error e) {
295- warning ("%s\n", e.message);
296- return;
297- }
298-
299- callback ();
300- }));
301- }
302-
303- public static void deactivate_hotspot (NM.DeviceWifi wifi_device) {
304- client.get_active_connections ().@foreach ((active_connection) => {
305- var devices = active_connection.get_devices ();
306- if (devices != null && devices.@get (0) == wifi_device) {
307- client.deactivate_connection (active_connection);
308- }
309- });
310- }
311-
312- private static void set_wpa_key (NM.SettingWirelessSecurity setting, string key) {
313- setting.key_mgmt = "wpa-psk";
314- setting.psk = key;
315- }
316-
317- private static void set_wep_key (NM.SettingWirelessSecurity setting, string key) {
318- setting.key_mgmt = "none";
319- setting.wep_key0 = key;
320- setting.wep_key_type = NM.WepKeyType.PASSPHRASE;
321- }
322-
323- public static bool get_device_is_hotspot (NM.DeviceWifi wifi_device, NM.RemoteSettings nm_settings) {
324- if (wifi_device.get_active_connection () != null) {
325- var connection = nm_settings.get_connection_by_path (wifi_device.get_active_connection ().get_connection ());
326- if (connection != null) {
327- var ip4_setting = connection.get_setting_ip4_config ();
328- return (ip4_setting != null && ip4_setting.get_method () == "shared");
329- }
330- }
331-
332- return false;
333- }
334-
335- public static bool get_connection_is_hotspot (NM.Connection connection) {
336- var setting_connection = connection.get_setting_connection ();
337- if (setting_connection.get_connection_type () != "802-11-wireless") {
338- return false;
339- }
340-
341- var setting_wireless = connection.get_setting_wireless ();
342- if (setting_wireless.get_mode () != "adhoc"
343- && setting_wireless.get_mode () != "ap") {
344- return false;
345- }
346-
347- if (setting_wireless.get_security () != "802-11-wireless-security") {
348- return false;
349- }
350-
351- var ip4_config = connection.get_setting_ip4_config ();
352- if (ip4_config.get_method () != "shared") {
353- return false;
354- }
355-
356- return true;
357- }
358-
359- private static void finish_connection_cb (NM.Client? cb_client,
360- NM.ActiveConnection? cb_connection,
361- string? new_connection_path,
362- Error? error) {
363- if (error != null && error.code != 0) {
364- warning ("%s\n", error.message);
365- }
366- }
367- }
368-
369- public enum CustomMode {
370- PROXY_NONE = 0,
371- PROXY_MANUAL,
372- PROXY_AUTO,
373- HOTSPOT_ENABLED,
374- HOTSPOT_DISABLED,
375- INVALID
376- }
377-
378- public enum ItemType {
379- DEVICE = 0,
380- VIRTUAL,
381- INVALID
382- }
383-
384- public static string state_to_string (NM.DeviceState state) {
385- switch (state) {
386- case NM.DeviceState.ACTIVATED:
387- return _("Connected");
388- case NM.DeviceState.DISCONNECTED:
389- return _("Disconnected");
390- case NM.DeviceState.UNMANAGED:
391- return _("Unmanaged");
392- case NM.DeviceState.PREPARE:
393- return _("In preparation");
394- case NM.DeviceState.CONFIG:
395- return _("Connecting…");
396- case NM.DeviceState.NEED_AUTH:
397- return _("Requires more information");
398- case NM.DeviceState.IP_CONFIG:
399- return _("Requesting adresses...");
400- case NM.DeviceState.IP_CHECK:
401- return _("Checking connection...");
402- case NM.DeviceState.SECONDARIES:
403- return _("Waiting for connection...");
404- case NM.DeviceState.DEACTIVATING:
405- return _("Disconnecting...");
406- case NM.DeviceState.FAILED:
407- return _("Failed to connect");
408- case NM.DeviceState.UNKNOWN:
409- default:
410- return UNKNOWN_STR;
411- }
412- }
413-
414- public static string type_to_string (NM.DeviceType type) {
415- switch (type) {
416- case NM.DeviceType.ETHERNET:
417- return _("Ethernet");
418- case NM.DeviceType.WIFI:
419- return _("Wi-Fi");
420- case NM.DeviceType.UNUSED1:
421- return _("Not used");
422- case NM.DeviceType.UNUSED2:
423- return _("Not used");
424- case NM.DeviceType.BT:
425- return _("Bluetooth");
426- case NM.DeviceType.OLPC_MESH:
427- return _("OLPC XO");
428- case NM.DeviceType.WIMAX:
429- return _("WiMAX Broadband");
430- case NM.DeviceType.MODEM:
431- return _("Modem");
432- case NM.DeviceType.INFINIBAND:
433- return _("InfiniBand device");
434- case NM.DeviceType.BOND:
435- return _("Bond master");
436- case NM.DeviceType.VLAN:
437- return _("VLAN Interface");
438- case NM.DeviceType.ADSL:
439- return _("ADSL Modem");
440- case NM.DeviceType.BRIDGE:
441- return _("Bridge master");
442- case NM.DeviceType.UNKNOWN:
443- default:
444- return UNKNOWN_STR;
445- }
446- }
447- }
448-}
449
450=== modified file 'src/Widgets/Device/DeviceItem.vala'
451--- src/Widgets/Device/DeviceItem.vala 2016-07-26 21:04:29 +0000
452+++ src/Widgets/Device/DeviceItem.vala 2016-11-20 19:56:12 +0000
453@@ -18,11 +18,20 @@
454 */
455
456 namespace Network.Widgets {
457+ public enum CustomMode {
458+ PROXY_NONE = 0,
459+ PROXY_MANUAL,
460+ PROXY_AUTO,
461+ HOTSPOT_ENABLED,
462+ HOTSPOT_DISABLED,
463+ INVALID
464+ }
465+
466 public class DeviceItem : Gtk.ListBoxRow {
467 public NM.Device? device = null;
468 private NM.RemoteSettings? nm_settings = null;
469 public Gtk.Widget? page = null;
470- public Utils.ItemType type;
471+ public ItemType type;
472
473 public Gtk.Label row_description;
474 private Gtk.Image row_image;
475@@ -43,35 +52,35 @@
476 public DeviceItem (string _title, string _subtitle, string _icon_name = "network-wired") {
477 this.subtitle = _subtitle;
478 this.icon_name = _icon_name;
479- this.type = Utils.ItemType.INVALID;
480+ this.type = ItemType.INVALID;
481
482 create_ui (icon_name);
483
484 this.title = _title;
485 }
486
487- public DeviceItem.from_interface (WidgetNMInterface iface,
488+ public DeviceItem.from_view (AbstractView view,
489 string _icon_name = "network-wired",
490 string _title = "") {
491- this.page = iface;
492- this.device = iface.device;
493- this.type = Utils.ItemType.DEVICE;
494+ this.page = view;
495+ this.device = view.get_device ();
496+ this.type = ItemType.DEVICE;
497
498 this.subtitle = "";
499 this.icon_name = _icon_name;
500
501 create_ui (icon_name);
502- iface.bind_property ("display-title", this, "title");
503+ view.bind_property ("display-title", this, "title");
504
505- switch_status (Utils.CustomMode.INVALID, iface.state);
506+ switch_status (CustomMode.INVALID, view.state);
507
508 nm_settings = new NM.RemoteSettings (null);
509 nm_settings.connections_read.connect (() => {
510- switch_status (Utils.CustomMode.INVALID, iface.state);
511+ switch_status (CustomMode.INVALID, view.state);
512 });
513
514- iface.notify["state"].connect (() => {
515- switch_status (Utils.CustomMode.INVALID, iface.state);
516+ view.notify["state"].connect (() => {
517+ switch_status (CustomMode.INVALID, view.state);
518 });
519 }
520
521@@ -125,24 +134,24 @@
522 return icon_name;
523 }
524
525- public void switch_status (Utils.CustomMode custom_mode, Network.State? state = null) {
526+ public void switch_status (CustomMode custom_mode, Network.Utils.State? state = null) {
527 if (state != null) {
528 switch (state) {
529- case Network.State.CONNECTED_WIFI:
530- case Network.State.CONNECTED_WIFI_WEAK:
531- case Network.State.CONNECTED_WIFI_OK:
532- case Network.State.CONNECTED_WIFI_GOOD:
533- case Network.State.CONNECTED_WIFI_EXCELLENT:
534- case Network.State.CONNECTED_WIRED:
535- case Network.State.CONNECTED_VPN:
536+ case Network.Utils.State.CONNECTED_WIFI:
537+ case Network.Utils.State.CONNECTED_WIFI_WEAK:
538+ case Network.Utils.State.CONNECTED_WIFI_OK:
539+ case Network.Utils.State.CONNECTED_WIFI_GOOD:
540+ case Network.Utils.State.CONNECTED_WIFI_EXCELLENT:
541+ case Network.Utils.State.CONNECTED_WIRED:
542+ case Network.Utils.State.CONNECTED_VPN:
543 status_image.icon_name = "user-available";
544 break;
545- case Network.State.DISCONNECTED:
546+ case Network.Utils.State.DISCONNECTED:
547 status_image.icon_name = "user-offline";
548 break;
549- case Network.State.FAILED_WIRED:
550- case Network.State.FAILED_WIFI:
551- case Network.State.FAILED_VPN:
552+ case Network.Utils.State.FAILED_WIRED:
553+ case Network.Utils.State.FAILED_WIFI:
554+ case Network.Utils.State.FAILED_VPN:
555 status_image.icon_name = "user-busy";
556 break;
557 default:
558@@ -150,18 +159,18 @@
559 break;
560 }
561
562- row_description.label = Common.Utils.network_state_to_string (state);
563- } else if (custom_mode != Utils.CustomMode.INVALID) {
564+ row_description.label = state.to_localized_string ();
565+ } else if (custom_mode != CustomMode.INVALID) {
566 switch (custom_mode) {
567- case Utils.CustomMode.PROXY_NONE:
568+ case CustomMode.PROXY_NONE:
569 row_description.label = _("Disabled");
570 status_image.icon_name = "user-offline";
571 break;
572- case Utils.CustomMode.PROXY_MANUAL:
573+ case CustomMode.PROXY_MANUAL:
574 row_description.label = _("Enabled (manual mode)");
575 status_image.icon_name = "user-available";
576 break;
577- case Utils.CustomMode.PROXY_AUTO:
578+ case CustomMode.PROXY_AUTO:
579 row_description.label = _("Enabled (auto mode)");
580 status_image.icon_name = "user-available";
581 break;
582
583=== modified file 'src/Widgets/Device/DevicePage.vala'
584--- src/Widgets/Device/DevicePage.vala 2016-07-29 19:49:28 +0000
585+++ src/Widgets/Device/DevicePage.vala 2016-11-20 19:56:12 +0000
586@@ -18,15 +18,14 @@
587 */
588
589 namespace Network.Widgets {
590- public class DevicePage : WidgetNMInterface {
591-
592+ public class DevicePage : View {
593 public DevicePage (NM.Client client, NM.RemoteSettings settings, NM.Device device) {
594 this.init (device);
595
596 bottom_revealer.transition_type = Gtk.RevealerTransitionType.NONE;
597
598- this.icon_name = "network-wired";
599- display_title = Utils.type_to_string (device.get_device_type ());
600+ icon_name = "network-wired";
601+ display_title = Network.Utils.device_type_to_string (device.get_device_type ());
602
603 var details_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
604 details_box.pack_end (new SettingsButton.from_device (device), false, false, 0);
605@@ -44,7 +43,7 @@
606 this.init (owner.get_item_device ());
607
608 this.icon_name = owner.get_item_icon_name ();
609- display_title = Utils.type_to_string (device.get_device_type ());
610+ display_title = Network.Utils.device_type_to_string (device.get_device_type ());
611
612 var details_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
613 details_box.pack_start (new SettingsButton.from_device (device), false, false, 0);
614
615=== modified file 'src/Widgets/DeviceList.vala'
616--- src/Widgets/DeviceList.vala 2016-07-26 21:04:29 +0000
617+++ src/Widgets/DeviceList.vala 2016-11-20 19:56:12 +0000
618@@ -18,6 +18,12 @@
619 */
620
621 namespace Network.Widgets {
622+ public enum ItemType {
623+ DEVICE = 0,
624+ VIRTUAL,
625+ INVALID
626+ }
627+
628 public class DeviceList : Gtk.ListBox {
629 public signal void show_no_devices (bool show);
630
631@@ -46,18 +52,18 @@
632 this.add_vpn ();
633 }
634
635- public void add_iface_to_list (WidgetNMInterface iface) {
636+ public void add_view_to_list (AbstractView iface) {
637 DeviceItem item;
638- if (iface is AbstractWifiInterface) {
639- item = new DeviceItem.from_interface (iface, "network-wireless");
640- } else if (iface is AbstractHotspotInterface) {
641- item = new DeviceItem.from_interface (iface, "network-wireless-hotspot");
642- item.type = Utils.ItemType.VIRTUAL;
643+ if (iface is AbstractWiFiView) {
644+ item = new DeviceItem.from_view (iface, "network-wireless");
645+ } else if (iface is AbstractHotspotView) {
646+ item = new DeviceItem.from_view (iface, "network-wireless-hotspot");
647+ item.type = ItemType.VIRTUAL;
648 } else {
649- if (iface.device.get_iface ().has_prefix ("usb")) {
650- item = new DeviceItem.from_interface (iface, "drive-removable-media");
651+ if (iface.get_device ().get_iface ().has_prefix ("usb")) {
652+ item = new DeviceItem.from_view (iface, "drive-removable-media");
653 } else {
654- item = new DeviceItem.from_interface (iface);
655+ item = new DeviceItem.from_view (iface);
656 }
657 }
658
659@@ -65,7 +71,7 @@
660 show_all ();
661 }
662
663- public void remove_iface_from_list (WidgetNMInterface iface) {
664+ public void remove_view_from_list (AbstractView iface) {
665 foreach (Gtk.Widget _list_item in get_children ()) {
666 var list_item = (DeviceItem)_list_item;
667 if (list_item.page == iface) {
668@@ -77,7 +83,7 @@
669 public void add_connection (NM.RemoteConnection connection) {
670 switch (connection.get_connection_type ()) {
671 case NM.SettingVpn.SETTING_NAME:
672- ((VPNPage)vpn.page).add_connection (connection);
673+ ((VPNView)vpn.page).add_connection (connection);
674 break;
675 default:
676 break;
677@@ -87,7 +93,7 @@
678 public void remove_connection (NM.RemoteConnection connection) {
679 switch (connection.get_connection_type ()) {
680 case NM.SettingVpn.SETTING_NAME:
681- ((VPNPage)vpn.page).remove_connection (connection);
682+ ((VPNView)vpn.page).remove_connection (connection);
683 break;
684 default:
685 break;
686@@ -101,16 +107,16 @@
687
688 private void add_proxy () {
689 proxy = new DeviceItem (_("Proxy"), "", "preferences-system-network");
690- proxy.page = new ProxyPage (proxy);
691- proxy.type = Utils.ItemType.VIRTUAL;
692+ proxy.page = new ProxyView (proxy);
693+ proxy.type = ItemType.VIRTUAL;
694
695 this.add (proxy);
696 }
697
698 private void add_vpn () {
699 vpn = new DeviceItem (_("VPN"), "", "network-vpn");
700- vpn.page = new VPNPage (vpn);
701- vpn.type = Utils.ItemType.VIRTUAL;
702+ vpn.page = new VPNView (vpn);
703+ vpn.type = ItemType.VIRTUAL;
704
705 this.add (vpn);
706 }
707@@ -120,9 +126,9 @@
708 }
709
710 private int sort_items (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) {
711- if (((DeviceItem) row1).type == Utils.ItemType.DEVICE) {
712+ if (((DeviceItem) row1).type == ItemType.DEVICE) {
713 return -1;
714- } else if (((DeviceItem) row1).type == Utils.ItemType.VIRTUAL) {
715+ } else if (((DeviceItem) row1).type == ItemType.VIRTUAL) {
716 return 1;
717 } else {
718 return 0;
719@@ -130,26 +136,26 @@
720 }
721
722 private void update_headers (Gtk.ListBoxRow row, Gtk.ListBoxRow? before = null) {
723- if (((DeviceItem) row).type == Utils.ItemType.VIRTUAL) {
724- if (before != null && ((DeviceItem) before).type == Utils.ItemType.VIRTUAL) {
725+ if (((DeviceItem) row).type == ItemType.VIRTUAL) {
726+ if (before != null && ((DeviceItem) before).type == ItemType.VIRTUAL) {
727 return;
728 }
729
730- remove_headers_for_type (Utils.ItemType.VIRTUAL);
731+ remove_headers_for_type (ItemType.VIRTUAL);
732 row.set_header (virtual_l);
733- } else if (((DeviceItem) row).type == Utils.ItemType.DEVICE) {
734- if (before != null && ((DeviceItem) before).type == Utils.ItemType.DEVICE) {
735+ } else if (((DeviceItem) row).type == ItemType.DEVICE) {
736+ if (before != null && ((DeviceItem) before).type == ItemType.DEVICE) {
737 return;
738 }
739
740- remove_headers_for_type (Utils.ItemType.DEVICE);
741+ remove_headers_for_type (ItemType.DEVICE);
742 row.set_header (devices_l);
743 } else {
744 row.set_header (null);
745 }
746 }
747
748- private void remove_headers_for_type (Utils.ItemType type) {
749+ private void remove_headers_for_type (ItemType type) {
750 foreach (Gtk.Widget _item in get_children ()) {
751 var item = (DeviceItem)_item;
752 if (item.type == type) {
753
754=== renamed file 'src/Widgets/EtherInterface.vala' => 'src/Widgets/EthernetView.vala'
755--- src/Widgets/EtherInterface.vala 2016-08-09 12:41:03 +0000
756+++ src/Widgets/EthernetView.vala 2016-11-20 19:56:12 +0000
757@@ -18,25 +18,28 @@
758 */
759
760 namespace Network.Widgets {
761- public class EtherInterface : AbstractEtherInterface {
762+ public class EthernetView : AbstractEthernetView {
763 private Gtk.Revealer top_revealer;
764
765- public EtherInterface (NM.Client client, NM.RemoteSettings settings, NM.Device device) {
766- this.init (device);
767+ public EthernetView (NM.Client client, NM.RemoteSettings settings, NM.Device device) {
768+ init (device);
769
770 info_box.halign = Gtk.Align.CENTER;
771
772- this.icon_name = "network-wired";
773+ icon_name = "network-wired";
774
775 top_revealer = new Gtk.Revealer ();
776 top_revealer.valign = Gtk.Align.START;
777 top_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN;
778 top_revealer.add (info_box);
779
780- bottom_box.pack_start (new SettingsButton.from_device (device), false, false, 0);
781-
782- add (top_revealer);
783- add (bottom_revealer);
784+ var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
785+ button_box.pack_end (new SettingsButton.from_device (device), false, false, 0);
786+
787+ bottom_box.add (button_box);
788+
789+ container.add (top_revealer);
790+ container.add (bottom_revealer);
791 show_all ();
792
793 update ();
794
795=== removed directory 'src/Widgets/Hotspot'
796=== removed file 'src/Widgets/Hotspot/HotspotDialog.vala'
797--- src/Widgets/Hotspot/HotspotDialog.vala 2016-02-12 15:09:30 +0000
798+++ src/Widgets/Hotspot/HotspotDialog.vala 1970-01-01 00:00:00 +0000
799@@ -1,227 +0,0 @@
800-/*-
801- * Copyright (c) 2015-2016 elementary LLC.
802- *
803- * This program is free software: you can redistribute it and/or modify
804- * it under the terms of the GNU Lesser General Public License as published by
805- * the Free Software Foundation, either version 2.1 of the License, or
806- * (at your option) any later version.
807- *
808- * This program is distributed in the hope that it will be useful,
809- * but WITHOUT ANY WARRANTY; without even the implied warranty of
810- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
811- * GNU Lesser General Public License for more details.
812- *
813- * You should have received a copy of the GNU Lesser General Public License
814- * along with this program. If not, see <http://www.gnu.org/licenses/>.
815- *
816- * Authored by: Adam Bieńkowski <donadigos159@gmail.com>
817- */
818-
819-namespace Network.Widgets {
820- public class HotspotDialog : Gtk.Dialog {
821- private const string NEW_ID = "0";
822- private Gtk.Entry ssid_entry;
823- private Gtk.Entry key_entry;
824-
825- private Gtk.Label ssid_label;
826- private Gtk.Label key_label;
827-
828- private Gtk.ComboBoxText conn_combo;
829-
830- private Gtk.CheckButton check_btn;
831- private Gtk.Label dumb;
832-
833- private Gtk.Button create_btn;
834-
835- private HashTable<string, NM.Connection> conn_hash;
836- private unowned List<NM.Connection> available;
837-
838- public HotspotDialog (NM.AccessPoint? active, List<NM.Connection> _available) {
839- this.available = _available;
840- this.deletable = false;
841- this.resizable = false;
842- this.border_width = 6;
843-
844- conn_hash = new HashTable<string, NM.Connection> (str_hash, str_equal);
845-
846- var content_area = this.get_content_area ();
847- content_area.halign = content_area.valign = Gtk.Align.CENTER;
848-
849- var main_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
850- var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
851-
852- vbox.margin_left = vbox.margin_right = 6;
853-
854- string? ssid_str = null;
855- if (active != null) {
856- ssid_str = NM.Utils.ssid_to_utf8 (active.get_ssid ());
857- } else {
858- ssid_str = _("current");
859- }
860-
861- var title = new Gtk.Label ("<span weight='bold' size='larger'>" + _("Wireless Hotspot") + "</span>");
862- title.use_markup = true;
863- title.halign = Gtk.Align.START;
864-
865- var image = new Gtk.Image.from_icon_name ("network-wireless-hotspot", Gtk.IconSize.DIALOG);
866- image.valign = Gtk.Align.START;
867- main_box.add (image);
868-
869- var info_label = new Gtk.Label (_("Enabling Wireless Hotspot will disconnect from %s network.").printf (ssid_str) + "\n" +
870- _("You will not be able to connect to a wireless network while Hotspot is active."));
871- info_label.halign = Gtk.Align.START;
872- info_label.margin_top = 6;
873- info_label.use_markup = true;
874-
875- var grid = new Gtk.Grid ();
876- grid.hexpand = true;
877- grid.row_spacing = 6;
878- grid.column_spacing = 12;
879- grid.vexpand_set = true;
880-
881- ssid_entry = new Gtk.Entry ();
882- ssid_entry.hexpand = true;
883- ssid_entry.text = get_ssid_for_hotspot ();
884-
885- key_entry = new Gtk.Entry ();
886- key_entry.hexpand = true;
887- key_entry.visibility = false;
888- key_entry.secondary_icon_tooltip_text = _("Password needs to be at least 8 characters long.");
889-
890- check_btn = new Gtk.CheckButton.with_label (_("Show Password"));
891- check_btn.toggled.connect (() => {
892- key_entry.visibility = check_btn.active;
893- });
894-
895- ssid_entry.changed.connect (update);
896- key_entry.changed.connect (update);
897-
898- ssid_label = new Gtk.Label (_("Network Name:"));
899- ssid_label.halign = Gtk.Align.END;
900-
901- key_label = new Gtk.Label (_("Password:"));
902- key_label.halign = Gtk.Align.END;
903-
904- conn_combo = new Gtk.ComboBoxText ();
905- conn_combo.append (NEW_ID, _("New…"));
906- int i = 1;
907- foreach (var connection in available) {
908- var setting_wireless = connection.get_setting_wireless ();
909- conn_combo.append (i.to_string (), NM.Utils.ssid_to_utf8 (setting_wireless.get_ssid ()));
910- conn_hash.insert (i.to_string (), connection);
911- i++;
912- }
913-
914- conn_combo.active_id = NEW_ID;
915- conn_combo.changed.connect (update);
916-
917- var conn_label = new Gtk.Label (_("Connection:"));
918- conn_label.halign = Gtk.Align.END;
919-
920- grid.attach (conn_label, 0, 0, 1, 1);
921- grid.attach_next_to (conn_combo, conn_label, Gtk.PositionType.RIGHT, 1, 1);
922-
923- dumb = new Gtk.Label ("");
924-
925- grid.attach_next_to (ssid_label, conn_label, Gtk.PositionType.BOTTOM, 1, 1);
926- grid.attach_next_to (ssid_entry, ssid_label, Gtk.PositionType.RIGHT, 1, 1);
927- grid.attach_next_to (key_label, ssid_label, Gtk.PositionType.BOTTOM, 1, 1);
928- grid.attach_next_to (key_entry, key_label, Gtk.PositionType.RIGHT, 1, 1);
929- grid.attach_next_to (dumb, key_label, Gtk.PositionType.BOTTOM, 1, 1);
930- grid.attach_next_to (check_btn, dumb, Gtk.PositionType.RIGHT, 1, 1);
931-
932- var cancel_btn = new Gtk.Button.with_label (_("Cancel"));
933- create_btn = new Gtk.Button.with_label (_("Enable Hotspot"));
934- if (active != null) {
935- create_btn.label = _("Switch to Hotspot");
936- }
937-
938- create_btn.get_style_context ().add_class ("suggested-action");
939-
940- this.add_action_widget (cancel_btn, 0);
941- this.add_action_widget (create_btn, 1);
942-
943- vbox.add (title);
944- vbox.add (info_label);
945- vbox.add (grid);
946-
947- update ();
948-
949- main_box.add (vbox);
950- content_area.add (main_box);
951- this.show_all ();
952- }
953-
954- public ByteArray get_ssid () {
955- var byte_array = new ByteArray ();
956- byte_array.append (ssid_entry.get_text ().data);
957- return byte_array;
958- }
959-
960- public string get_key () {
961- return key_entry.get_text ();
962- }
963-
964- public NM.Connection? get_selected_connection () {
965- return conn_hash[conn_combo.get_active_id ()];
966- }
967-
968- private string get_ssid_for_hotspot () {
969- string hostname = "";
970- try {
971- Process.spawn_command_line_sync ("hostname", out hostname, null, null);
972- } catch (SpawnError e) {
973- warning ("%s\n", e.message);
974- }
975-
976- return hostname.strip ().replace ("\n", "");
977- }
978-
979- private void update () {
980- bool sensitive = (conn_combo.get_active_id () == NEW_ID);
981- ssid_label.sensitive = sensitive;
982- key_label.sensitive = sensitive;
983-
984- ssid_entry.sensitive = sensitive;
985- key_entry.sensitive = sensitive;
986-
987- check_btn.sensitive = sensitive;
988- dumb.sensitive = sensitive;
989-
990- string? secret = null;
991- if (get_selected_connection () != null) {
992- var setting_wireless_security = get_selected_connection ().get_setting_wireless_security ();
993-
994- string key_mgmt = setting_wireless_security.get_key_mgmt ();
995- if (key_mgmt == "none") {
996- secret = setting_wireless_security.get_wep_key (0);
997- } else if (key_mgmt == "wpa-psk" ||
998- key_mgmt == "wpa-none") {
999- secret = setting_wireless_security.get_psk ();
1000- }
1001-
1002- if (secret == null) {
1003- var connection = get_selected_connection ();
1004- Utils.Hotspot.update_secrets (((NM.RemoteConnection) connection), update);
1005- }
1006- }
1007-
1008- if (conn_combo.get_active_id () != NEW_ID) {
1009- ssid_entry.text = NM.Utils.ssid_to_utf8 (get_selected_connection ().get_setting_wireless ().get_ssid ());
1010- if (secret == null) {
1011- secret = "";
1012- }
1013-
1014- key_entry.text = secret;
1015- }
1016-
1017- create_btn.sensitive = ((ssid_entry.get_text () != "" && key_entry.get_text ().to_utf8 ().length >= 8) || !sensitive);
1018-
1019- if (key_entry.get_text ().to_utf8 ().length < 8 && key_entry.get_text () != "") {
1020- key_entry.set_icon_from_icon_name (Gtk.EntryIconPosition.SECONDARY, "process-error-symbolic");
1021- } else {
1022- key_entry.set_icon_from_icon_name (Gtk.EntryIconPosition.SECONDARY, "");
1023- }
1024- }
1025- }
1026-}
1027\ No newline at end of file
1028
1029=== renamed file 'src/Widgets/HotspotInterface.vala' => 'src/Widgets/HotspotView.vala'
1030--- src/Widgets/HotspotInterface.vala 2016-07-29 19:49:28 +0000
1031+++ src/Widgets/HotspotView.vala 2016-11-20 19:56:12 +0000
1032@@ -18,21 +18,21 @@
1033 */
1034
1035 namespace Network.Widgets {
1036- public class HotspotInterface : Network.AbstractHotspotInterface {
1037-
1038- private NM.RemoteSettings nm_settings;
1039+ public class HotspotView : AbstractHotspotView {
1040 private Gtk.Revealer hotspot_revealer;
1041 private Gtk.Button hotspot_settings_btn;
1042 private Gtk.Label ssid_label;
1043 private Gtk.Label key_label;
1044 private bool switch_updating = false;
1045
1046- public HotspotInterface (WifiInterface _root_iface) {
1047- root_iface = _root_iface;
1048- nm_settings = _root_iface.get_nm_settings ();
1049- this.init (root_iface.device);
1050-
1051- this.icon_name = "network-wireless-hotspot";
1052+ public HotspotView (NM.Client client, NM.RemoteSettings settings, NM.Device device) {
1053+ this.client = client;
1054+ this.settings = settings;
1055+ this.device = device;
1056+
1057+ init (device);
1058+
1059+ icon_name = "network-wireless-hotspot";
1060
1061 hotspot_revealer = new Gtk.Revealer ();
1062 hotspot_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN;
1063@@ -57,19 +57,19 @@
1064 button_box.pack_end (hotspot_settings_btn, false, false, 0);
1065 bottom_revealer.add (button_box);
1066
1067- nm_settings.connections_read.connect (update);
1068+ settings.connections_read.connect (update);
1069 device.state_changed.connect (update);
1070
1071 update ();
1072
1073- this.add (hotspot_revealer);
1074- this.add (bottom_revealer);
1075- this.show_all ();
1076+ container.add (hotspot_revealer);
1077+ container.add (bottom_revealer);
1078+ show_all ();
1079 }
1080
1081 protected override void update () {
1082 if (hotspot_settings_btn != null) {
1083- hotspot_settings_btn.sensitive = Utils.Hotspot.get_device_is_hotspot (root_iface.wifi_device, root_iface.nm_settings);
1084+ hotspot_settings_btn.sensitive = Utils.Hotspot.get_device_is_hotspot (wifi_device, settings);
1085 }
1086
1087 update_hotspot_info ();
1088@@ -79,7 +79,7 @@
1089
1090 protected override void update_switch () {
1091 switch_updating = true;
1092- control_switch.active = state == Network.State.CONNECTED_WIFI;
1093+ control_switch.active = state == Network.Utils.State.CONNECTED_WIFI;
1094 switch_updating = false;
1095 }
1096
1097@@ -89,42 +89,43 @@
1098 return;
1099 }
1100
1101- var wifi_device = (NM.DeviceWifi)device;
1102- if (!control_switch.active && Utils.Hotspot.get_device_is_hotspot (wifi_device, nm_settings)) {
1103+ if (!control_switch.active) {
1104 Utils.Hotspot.deactivate_hotspot (wifi_device);
1105 } else {
1106- var hotspot_dialog = new HotspotDialog (wifi_device.get_active_access_point (), get_hotspot_connections ());
1107- hotspot_dialog.response.connect ((response) => {
1108- if (response == 1) {
1109- Utils.Hotspot.activate_hotspot (wifi_device,
1110- hotspot_dialog.get_ssid (),
1111- hotspot_dialog.get_key (),
1112- hotspot_dialog.get_selected_connection ());
1113-
1114- } else {
1115- switch_updating = true;
1116- control_switch.active = false;
1117- }
1118- });
1119+ var hotspot_dialog = new HotspotDialog (wifi_device.get_active_access_point (), Utils.Hotspot.get_hotspot_connections (settings));
1120+ hotspot_dialog.response.connect (on_hotspot_dialog_response);
1121
1122 hotspot_dialog.run ();
1123 hotspot_dialog.destroy ();
1124 }
1125 }
1126
1127+ private void on_hotspot_dialog_response (Gtk.Dialog dialog, int response) {
1128+ var hotspot_dialog = (HotspotDialog)dialog;
1129+ if (response == 1) {
1130+ Utils.Hotspot.activate_hotspot (wifi_device,
1131+ hotspot_dialog.get_ssid (),
1132+ hotspot_dialog.get_key (),
1133+ hotspot_dialog.get_selected_connection ());
1134+
1135+ } else {
1136+ switch_updating = true;
1137+ control_switch.active = false;
1138+ }
1139+ }
1140+
1141 private void update_hotspot_info () {
1142- var wifi_device = (NM.DeviceWifi)device;
1143- bool hotspot_mode = Utils.Hotspot.get_device_is_hotspot (wifi_device, nm_settings);
1144+ bool hotspot_mode = Utils.Hotspot.get_device_is_hotspot (wifi_device, settings);
1145
1146- var mode = Utils.CustomMode.HOTSPOT_DISABLED;
1147+ var mode = CustomMode.HOTSPOT_DISABLED;
1148 if (hotspot_mode) {
1149- mode = Utils.CustomMode.HOTSPOT_ENABLED;
1150+ mode = CustomMode.HOTSPOT_ENABLED;
1151 }
1152
1153 hotspot_revealer.set_reveal_child (hotspot_mode);
1154
1155 if (hotspot_mode) {
1156- var connection = nm_settings.get_connection_by_path (wifi_device.get_active_connection ().get_connection ());
1157+ var connection = settings.get_connection_by_path (wifi_device.get_active_connection ().get_connection ());
1158
1159 var setting_wireless = connection.get_setting_wireless ();
1160 ssid_label.label = _("Network Name (SSID): %s").printf (NM.Utils.ssid_to_utf8 (setting_wireless.get_ssid ()));
1161@@ -134,11 +135,11 @@
1162 string key_mgmt = setting_wireless_security.get_key_mgmt ();
1163 string? secret = null;
1164 string security = "";
1165+
1166 if (key_mgmt == "none") {
1167 secret = setting_wireless_security.get_wep_key (0);
1168 security = _("(WEP)");
1169- } else if (key_mgmt == "wpa-psk" ||
1170- key_mgmt == "wpa-none") {
1171+ } else if (key_mgmt == "wpa-psk" || key_mgmt == "wpa-none") {
1172 security = _("(WPA)");
1173 secret = setting_wireless_security.get_psk ();
1174 }
1175@@ -151,18 +152,5 @@
1176 key_label.label = _("Password %s: %s").printf (security, secret);
1177 }
1178 }
1179-
1180- private List<NM.Connection> get_hotspot_connections () {
1181- var list = new List<NM.Connection> ();
1182- var connections = nm_settings.list_connections ();
1183-
1184- foreach (var connection in connections) {
1185- if (Utils.Hotspot.get_connection_is_hotspot (connection)) {
1186- list.append (connection);
1187- }
1188- }
1189-
1190- return list;
1191- }
1192 }
1193 }
1194
1195=== modified file 'src/Widgets/InfoBox.vala'
1196--- src/Widgets/InfoBox.vala 2016-07-19 08:28:38 +0000
1197+++ src/Widgets/InfoBox.vala 2016-11-20 19:56:12 +0000
1198@@ -142,23 +142,23 @@
1199 }
1200
1201 public void update_activity (string sent_bytes, string received_bytes) {
1202- sent.label = sent_bytes ?? UNKNOWN_STR;
1203- received.label = received_bytes ?? UNKNOWN_STR;
1204+ sent.label = sent_bytes ?? Network.Utils.UNKNOWN_STR;
1205+ received.label = received_bytes ?? Network.Utils.UNKNOWN_STR;
1206 }
1207
1208 public void update_status () {
1209 // Refresh DHCP4 info
1210 var dhcp4 = device.get_dhcp4_config ();
1211 if (dhcp4 != null) {
1212- ip4address.label = (dhcp4.get_one_option ("ip_address") ?? UNKNOWN_STR);
1213- mask.label = (dhcp4.get_one_option ("subnet_mask") ?? UNKNOWN_STR);
1214- router.label = (dhcp4.get_one_option ("routers") ?? UNKNOWN_STR);
1215- broadcast.label = (dhcp4.get_one_option ("broadcast_address") ?? UNKNOWN_STR);
1216+ ip4address.label = (dhcp4.get_one_option ("ip_address") ?? Network.Utils.UNKNOWN_STR);
1217+ mask.label = (dhcp4.get_one_option ("subnet_mask") ?? Network.Utils.UNKNOWN_STR);
1218+ router.label = (dhcp4.get_one_option ("routers") ?? Network.Utils.UNKNOWN_STR);
1219+ broadcast.label = (dhcp4.get_one_option ("broadcast_address") ?? Network.Utils.UNKNOWN_STR);
1220 } else {
1221- ip4address.label = UNKNOWN_STR;
1222- mask.label = UNKNOWN_STR;
1223- router.label = UNKNOWN_STR;
1224- broadcast.label = UNKNOWN_STR;
1225+ ip4address.label = Network.Utils.UNKNOWN_STR;
1226+ mask.label = Network.Utils.UNKNOWN_STR;
1227+ router.label = Network.Utils.UNKNOWN_STR;
1228+ broadcast.label = Network.Utils.UNKNOWN_STR;
1229 }
1230
1231 var ip6 = device.get_ip6_config ();
1232
1233=== modified file 'src/Widgets/Page.vala'
1234--- src/Widgets/Page.vala 2016-08-09 12:41:03 +0000
1235+++ src/Widgets/Page.vala 2016-11-20 19:56:12 +0000
1236@@ -19,8 +19,9 @@
1237 */
1238
1239 namespace Network.Widgets {
1240- public class Page : Gtk.Grid {
1241- public NM.Device device;
1242+ public class View : AbstractView {
1243+ protected Gtk.Grid container;
1244+
1245 public InfoBox info_box;
1246 public Gtk.Switch control_switch;
1247 public Gtk.Grid control_box;
1248@@ -38,28 +39,18 @@
1249 }
1250 }
1251
1252- private string _title;
1253- public string title {
1254- get {
1255- return _title;
1256- }
1257-
1258- set {
1259- _title = value;
1260- device_label.label = value;
1261- }
1262- }
1263-
1264 private Gtk.Image device_img;
1265 protected Gtk.Label device_label;
1266
1267 protected Gtk.Revealer bottom_revealer;
1268 protected Gtk.Box bottom_box;
1269
1270- public Page () {
1271+ construct {
1272 margin = 24;
1273- orientation = Gtk.Orientation.VERTICAL;
1274- row_spacing = 24;
1275+
1276+ container = new Gtk.Grid ();
1277+ container.orientation = Gtk.Orientation.VERTICAL;
1278+ container.row_spacing = 24;
1279
1280 bottom_revealer = new Gtk.Revealer ();
1281 bottom_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_UP;
1282@@ -68,6 +59,7 @@
1283 bottom_box.pack_start (new SettingsButton (), false, false, 0);
1284
1285 bottom_revealer.add (bottom_box);
1286+ add (container);
1287 }
1288
1289 public void init (NM.Device? _device) {
1290@@ -76,12 +68,16 @@
1291 device_img = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DIALOG);
1292 device_img.pixel_size = 48;
1293
1294- device_label = new Gtk.Label (null);
1295+ device_label = new Gtk.Label (display_title);
1296 device_label.ellipsize = Pango.EllipsizeMode.MIDDLE;
1297 device_label.get_style_context ().add_class ("h2");
1298 device_label.hexpand = true;
1299 device_label.xalign = 0;
1300
1301+ notify["display-title"].connect (() => {
1302+ device_label.label = display_title;
1303+ });
1304+
1305 control_switch = new Gtk.Switch ();
1306 control_switch.valign = Gtk.Align.CENTER;
1307 update_switch ();
1308@@ -94,7 +90,7 @@
1309 info_box.vexpand = true;
1310 info_box.info_changed.connect (update);
1311
1312- title = Utils.type_to_string (device.get_device_type ());
1313+ display_title = Network.Utils.device_type_to_string (device.get_device_type ());
1314 }
1315
1316 control_box = new Gtk.Grid ();
1317@@ -103,7 +99,7 @@
1318 control_box.add (device_label);
1319 control_box.add (control_switch);
1320
1321- add (control_box);
1322+ container.add (control_box);
1323 show_all ();
1324 }
1325
1326@@ -139,8 +135,8 @@
1327 }
1328
1329 public void get_activity_information (string iface, out string sent_bytes, out string received_bytes) {
1330- sent_bytes = UNKNOWN_STR;
1331- received_bytes = UNKNOWN_STR;
1332+ sent_bytes = Network.Utils.UNKNOWN_STR;
1333+ received_bytes = Network.Utils.UNKNOWN_STR;
1334
1335 string tx_bytes_path = "/sys/class/net/" + iface + "/statistics/tx_bytes";
1336 string rx_bytes_path = "/sys/class/net/" + iface + "/statistics/rx_bytes";
1337
1338=== renamed file 'src/Widgets/Proxy/ProxyPage.vala' => 'src/Widgets/Proxy/ProxyView.vala'
1339--- src/Widgets/Proxy/ProxyPage.vala 2016-07-29 21:08:04 +0000
1340+++ src/Widgets/Proxy/ProxyView.vala 2016-11-20 19:56:12 +0000
1341@@ -18,21 +18,21 @@
1342 */
1343
1344 namespace Network.Widgets {
1345- public class ProxyPage : Page {
1346+ public class ProxyView : View {
1347 public Gtk.Stack stack;
1348 public signal void update_status_label (string mode);
1349
1350 private DeviceItem owner;
1351
1352- public ProxyPage (DeviceItem _owner) {
1353- owner = _owner;
1354+ public ProxyView (DeviceItem owner) {
1355+ this.owner = owner;
1356
1357 init (null);
1358- title = _("Proxy");
1359+ display_title = _("Proxy");
1360 icon_name = "preferences-system-network";
1361
1362- column_spacing = 12;
1363- row_spacing = 12;
1364+ container.column_spacing = 12;
1365+ container.row_spacing = 12;
1366 margin = 24;
1367 margin_bottom = 12;
1368
1369@@ -53,8 +53,8 @@
1370 proxy_settings.changed.connect (update_mode);
1371 update_mode ();
1372
1373- add (stackswitcher);
1374- add (stack);
1375+ container.add (stackswitcher);
1376+ container.add (stack);
1377
1378 show_all ();
1379
1380@@ -71,22 +71,22 @@
1381 }
1382
1383 private void update_mode () {
1384- var mode = Utils.CustomMode.INVALID;
1385+ var mode = CustomMode.INVALID;
1386 switch (proxy_settings.mode) {
1387 case "none":
1388- mode = Utils.CustomMode.PROXY_NONE;
1389+ mode = CustomMode.PROXY_NONE;
1390 control_switch.active = false;
1391 break;
1392 case "manual":
1393- mode = Utils.CustomMode.PROXY_MANUAL;
1394+ mode = CustomMode.PROXY_MANUAL;
1395 control_switch.active = true;
1396 break;
1397 case "auto":
1398- mode = Utils.CustomMode.PROXY_AUTO;
1399+ mode = CustomMode.PROXY_AUTO;
1400 control_switch.active = true;
1401 break;
1402 default:
1403- mode = Utils.CustomMode.INVALID;
1404+ mode = CustomMode.INVALID;
1405 break;
1406 }
1407
1408
1409=== renamed file 'src/Widgets/VPNPage.vala' => 'src/Widgets/VPNView.vala'
1410--- src/Widgets/VPNPage.vala 2016-08-09 12:41:03 +0000
1411+++ src/Widgets/VPNView.vala 2016-11-20 19:56:12 +0000
1412@@ -17,10 +17,8 @@
1413 * Authored by: Adam Bieńkowski <donadigos159@gmail.com>
1414 */
1415
1416-using Network.Widgets;
1417-
1418-namespace Network {
1419- public class VPNPage : WidgetNMInterface {
1420+namespace Network.Widgets {
1421+ public class VPNView : View {
1422 private DeviceItem owner;
1423 private NM.VPNConnection? active_connection = null;
1424 private VPNMenuItem? active_vpn_item = null;
1425@@ -37,14 +35,14 @@
1426 private Gtk.Revealer top_revealer;
1427 private Gtk.Popover popover;
1428
1429- public VPNPage (DeviceItem _owner) {
1430- owner = _owner;
1431-
1432- this.init (null);
1433- this.title = _("Virtual Private Network");
1434- this.icon_name = "network-vpn";
1435-
1436- row_spacing = 0;
1437+ public VPNView (DeviceItem owner) {
1438+ this.owner = owner;
1439+
1440+ init (null);
1441+ display_title = _("Virtual Private Network");
1442+ icon_name = "network-vpn";
1443+
1444+ container.row_spacing = 0;
1445 control_box.margin_bottom = 12;
1446
1447 vpn_info_box = new VPNInfoBox ();
1448@@ -68,23 +66,12 @@
1449 no_connections_box.visible = true;
1450 no_connections_box.valign = Gtk.Align.CENTER;
1451
1452- var no_connections_label = new Gtk.Label (_("No VPN Connections"));
1453- no_connections_label.valign = Gtk.Align.CENTER;
1454- no_connections_label.wrap = true;
1455- no_connections_label.wrap_mode = Pango.WrapMode.WORD_CHAR;
1456- no_connections_label.max_width_chars = 30;
1457- no_connections_label.justify = Gtk.Justification.CENTER;
1458- no_connections_label.get_style_context ().add_class ("h2");
1459+ var no_connections_label = new PlaceholderLabel (_("No VPN Connections"), true);
1460
1461- var second_label = new Gtk.Label (_("Add a new VPN connection to begin."));
1462- second_label.valign = Gtk.Align.CENTER;
1463- second_label.wrap = true;
1464- second_label.wrap_mode = Pango.WrapMode.WORD_CHAR;
1465- second_label.max_width_chars = 30;
1466- second_label.justify = Gtk.Justification.CENTER;
1467+ var add_connections_label = new PlaceholderLabel (_("Add a new VPN connection to begin."), false);
1468
1469 no_connections_box.add (no_connections_label);
1470- no_connections_box.add (second_label);
1471+ no_connections_box.add (add_connections_label);
1472 no_connections_box.show_all ();
1473
1474 vpn_list = new Gtk.ListBox ();
1475@@ -100,8 +87,7 @@
1476 add_button.tooltip_text = _("Add VPN Connection…");
1477 add_button.clicked.connect (() => {
1478 add_button.sensitive = false;
1479- var command = new Granite.Services.SimpleCommand ("/usr/bin",
1480- "nm-connection-editor --create --type=vpn");
1481+ var command = new Granite.Services.SimpleCommand ("/usr/bin", "nm-connection-editor --create --type=vpn");
1482 command.done.connect ((exit) => {
1483 if (exit != 0) {
1484 var dialog = new Gtk.MessageDialog (null, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, "%s", _("Failed to run Connection Editor."));
1485@@ -137,12 +123,10 @@
1486 control_switch.no_show_all = true;
1487 control_switch.visible = false;
1488
1489- bottom_revealer.set_reveal_child (true);
1490-
1491- this.add (top_revealer);
1492- this.add (main_frame);
1493- this.add (bottom_revealer);
1494- this.show_all ();
1495+ container.add (top_revealer);
1496+ container.add (main_frame);
1497+ container.add (bottom_revealer);
1498+ show_all ();
1499
1500 client.notify["active-connections"].connect (update_active_connection);
1501 update ();
1502@@ -157,25 +141,25 @@
1503 switch (active_connection.get_vpn_state ()) {
1504 case NM.VPNConnectionState.UNKNOWN:
1505 case NM.VPNConnectionState.DISCONNECTED:
1506- state = State.DISCONNECTED;
1507+ state = Network.Utils.State.DISCONNECTED;
1508 break;
1509 case NM.VPNConnectionState.PREPARE:
1510 case NM.VPNConnectionState.IP_CONFIG_GET:
1511 case NM.VPNConnectionState.CONNECT:
1512- state = State.CONNECTING_VPN;
1513+ state = Network.Utils.State.CONNECTING_VPN;
1514 item = get_item_by_uuid (active_connection.get_uuid ());
1515 break;
1516 case NM.VPNConnectionState.FAILED:
1517- state = State.FAILED_VPN;
1518+ state = Network.Utils.State.FAILED_VPN;
1519 break;
1520 case NM.VPNConnectionState.ACTIVATED:
1521- state = State.CONNECTED_VPN;
1522+ state = Network.Utils.State.CONNECTED_VPN;
1523 item = get_item_by_uuid (active_connection.get_uuid ());
1524 sensitive = true;
1525 break;
1526 }
1527 } else {
1528- state = State.DISCONNECTED;
1529+ state = Network.Utils.State.DISCONNECTED;
1530 }
1531
1532 if (disconnect_btn != null) {
1533@@ -254,7 +238,7 @@
1534 connected_frame.show_all ();
1535 }
1536
1537- owner.switch_status (Utils.CustomMode.INVALID, state);
1538+ owner.switch_status (CustomMode.INVALID, state);
1539 update_switch ();
1540 }
1541
1542@@ -268,11 +252,11 @@
1543
1544 public void add_connection (NM.RemoteConnection connection) {
1545 var item = new VPNMenuItem (connection, get_previous_menu_item ());
1546- item.user_action.connect (vpn_activate_cb);
1547+ item.activated.connect (vpn_activate_cb);
1548
1549 vpn_list.add (item);
1550 update ();
1551- this.show_all ();
1552+ show_all ();
1553 }
1554
1555 public void remove_connection (NM.RemoteConnection connection) {
1556@@ -282,6 +266,7 @@
1557
1558 private VPNMenuItem? get_item_by_uuid (string uuid) {
1559 VPNMenuItem? item = null;
1560+
1561 foreach (var child in vpn_list.get_children ()) {
1562 var _item = (VPNMenuItem)child;
1563 if (_item.connection != null && _item.connection.get_uuid () == uuid && item == null) {
1564@@ -294,6 +279,7 @@
1565
1566 private VPNMenuItem? get_previous_menu_item () {
1567 var children = vpn_list.get_children ();
1568+
1569 if (children.length () == 0) {
1570 return blank_item;
1571 }
1572@@ -314,6 +300,7 @@
1573
1574 private void vpn_activate_cb (VPNMenuItem item) {
1575 active_vpn_item = item;
1576+
1577 foreach (var child in vpn_list.get_children ()) {
1578 ((VPNMenuItem)child).hide_icons ();
1579 }
1580
1581=== added file 'src/Widgets/View.vala'
1582--- src/Widgets/View.vala 1970-01-01 00:00:00 +0000
1583+++ src/Widgets/View.vala 2016-11-20 19:56:12 +0000
1584@@ -0,0 +1,159 @@
1585+/*-
1586+ * Copyright (c) 2015-2016 elementary LLC.
1587+ *
1588+ * This program is free software: you can redistribute it and/or modify
1589+ * it under the terms of the GNU Lesser General Public License as published by
1590+ * the Free Software Foundation, either version 2.1 of the License, or
1591+ * (at your option) any later version.
1592+ *
1593+ * This program is distributed in the hope that it will be useful,
1594+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1595+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1596+ * GNU Lesser General Public License for more details.
1597+ *
1598+ * You should have received a copy of the GNU Lesser General Public License
1599+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1600+ *
1601+ * Authored by: Adam Bieńkowski <donadigos159@gmail.com>
1602+ * xapantu
1603+ */
1604+
1605+namespace Network.Widgets {
1606+ public class View : AbstractView {
1607+ protected Gtk.Grid container;
1608+
1609+ public InfoBox info_box;
1610+ public Gtk.Switch control_switch;
1611+ public Gtk.Grid control_box;
1612+ public signal void show_error ();
1613+
1614+ private string _icon_name;
1615+ public string icon_name {
1616+ get {
1617+ return _icon_name;
1618+ }
1619+
1620+ set {
1621+ _icon_name = value;
1622+ device_img.icon_name = value;
1623+ }
1624+ }
1625+
1626+ private Gtk.Image device_img;
1627+ protected Gtk.Label device_label;
1628+
1629+ protected Gtk.Revealer bottom_revealer;
1630+ protected Gtk.Box bottom_box;
1631+
1632+ construct {
1633+ margin = 24;
1634+
1635+ container = new Gtk.Grid ();
1636+ container.orientation = Gtk.Orientation.VERTICAL;
1637+ container.row_spacing = 24;
1638+
1639+ bottom_revealer = new Gtk.Revealer ();
1640+ bottom_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_UP;
1641+ bottom_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12);
1642+
1643+ bottom_revealer.add (bottom_box);
1644+ add (container);
1645+ }
1646+
1647+ public void init (NM.Device? _device) {
1648+ this.device = _device;
1649+
1650+ device_img = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DIALOG);
1651+ device_img.pixel_size = 48;
1652+
1653+ device_label = new Gtk.Label (display_title);
1654+ device_label.ellipsize = Pango.EllipsizeMode.MIDDLE;
1655+ device_label.get_style_context ().add_class ("h2");
1656+ device_label.hexpand = true;
1657+ device_label.xalign = 0;
1658+
1659+ notify["display-title"].connect (() => {
1660+ device_label.label = display_title;
1661+ });
1662+
1663+ control_switch = new Gtk.Switch ();
1664+ control_switch.valign = Gtk.Align.CENTER;
1665+ update_switch ();
1666+
1667+ control_switch.notify["active"].connect (control_switch_activated);
1668+
1669+ if (device != null) {
1670+ this.info_box = new InfoBox.from_device (device);
1671+ info_box.margin_end = 16;
1672+ info_box.vexpand = true;
1673+ info_box.info_changed.connect (update);
1674+
1675+ display_title = Network.Utils.device_type_to_string (device.get_device_type ());
1676+ }
1677+
1678+ control_box = new Gtk.Grid ();
1679+ control_box.column_spacing = 12;
1680+ control_box.add (device_img);
1681+ control_box.add (device_label);
1682+ control_box.add (control_switch);
1683+
1684+ container.add (control_box);
1685+ show_all ();
1686+ }
1687+
1688+ public override void update () {
1689+ if (info_box != null) {
1690+ string sent_bytes, received_bytes;
1691+ this.get_activity_information (device.get_iface (), out sent_bytes, out received_bytes);
1692+ info_box.update_activity (sent_bytes, received_bytes);
1693+ }
1694+
1695+ update_switch ();
1696+
1697+ bottom_revealer.set_reveal_child (control_switch.active);
1698+ }
1699+
1700+ protected virtual void update_switch () {
1701+ control_switch.active = device.get_state () != NM.DeviceState.DISCONNECTED && device.get_state () != NM.DeviceState.DEACTIVATING;
1702+ }
1703+
1704+ protected virtual void control_switch_activated () {
1705+ if (!control_switch.active && device.get_state () == NM.DeviceState.ACTIVATED) {
1706+ device.disconnect (null);
1707+ } else if (control_switch.active && device.get_state () == NM.DeviceState.DISCONNECTED) {
1708+ var connection = new NM.Connection ();
1709+ var remote_array = device.get_available_connections ();
1710+ if (remote_array == null) {
1711+ this.show_error ();
1712+ } else {
1713+ connection.path = remote_array.get (0).get_path ();
1714+ client.activate_connection (connection, device, null, null);
1715+ }
1716+ }
1717+ }
1718+
1719+ public void get_activity_information (string iface, out string sent_bytes, out string received_bytes) {
1720+ sent_bytes = Network.Utils.UNKNOWN_STR;
1721+ received_bytes = Network.Utils.UNKNOWN_STR;
1722+
1723+ string tx_bytes_path = "/sys/class/net/" + iface + "/statistics/tx_bytes";
1724+ string rx_bytes_path = "/sys/class/net/" + iface + "/statistics/rx_bytes";
1725+
1726+ if (!File.new_for_path (tx_bytes_path).query_exists () || !File.new_for_path (rx_bytes_path).query_exists ()) {
1727+ return;
1728+ }
1729+
1730+ try {
1731+ string tx_bytes, rx_bytes;
1732+
1733+ FileUtils.get_contents (tx_bytes_path, out tx_bytes);
1734+ FileUtils.get_contents (rx_bytes_path, out rx_bytes);
1735+
1736+ sent_bytes = format_size (uint64.parse (tx_bytes));
1737+ received_bytes = format_size (uint64.parse (rx_bytes));
1738+ } catch (FileError e) {
1739+ error ("%s\n", e.message);
1740+ }
1741+ }
1742+ }
1743+}
1744
1745=== renamed file 'src/Widgets/WifiInterface.vala' => 'src/Widgets/WiFiView.vala'
1746--- src/Widgets/WifiInterface.vala 2016-08-09 12:41:03 +0000
1747+++ src/Widgets/WiFiView.vala 2016-11-20 19:56:12 +0000
1748@@ -17,10 +17,8 @@
1749 * Authored by: Adam Bieńkowski <donadigos159@gmail.com>
1750 */
1751
1752-using Network.Widgets;
1753-
1754-namespace Network {
1755- public class WifiInterface : AbstractWifiInterface {
1756+namespace Network.Widgets {
1757+ public class WiFiView : AbstractWiFiView {
1758 protected Gtk.Frame connected_frame;
1759 protected Gtk.Stack list_stack;
1760 protected Gtk.ScrolledWindow scrolled;
1761@@ -33,8 +31,12 @@
1762 protected Gtk.ToggleButton info_btn;
1763 protected Gtk.Popover popover;
1764
1765- public WifiInterface (NM.Client nm_client, NM.RemoteSettings settings, NM.Device device) {
1766- this.init (device);
1767+ public WiFiView (NM.Client client, NM.RemoteSettings settings, NM.Device device) {
1768+ this.client = client;
1769+ this.settings = settings;
1770+ this.device = device;
1771+
1772+ init (device);
1773
1774 info_box.margin = 12;
1775
1776@@ -51,11 +53,9 @@
1777 top_revealer = new Gtk.Revealer ();
1778 top_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN;
1779 top_revealer.add (connected_frame);
1780-
1781- init_wifi_interface (nm_client, settings, device);
1782
1783- this.icon_name = "network-wireless";
1784- row_spacing = 0;
1785+ icon_name = "network-wireless";
1786+ container.row_spacing = 0;
1787
1788 control_box.margin_bottom = 12;
1789
1790@@ -71,8 +71,8 @@
1791 main_frame.vexpand = true;
1792 main_frame.override_background_color (0, { 255, 255, 255, 255 });
1793
1794- var hotspot_mode = construct_placeholder_label (_("This device is in Hotspot Mode"), true);
1795- var hotspot_mode_desc = construct_placeholder_label (_("Turn off the Hotspot Mode to connect to other Access Points."), false);
1796+ var hotspot_mode = new PlaceholderLabel (_("This device is in Hotspot Mode"), true);
1797+ var hotspot_mode_desc = new PlaceholderLabel (_("Turn off the Hotspot Mode to connect to other Access Points."), false);
1798 hotspot_mode_box.add (hotspot_mode);
1799 hotspot_mode_box.add (hotspot_mode_desc);
1800
1801@@ -83,27 +83,31 @@
1802 scrolled = new Gtk.ScrolledWindow (null, null);
1803 scrolled.add (wifi_list);
1804
1805- list_stack.add (hotspot_mode_box);
1806+ list_stack.add_named (hotspot_mode_box, "hotspot");
1807 list_stack.add (scrolled);
1808 list_stack.visible_child = scrolled;
1809
1810 main_frame.add (list_stack);
1811
1812+ var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
1813+
1814 hidden_btn = new Gtk.Button.with_label (_("Connect to Hidden Network…"));
1815- hidden_btn.clicked.connect (connect_to_hidden);
1816-
1817- bottom_box.pack_start (hidden_btn, false, false, 0);
1818-
1819- this.add (top_revealer);
1820- this.add (main_frame);
1821- this.add (bottom_revealer);
1822- this.show_all ();
1823-
1824- update ();
1825+ hidden_btn.clicked.connect (() => Utils.WiFi.connect_to_hidden_access_point (client, settings));
1826+
1827+ button_box.pack_start (hidden_btn, false, false, 0);
1828+
1829+ bottom_box.add (button_box);
1830+
1831+ container.add (top_revealer);
1832+ container.add (main_frame);
1833+ container.add (bottom_revealer);
1834+ show_all ();
1835+
1836+ populate ();
1837 }
1838
1839 public NM.RemoteSettings get_nm_settings () {
1840- return nm_settings;
1841+ return settings;
1842 }
1843
1844 public override void update () {
1845@@ -121,14 +125,14 @@
1846 }
1847
1848 if (hidden_btn != null) {
1849- hidden_btn.sensitive = (state != State.WIRED_UNPLUGGED);
1850+ hidden_btn.sensitive = (state != Network.Utils.State.WIRED_UNPLUGGED);
1851 }
1852
1853 var old_active = active_wifi_item;
1854
1855 base.update ();
1856
1857- bool is_hotspot = Utils.Hotspot.get_device_is_hotspot (wifi_device, nm_settings);
1858+ bool is_hotspot = Utils.Hotspot.get_device_is_hotspot (wifi_device, settings);
1859
1860 top_revealer.set_reveal_child (wifi_device.get_active_access_point () != null && !is_hotspot);
1861
1862@@ -215,11 +219,11 @@
1863 }
1864 }
1865
1866- protected override void wifi_activate_cb (WifiMenuItem row) {
1867+ protected override void activate_wifi_item (WifiMenuItem row) {
1868 if (device != null) {
1869 /* Do not activate connection if it is already activated */
1870 if (wifi_device.get_active_access_point () != row.ap) {
1871- var connections = nm_settings.list_connections ();
1872+ var connections = settings.list_connections ();
1873 var device_connections = wifi_device.filter_connections (connections);
1874 var ap_connections = row.ap.filter_connections (device_connections);
1875
1876@@ -232,34 +236,12 @@
1877 var setting_wireless = new NM.SettingWireless ();
1878 if (setting_wireless.add_seen_bssid (row.ap.get_bssid ())) {
1879 if (row.is_secured) {
1880- var connection = new NM.Connection ();
1881- var s_con = new NM.SettingConnection ();
1882- s_con.@set (NM.SettingConnection.UUID, NM.Utils.uuid_generate ());
1883- connection.add_setting (s_con);
1884-
1885- var s_wifi = new NM.SettingWireless ();
1886- s_wifi.@set (NM.SettingWireless.SSID, row.ap.get_ssid ());
1887- connection.add_setting (s_wifi);
1888-
1889- var s_wsec = new NM.SettingWirelessSecurity ();
1890- s_wsec.@set (NM.SettingWirelessSecurity.KEY_MGMT, "wpa-psk");
1891- connection.add_setting (s_wsec);
1892-
1893- var wifi_dialog = new NMAWifiDialog (client,
1894- nm_settings,
1895- connection,
1896- wifi_device,
1897- row.ap,
1898- false);
1899-
1900- set_wifi_dialog_cb (wifi_dialog);
1901- wifi_dialog.run ();
1902- wifi_dialog.destroy ();
1903+ Utils.WiFi.activate_secured_access_point (client, settings, wifi_device, row.ap);
1904 } else {
1905 client.add_and_activate_connection (new NM.Connection (),
1906 wifi_device,
1907 row.ap.get_path (),
1908- finish_connection_cb);
1909+ Utils.finish_connection_cb);
1910 }
1911 }
1912 }
1913@@ -267,7 +249,10 @@
1914 /* Do an update at the next iteration of the main loop, so as every
1915 * signal is flushed (for instance signals responsible for radio button
1916 * checked) */
1917- Idle.add(() => { update (); return false; });
1918+ Idle.add (() => {
1919+ update ();
1920+ return false;
1921+ });
1922 }
1923 }
1924
1925@@ -280,68 +265,5 @@
1926
1927 return null;
1928 }
1929-
1930- private void finish_connection_cb (NM.Client? cb_client,
1931- NM.ActiveConnection? cb_connection,
1932- string? new_connection_path,
1933- Error? error) {
1934- if (error != null && error.code != 0) {
1935- warning ("%s\n", error.message);
1936- }
1937- }
1938-
1939- private void connect_to_hidden () {
1940- var hidden_dialog = new NMAWifiDialog.for_other (client, nm_settings);
1941- set_wifi_dialog_cb (hidden_dialog);
1942- hidden_dialog.run ();
1943- hidden_dialog.destroy ();
1944- }
1945-
1946- private void set_wifi_dialog_cb (NMAWifiDialog wifi_dialog) {
1947- wifi_dialog.response.connect ((response) => {
1948- if (response == Gtk.ResponseType.OK) {
1949- NM.Connection? fuzzy = null;
1950- NM.Device dialog_device;
1951- NM.AccessPoint? dialog_ap = null;
1952- var dialog_connection = wifi_dialog.get_connection (out dialog_device, out dialog_ap);
1953-
1954- foreach (var possible in nm_settings.list_connections ()) {
1955- if (dialog_connection.compare (possible, NM.SettingCompareFlags.FUZZY | NM.SettingCompareFlags.IGNORE_ID)) {
1956- fuzzy = possible;
1957- }
1958- }
1959-
1960- string? path = null;
1961- if (dialog_ap != null) {
1962- path = dialog_ap.get_path ();
1963- }
1964-
1965- if (fuzzy != null) {
1966- client.activate_connection (fuzzy, wifi_device, path, null);
1967- } else {
1968- var connection_setting = dialog_connection.get_setting (typeof (NM.Setting));;
1969-
1970- string? mode = null;
1971- var setting_wireless = (NM.SettingWireless) dialog_connection.get_setting (typeof (NM.SettingWireless));
1972- if (setting_wireless != null) {
1973- mode = setting_wireless.get_mode ();
1974- }
1975-
1976- if (mode == "adhoc") {
1977- if (connection_setting == null) {
1978- connection_setting = new NM.SettingConnection ();
1979- }
1980-
1981- dialog_connection.add_setting (connection_setting);
1982- }
1983-
1984- client.add_and_activate_connection (dialog_connection,
1985- dialog_device,
1986- path,
1987- finish_connection_cb);
1988- }
1989- }
1990- });
1991- }
1992 }
1993 }
1994
1995=== removed directory 'src/common'
1996=== removed file 'src/common/Utils.vala'
1997--- src/common/Utils.vala 2016-07-21 22:42:00 +0000
1998+++ src/common/Utils.vala 1970-01-01 00:00:00 +0000
1999@@ -1,63 +0,0 @@
2000-/*
2001- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2002- *
2003- * This program is free software: you can redistribute it and/or modify
2004- * it under the terms of the GNU Library General Public License as published by
2005- * the Free Software Foundation, either version 2.1 of the License, or
2006- * (at your option) any later version.
2007- *
2008- * This program is distributed in the hope that it will be useful,
2009- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2010- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2011- * GNU Library General Public License for more details.
2012- *
2013- * You should have received a copy of the GNU Library General Public License
2014- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2015- */
2016-
2017-public enum Network.State {
2018- DISCONNECTED,
2019- WIRED_UNPLUGGED,
2020- CONNECTED_WIRED,
2021- CONNECTED_VPN,
2022- CONNECTED_WIFI,
2023- CONNECTED_WIFI_WEAK,
2024- CONNECTED_WIFI_OK,
2025- CONNECTED_WIFI_GOOD,
2026- CONNECTED_WIFI_EXCELLENT,
2027- CONNECTING_WIFI,
2028- CONNECTING_WIRED,
2029- CONNECTING_VPN,
2030- FAILED_WIRED,
2031- FAILED_WIFI,
2032- FAILED_VPN
2033-}
2034-
2035-namespace Network.Common.Utils {
2036- public string network_state_to_string (Network.State state) {
2037- switch(state) {
2038- case Network.State.DISCONNECTED:
2039- return _("Disconnected");
2040- case Network.State.CONNECTED_WIFI:
2041- case Network.State.CONNECTED_WIFI_WEAK:
2042- case Network.State.CONNECTED_WIFI_OK:
2043- case Network.State.CONNECTED_WIFI_GOOD:
2044- case Network.State.CONNECTED_WIFI_EXCELLENT:
2045- case Network.State.CONNECTED_WIRED:
2046- case Network.State.CONNECTED_VPN:
2047- return _("Connected");
2048- case Network.State.FAILED_WIRED:
2049- case Network.State.FAILED_WIFI:
2050- case Network.State.FAILED_VPN:
2051- return _("Failed");
2052- case Network.State.CONNECTING_WIFI:
2053- case Network.State.CONNECTING_WIRED:
2054- case Network.State.CONNECTING_VPN:
2055- return _("Connecting");
2056- case Network.State.WIRED_UNPLUGGED:
2057- return _("Cable unplugged");
2058- }
2059- return UNKNOWN_STR;
2060- }
2061-}
2062-
2063
2064=== removed directory 'src/common/Widgets'
2065=== removed file 'src/common/Widgets/AbstractEtherInterface.vala'
2066--- src/common/Widgets/AbstractEtherInterface.vala 2016-02-12 14:44:32 +0000
2067+++ src/common/Widgets/AbstractEtherInterface.vala 1970-01-01 00:00:00 +0000
2068@@ -1,77 +0,0 @@
2069-/*
2070- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2071- *
2072- * This program is free software: you can redistribute it and/or modify
2073- * it under the terms of the GNU Library General Public License as published by
2074- * the Free Software Foundation, either version 2.1 of the License, or
2075- * (at your option) any later version.
2076- *
2077- * This program is distributed in the hope that it will be useful,
2078- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2079- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2080- * GNU Library General Public License for more details.
2081- *
2082- * You should have received a copy of the GNU Library General Public License
2083- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2084- */
2085-
2086-public abstract class Network.AbstractEtherInterface : Network.WidgetNMInterface {
2087-
2088- public override void update_name (int count) {
2089- var name = device.get_description ();
2090-
2091- /* At least for docker related interfaces, which can be fairly common */
2092- if (name.has_prefix ("veth")) {
2093- display_title = _("Virtual network: %s").printf(name);
2094- }
2095- else {
2096- if (count <= 1) {
2097- display_title = _("Ethernet");
2098- }
2099- else {
2100- display_title = name;
2101- }
2102- }
2103- }
2104-
2105- public override void update () {
2106- base.update ();
2107-
2108- switch (device.state) {
2109- case NM.DeviceState.UNKNOWN:
2110- case NM.DeviceState.UNMANAGED:
2111- case NM.DeviceState.FAILED:
2112- state = State.FAILED_WIRED;
2113- break;
2114-
2115- /* physically not connected */
2116- case NM.DeviceState.UNAVAILABLE:
2117- state = State.WIRED_UNPLUGGED;
2118- break;
2119-
2120- /* virtually not working */
2121- case NM.DeviceState.DISCONNECTED:
2122- state = State.DISCONNECTED;
2123- break;
2124-
2125- case NM.DeviceState.DEACTIVATING:
2126- state = State.FAILED_WIRED;
2127- break;
2128-
2129- /* configuration */
2130- case NM.DeviceState.PREPARE:
2131- case NM.DeviceState.CONFIG:
2132- case NM.DeviceState.NEED_AUTH:
2133- case NM.DeviceState.IP_CONFIG:
2134- case NM.DeviceState.IP_CHECK:
2135- case NM.DeviceState.SECONDARIES:
2136- state = State.CONNECTING_WIRED;
2137- break;
2138-
2139- /* working */
2140- case NM.DeviceState.ACTIVATED:
2141- state = State.CONNECTED_WIRED;
2142- break;
2143- }
2144- }
2145-}
2146
2147=== removed file 'src/common/Widgets/AbstractHotspotInterface.vala'
2148--- src/common/Widgets/AbstractHotspotInterface.vala 2016-02-12 14:44:32 +0000
2149+++ src/common/Widgets/AbstractHotspotInterface.vala 1970-01-01 00:00:00 +0000
2150@@ -1,40 +0,0 @@
2151-/*
2152- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2153- *
2154- * This program is free software: you can redistribute it and/or modify
2155- * it under the terms of the GNU Library General Public License as published by
2156- * the Free Software Foundation, either version 2.1 of the License, or
2157- * (at your option) any later version.
2158- *
2159- * This program is distributed in the hope that it will be useful,
2160- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2161- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2162- * GNU Library General Public License for more details.
2163- *
2164- * You should have received a copy of the GNU Library General Public License
2165- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2166- */
2167-
2168-public abstract class Network.AbstractHotspotInterface : Network.WidgetNMInterface {
2169- protected AbstractWifiInterface root_iface;
2170-
2171- public override void update_name (int count) {
2172- if (count <= 1) {
2173- display_title = _("Hotspot");
2174- }
2175- else {
2176- display_title = _("Hotspot %s").printf (device.get_description ());
2177- }
2178- }
2179-
2180- public override void update () {
2181-#if PLUG_NETWORK
2182- if (Utils.Hotspot.get_device_is_hotspot (root_iface.wifi_device, root_iface.nm_settings)) {
2183- state = State.CONNECTED_WIFI;
2184- }
2185- else {
2186- state = State.DISCONNECTED;
2187- }
2188-#endif
2189- }
2190-}
2191
2192=== removed file 'src/common/Widgets/AbstractWifiInterface.vala'
2193--- src/common/Widgets/AbstractWifiInterface.vala 2016-07-24 22:04:55 +0000
2194+++ src/common/Widgets/AbstractWifiInterface.vala 1970-01-01 00:00:00 +0000
2195@@ -1,371 +0,0 @@
2196-/*
2197- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2198- *
2199- * This program is free software: you can redistribute it and/or modify
2200- * it under the terms of the GNU Library General Public License as published by
2201- * the Free Software Foundation, either version 2.1 of the License, or
2202- * (at your option) any later version.
2203- *
2204- * This program is distributed in the hope that it will be useful,
2205- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2206- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2207- * GNU Library General Public License for more details.
2208- *
2209- * You should have received a copy of the GNU Library General Public License
2210- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2211- */
2212-
2213-public abstract class Network.AbstractWifiInterface : Network.WidgetNMInterface {
2214- protected RFKillManager rfkill;
2215- public NM.DeviceWifi? wifi_device;
2216- protected NM.AccessPoint? active_ap;
2217-
2218- protected Gtk.ListBox wifi_list;
2219-
2220- protected NM.Client nm_client;
2221- public NM.RemoteSettings nm_settings;
2222-
2223- protected WifiMenuItem? active_wifi_item { get; set; }
2224- protected WifiMenuItem? blank_item = null;
2225- protected Gtk.Stack placeholder;
2226-
2227- protected bool locked;
2228- protected bool software_locked;
2229- protected bool hardware_locked;
2230-
2231- uint timeout_scan = 0;
2232-
2233- public void init_wifi_interface (NM.Client nm_client, NM.RemoteSettings nm_settings, NM.Device? _device) {
2234- this.nm_client = nm_client;
2235- this.nm_settings = nm_settings;
2236- device = _device;
2237- wifi_device = (NM.DeviceWifi)device;
2238- blank_item = new WifiMenuItem.blank ();
2239- active_wifi_item = null;
2240-
2241- var no_aps_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
2242- no_aps_box.visible = true;
2243- no_aps_box.valign = Gtk.Align.CENTER;
2244-
2245- var no_aps = construct_placeholder_label (_("No Access Points Available"), true);
2246-
2247- no_aps_box.add (no_aps);
2248-#if PLUG_NETWORK
2249- var no_aps_desc = construct_placeholder_label (_("There are no wireless access points within range."), false);
2250- no_aps_box.add (no_aps_desc);
2251-#endif
2252-
2253- var wireless_off_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
2254- wireless_off_box.visible = true;
2255- wireless_off_box.valign = Gtk.Align.CENTER;
2256-
2257-#if PLUG_NETWORK
2258- var wireless_off = construct_placeholder_label (_("Wireless Is Disabled"), true);
2259- var wireless_off_desc = construct_placeholder_label (_("Enable wireless to discover nearby wireless access points."), false);
2260- wireless_off_box.add (wireless_off);
2261- wireless_off_box.add (wireless_off_desc);
2262-#endif
2263-
2264- var spinner = new Gtk.Spinner ();
2265- spinner.visible = true;
2266- spinner.halign = spinner.valign = Gtk.Align.CENTER;
2267- spinner.start ();
2268-
2269- var scanning_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
2270- var scanning = construct_placeholder_label (_("Scanning for Access Points..."), true);
2271-
2272- scanning_box.add (scanning);
2273- scanning_box.add (spinner);
2274- scanning_box.visible = true;
2275- scanning_box.valign = Gtk.Align.CENTER;
2276-
2277- placeholder.add_named (no_aps_box, "no-aps");
2278- placeholder.add_named (wireless_off_box, "wireless-off");
2279- placeholder.add_named (scanning_box, "scanning");
2280- placeholder.visible_child_name = "no-aps";
2281-
2282- /* Monitor killswitch status */
2283- rfkill = new RFKillManager ();
2284- rfkill.open ();
2285- rfkill.device_added.connect (update);
2286- rfkill.device_changed.connect (update);
2287- rfkill.device_deleted.connect (update);
2288-
2289- nm_settings.connections_read.connect (update);
2290-
2291- wifi_device.notify["active-access-point"].connect (update);
2292- wifi_device.access_point_added.connect (access_point_added_cb);
2293- wifi_device.access_point_removed.connect (access_point_removed_cb);
2294- wifi_device.state_changed.connect (update);
2295-
2296- var aps = wifi_device.get_access_points ();
2297- if (aps != null && aps.length > 0) {
2298- aps.foreach(access_point_added_cb);
2299- }
2300-
2301- update();
2302- }
2303-
2304- construct {
2305- placeholder = new Gtk.Stack ();
2306- placeholder.visible = true;
2307-
2308- wifi_list = new Gtk.ListBox ();
2309- wifi_list.set_sort_func (sort_func);
2310- wifi_list.set_placeholder (placeholder);
2311- }
2312-
2313- public override void update_name (int count) {
2314- if (count <= 1) {
2315- display_title = _("Wireless");
2316- } else {
2317- display_title = device.get_description ();
2318- }
2319- }
2320-
2321- protected Gtk.Label construct_placeholder_label (string text, bool title) {
2322- var label = new Gtk.Label (text);
2323- label.visible = true;
2324- label.use_markup = true;
2325- label.wrap = true;
2326- label.wrap_mode = Pango.WrapMode.WORD_CHAR;
2327- label.max_width_chars = 30;
2328- label.justify = Gtk.Justification.CENTER;
2329-
2330- if (title) {
2331-#if PLUG_NETWORK
2332- label.get_style_context ().add_class ("h2");
2333-#endif
2334- }
2335-
2336- return label;
2337- }
2338-
2339- void access_point_added_cb (Object ap_) {
2340- NM.AccessPoint ap = (NM.AccessPoint)ap_;
2341- WifiMenuItem? previous_wifi_item = blank_item;
2342-
2343- bool found = false;
2344-
2345- foreach(var w in wifi_list.get_children()) {
2346- var menu_item = (WifiMenuItem) w;
2347-
2348- if(NM.Utils.same_ssid (ap.get_ssid (), menu_item.ssid, true)) {
2349- found = true;
2350- menu_item.add_ap(ap);
2351- break;
2352- }
2353-
2354- previous_wifi_item = menu_item;
2355- }
2356-
2357- /* Sometimes network manager sends a (fake?) AP without a valid ssid. */
2358- if(!found && ap.get_ssid() != null) {
2359- WifiMenuItem item = new WifiMenuItem(ap, previous_wifi_item);
2360-
2361- previous_wifi_item = item;
2362- item.set_visible(true);
2363- item.user_action.connect (wifi_activate_cb);
2364-
2365- wifi_list.add (item);
2366- wifi_list.show_all ();
2367-
2368- update ();
2369- }
2370- }
2371-
2372- void update_active_ap () {
2373- debug("Update active AP");
2374-
2375- active_ap = wifi_device.get_active_access_point ();
2376-
2377- if (active_wifi_item != null) {
2378- if(active_wifi_item.state == Network.State.CONNECTING_WIFI) {
2379- active_wifi_item.state = Network.State.DISCONNECTED;
2380- }
2381- active_wifi_item = null;
2382- }
2383-
2384- if(active_ap == null) {
2385- debug("No active AP");
2386- blank_item.set_active (true);
2387- } else {
2388- debug("Active ap: %s", NM.Utils.ssid_to_utf8(active_ap.get_ssid()));
2389-
2390- bool found = false;
2391- foreach(var w in wifi_list.get_children()) {
2392- var menu_item = (WifiMenuItem) w;
2393-
2394- if(NM.Utils.same_ssid (active_ap.get_ssid (), menu_item.ssid, true)) {
2395- found = true;
2396- menu_item.set_active (true);
2397- active_wifi_item = menu_item;
2398- active_wifi_item.state = state;
2399- }
2400- }
2401-
2402- /* This can happen at start, when the access point list is populated. */
2403- if (!found) {
2404- debug ("Active AP not added");
2405- }
2406- }
2407- }
2408-
2409- void access_point_removed_cb (Object ap_) {
2410- NM.AccessPoint ap = (NM.AccessPoint)ap_;
2411-
2412- WifiMenuItem found_item = null;
2413-
2414- foreach(var w in wifi_list.get_children()) {
2415- var menu_item = (WifiMenuItem) w;
2416-
2417- assert(menu_item != null);
2418-
2419- if(NM.Utils.same_ssid (ap.get_ssid (), menu_item.ssid, true)) {
2420- found_item = menu_item;
2421- break;
2422- }
2423- }
2424-
2425- if(found_item == null) {
2426- critical("Couldn't remove an access point which has not been added.");
2427- } else {
2428- if(!found_item.remove_ap(ap)) {
2429- found_item.destroy ();
2430- }
2431- }
2432-
2433- update ();
2434- }
2435-
2436- Network.State strength_to_state (uint8 strength) {
2437- if(strength < 30)
2438- return Network.State.CONNECTED_WIFI_WEAK;
2439- else if(strength < 55)
2440- return Network.State.CONNECTED_WIFI_OK;
2441- else if(strength < 80)
2442- return Network.State.CONNECTED_WIFI_GOOD;
2443- else
2444- return Network.State.CONNECTED_WIFI_EXCELLENT;
2445- }
2446-
2447- public override void update () {
2448-#if PLUG_NETWORK
2449- if (Utils.Hotspot.get_device_is_hotspot (wifi_device, nm_settings)) {
2450- state = State.DISCONNECTED;
2451- return;
2452- }
2453-#endif
2454-
2455- switch (wifi_device.state) {
2456- case NM.DeviceState.UNKNOWN:
2457- case NM.DeviceState.UNMANAGED:
2458- case NM.DeviceState.FAILED:
2459- state = State.FAILED_WIFI;
2460- if(active_wifi_item != null) {
2461- active_wifi_item.state = state;
2462- }
2463- cancel_scan ();
2464- break;
2465-
2466- case NM.DeviceState.DEACTIVATING:
2467- case NM.DeviceState.UNAVAILABLE:
2468- cancel_scan ();
2469- placeholder.visible_child_name = "wireless-off";
2470- state = State.DISCONNECTED;
2471- break;
2472- case NM.DeviceState.DISCONNECTED:
2473- set_scan_placeholder ();
2474- state = State.DISCONNECTED;
2475- break;
2476-
2477- case NM.DeviceState.PREPARE:
2478- case NM.DeviceState.CONFIG:
2479- case NM.DeviceState.NEED_AUTH:
2480- case NM.DeviceState.IP_CONFIG:
2481- case NM.DeviceState.IP_CHECK:
2482- case NM.DeviceState.SECONDARIES:
2483- set_scan_placeholder ();
2484- state = State.CONNECTING_WIFI;
2485- break;
2486-
2487- case NM.DeviceState.ACTIVATED:
2488- set_scan_placeholder ();
2489-
2490- /* That can happen if active_ap has not been added yet, at startup. */
2491- if (active_ap != null) {
2492- state = strength_to_state(active_ap.get_strength());
2493- } else {
2494- state = State.CONNECTED_WIFI_WEAK;
2495- }
2496- break;
2497- }
2498-
2499- debug("New network state: %s", state.to_string ());
2500-
2501- /* Wifi */
2502- software_locked = false;
2503- hardware_locked = false;
2504- foreach (var device in rfkill.get_devices ()) {
2505- if (device.device_type != RFKillDeviceType.WLAN)
2506- continue;
2507-
2508- if (device.software_lock)
2509- software_locked = true;
2510- if (device.hardware_lock)
2511- hardware_locked = true;
2512- }
2513-
2514- locked = hardware_locked || software_locked;
2515-
2516- update_active_ap ();
2517-
2518- base.update ();
2519- }
2520-
2521- void cancel_scan () {
2522- if (timeout_scan > 0) {
2523- Source.remove (timeout_scan);
2524- timeout_scan = 0;
2525- }
2526- }
2527-
2528- void set_scan_placeholder () {
2529- // this state is the previous state (because this method is called before putting the new state)
2530- if (state == State.DISCONNECTED) {
2531- placeholder.visible_child_name = "scanning";
2532- cancel_scan ();
2533- wifi_device.request_scan_simple (null);
2534- timeout_scan = Timeout.add(5000, () => {
2535-#if PLUG_NETWORK
2536- if (Utils.Hotspot.get_device_is_hotspot (wifi_device, nm_settings)) {
2537- return false;
2538- }
2539-#endif
2540-
2541- timeout_scan = 0;
2542- placeholder.visible_child_name = "no-aps";
2543- return false;
2544- });
2545- }
2546- }
2547-
2548- protected abstract void wifi_activate_cb (WifiMenuItem i);
2549-
2550- private int sort_func (Gtk.ListBoxRow r1, Gtk.ListBoxRow r2) {
2551- if (r1 == null || r2 == null) {
2552- return 0;
2553- }
2554-
2555- var w1 = (WifiMenuItem)r1;
2556- var w2 = (WifiMenuItem)r2;
2557-
2558- if (w1.ap.get_strength () > w2.ap.get_strength ()) {
2559- return -1;
2560- } else if (w1.ap.get_strength () < w2.ap.get_strength ()) {
2561- return 1;
2562- } else {
2563- return 0;
2564- }
2565- }
2566-}
2567
2568=== removed file 'src/common/Widgets/NMVisualizer.vala'
2569--- src/common/Widgets/NMVisualizer.vala 2016-07-24 22:04:55 +0000
2570+++ src/common/Widgets/NMVisualizer.vala 1970-01-01 00:00:00 +0000
2571@@ -1,156 +0,0 @@
2572-/*
2573- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2574- *
2575- * This program is free software: you can redistribute it and/or modify
2576- * it under the terms of the GNU Library General Public License as published by
2577- * the Free Software Foundation, either version 2.1 of the License, or
2578- * (at your option) any later version.
2579- *
2580- * This program is distributed in the hope that it will be useful,
2581- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2582- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2583- * GNU Library General Public License for more details.
2584- *
2585- * You should have received a copy of the GNU Library General Public License
2586- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2587- */
2588-
2589-public abstract class Network.Widgets.NMVisualizer : Gtk.Box {
2590- protected NM.Client nm_client;
2591- protected NM.RemoteSettings nm_settings;
2592-
2593- protected GLib.List<WidgetNMInterface>? network_interface;
2594-
2595- public Network.State state { private set; get; default = Network.State.CONNECTING_WIRED; }
2596-
2597- construct {
2598- network_interface = new GLib.List<WidgetNMInterface>();
2599-
2600- build_ui ();
2601-
2602- /* Monitor network manager */
2603- nm_client = new NM.Client ();
2604- nm_settings = new NM.RemoteSettings (null);
2605- nm_settings.new_connection.connect (new_connection_cb);
2606-
2607- nm_client.device_added.connect (device_added_cb);
2608- nm_client.device_removed.connect (device_removed_cb);
2609-
2610- var devices = nm_client.get_devices ();
2611- for (var i = 0; i < devices.length; i++) {
2612- device_added_cb (devices.get (i));
2613- }
2614-
2615- show_all();
2616- }
2617-
2618- protected abstract void build_ui ();
2619- protected abstract void add_interface (WidgetNMInterface widget_interface);
2620- protected abstract void remove_interface (WidgetNMInterface widget_interface);
2621- protected abstract void add_connection (NM.RemoteConnection connection);
2622- protected abstract void remove_connection (NM.RemoteConnection connection);
2623-
2624- void device_removed_cb (NM.Device device) {
2625- foreach (var widget_interface in network_interface) {
2626- if (widget_interface.is_device (device)) {
2627- network_interface.remove (widget_interface);
2628-
2629- // Implementation call
2630- remove_interface (widget_interface);
2631- break;
2632- }
2633- }
2634-
2635- update_interfaces_names ();
2636- }
2637-
2638- void update_interfaces_names () {
2639- var count_type = new Gee.HashMap<string, int?> ();
2640- foreach (var iface in network_interface) {
2641- var type = iface.get_type ().name ();
2642- if (count_type.has_key (type)) {
2643- count_type[type] = count_type[type] + 1;
2644- } else {
2645- count_type[type] = 1;
2646- }
2647- }
2648-
2649- foreach (var iface in network_interface) {
2650- var type = iface.get_type ().name ();
2651- iface.update_name (count_type [type]);
2652- }
2653- }
2654-
2655- void new_connection_cb (Object obj) {
2656- var connection = (NM.RemoteConnection)obj;
2657- connection.removed.connect (() => {
2658- remove_connection (connection);
2659- });
2660-
2661- add_connection (connection);
2662- }
2663-
2664- private void device_added_cb (NM.Device device) {
2665- if (device.get_iface ().has_prefix ("vmnet") ||
2666- device.get_iface ().has_prefix ("lo")) {
2667- return;
2668- }
2669-
2670- WidgetNMInterface? widget_interface = null;
2671-#if PLUG_NETWORK
2672- WidgetNMInterface? hotspot_interface = null;
2673-#endif
2674-
2675- if (device is NM.DeviceWifi) {
2676- widget_interface = new WifiInterface (nm_client, nm_settings, device);
2677-#if PLUG_NETWORK
2678- hotspot_interface = new HotspotInterface ((WifiInterface)widget_interface);
2679-#endif
2680-
2681- debug ("Wifi interface added");
2682- } else if (device is NM.DeviceEthernet) {
2683- widget_interface = new EtherInterface (nm_client, nm_settings, device);
2684- debug ("Ethernet interface added");
2685- } else {
2686- debug ("Unknown device: %s\n", device.get_device_type().to_string());
2687- }
2688-
2689- if (widget_interface != null) {
2690- // Implementation call
2691- network_interface.append (widget_interface);
2692- add_interface(widget_interface);
2693- widget_interface.notify["state"].connect(update_state);
2694-
2695- }
2696-
2697-#if PLUG_NETWORK
2698- if (hotspot_interface != null) {
2699- // Implementation call
2700- network_interface.append (hotspot_interface);
2701- add_interface (hotspot_interface);
2702- hotspot_interface.notify["state"].connect(update_state);
2703- }
2704-#endif
2705-
2706- update_interfaces_names ();
2707- update_all ();
2708- show_all ();
2709- }
2710-
2711- void update_all () {
2712- foreach (var inter in network_interface) {
2713- inter.update ();
2714- }
2715- }
2716-
2717- void update_state () {
2718- var next_state = Network.State.DISCONNECTED;
2719- foreach (var inter in network_interface) {
2720- if (inter.state != Network.State.DISCONNECTED) {
2721- next_state = inter.state;
2722- }
2723- }
2724-
2725- state = next_state;
2726- }
2727-}
2728
2729=== removed file 'src/common/Widgets/VPNMenuItem.vala'
2730--- src/common/Widgets/VPNMenuItem.vala 2016-07-25 17:50:41 +0000
2731+++ src/common/Widgets/VPNMenuItem.vala 1970-01-01 00:00:00 +0000
2732@@ -1,121 +0,0 @@
2733-/*
2734- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2735- *
2736- * This program is free software: you can redistribute it and/or modify
2737- * it under the terms of the GNU Library General Public License as published by
2738- * the Free Software Foundation, either version 2.1 of the License, or
2739- * (at your option) any later version.
2740- *
2741- * This program is distributed in the hope that it will be useful,
2742- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2743- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2744- * GNU Library General Public License for more details.
2745- *
2746- * You should have received a copy of the GNU Library General Public License
2747- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2748- */
2749-
2750-public class Network.VPNMenuItem : Gtk.ListBoxRow {
2751- public signal void user_action();
2752- public NM.RemoteConnection? connection;
2753-
2754- public Network.State state { get; set; default = Network.State.DISCONNECTED; }
2755-
2756- Gtk.RadioButton radio_button;
2757- Gtk.Spinner spinner;
2758- Gtk.Image error_img;
2759- Gtk.Button remove_button;
2760-
2761- public VPNMenuItem (NM.RemoteConnection _connection, VPNMenuItem? previous = null) {
2762- connection = _connection;
2763-
2764- var main_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
2765- main_box.margin_start = main_box.margin_end = 6;
2766- radio_button = new Gtk.RadioButton(null);
2767- if (previous != null) radio_button.set_group (previous.get_group ());
2768-
2769- radio_button.button_release_event.connect ( (b, ev) => {
2770- user_action();
2771- return false;
2772- });
2773-
2774- error_img = new Gtk.Image.from_icon_name ("process-error-symbolic", Gtk.IconSize.MENU);
2775- error_img.set_tooltip_text (_("This Virtual Private Network could not be connected to."));
2776-
2777- spinner = new Gtk.Spinner();
2778- spinner.visible = false;
2779- spinner.no_show_all = !spinner.visible;
2780-
2781- remove_button = new Gtk.Button.from_icon_name ("user-trash-symbolic", Gtk.IconSize.MENU);
2782- remove_button.get_style_context ().add_class ("flat");
2783- remove_button.clicked.connect (() => {
2784- connection.delete (null);
2785- });
2786-
2787- main_box.pack_start (radio_button, true, true);
2788- main_box.pack_start (spinner, false, false);
2789- main_box.pack_start (error_img, false, false);
2790- main_box.pack_start (remove_button, false, false);
2791-
2792- notify["state"].connect (update);
2793- radio_button.notify["active"].connect (update);
2794- this.add (main_box);
2795- this.get_style_context ().add_class ("menuitem");
2796-
2797- connection.changed.connect (update);
2798- update ();
2799- }
2800-
2801- /**
2802- * Only used for an item which is not displayed: hacky way to have no radio button selected.
2803- **/
2804- public VPNMenuItem.blank () {
2805- radio_button = new Gtk.RadioButton(null);
2806- }
2807-
2808- unowned SList get_group () {
2809- return radio_button.get_group();
2810- }
2811-
2812- public void set_active (bool active) {
2813- radio_button.set_active (active);
2814- }
2815-
2816- private void update () {
2817- radio_button.label = connection.get_id ();
2818-
2819- switch (state) {
2820- case State.FAILED_VPN:
2821- show_item(error_img);
2822- break;
2823- case State.CONNECTING_VPN:
2824- show_item(spinner);
2825- break;
2826- default:
2827- hide_icons ();
2828- break;
2829- }
2830- }
2831-
2832- public void hide_icons (bool show_remove_button = true) {
2833-#if PLUG_NETWORK
2834- hide_item (error_img);
2835- hide_item (spinner);
2836-
2837- if (!show_remove_button) {
2838- hide_item (remove_button);
2839- }
2840-#endif
2841- }
2842-
2843- void show_item(Gtk.Widget w) {
2844- w.visible = true;
2845- w.no_show_all = !w.visible;
2846- }
2847-
2848- void hide_item(Gtk.Widget w) {
2849- w.visible = false;
2850- w.no_show_all = !w.visible;
2851- w.hide();
2852- }
2853-}
2854\ No newline at end of file
2855
2856=== removed file 'src/common/Widgets/WidgetNMInterface.vala'
2857--- src/common/Widgets/WidgetNMInterface.vala 2015-11-18 10:28:07 +0000
2858+++ src/common/Widgets/WidgetNMInterface.vala 1970-01-01 00:00:00 +0000
2859@@ -1,58 +0,0 @@
2860-/*
2861- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2862- *
2863- * This program is free software: you can redistribute it and/or modify
2864- * it under the terms of the GNU Library General Public License as published by
2865- * the Free Software Foundation, either version 2.1 of the License, or
2866- * (at your option) any later version.
2867- *
2868- * This program is distributed in the hope that it will be useful,
2869- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2870- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2871- * GNU Library General Public License for more details.
2872- *
2873- * You should have received a copy of the GNU Library General Public License
2874- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2875- */
2876-
2877-#if INDICATOR_NETWORK
2878-public abstract class Network.WidgetNMInterface : Gtk.Box {
2879- protected NM.Device? device;
2880-#else
2881-public abstract class Network.WidgetNMInterface : Network.Widgets.Page {
2882-#endif
2883- public Network.State state { get; protected set; default = Network.State.DISCONNECTED; }
2884-
2885- public string display_title { get; protected set; default = _("Unknown device"); }
2886-
2887-#if PLUG_NETWORK
2888- construct {
2889- notify["display-title"].connect ( () => {
2890- device_label.label = display_title;
2891- });
2892- }
2893-#endif
2894-
2895-#if INDICATOR_NETWORK
2896- public Wingpanel.Widgets.Separator? sep = null;
2897-
2898- public signal void show_dialog (Gtk.Widget w);
2899- public signal void need_settings ();
2900-#endif
2901-
2902- public bool is_device (NM.Device device) {
2903- return device == this.device;
2904- }
2905-
2906-#if PLUG_NETWORK
2907- public override void update () {
2908- base.update ();
2909-#else
2910- public virtual void update () {
2911-#endif
2912- }
2913-
2914- public virtual void update_name (int count) {
2915- display_title = _("Unknown type: %s ").printf (device.get_description ());
2916- }
2917-}
2918
2919=== removed file 'src/common/Widgets/WifiMenuItem.vala'
2920--- src/common/Widgets/WifiMenuItem.vala 2016-07-24 22:04:55 +0000
2921+++ src/common/Widgets/WifiMenuItem.vala 1970-01-01 00:00:00 +0000
2922@@ -1,214 +0,0 @@
2923-/*
2924- * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
2925- *
2926- * This program is free software: you can redistribute it and/or modify
2927- * it under the terms of the GNU Library General Public License as published by
2928- * the Free Software Foundation, either version 2.1 of the License, or
2929- * (at your option) any later version.
2930- *
2931- * This program is distributed in the hope that it will be useful,
2932- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2933- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2934- * GNU Library General Public License for more details.
2935- *
2936- * You should have received a copy of the GNU Library General Public License
2937- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2938- */
2939-
2940-public class Network.WifiMenuItem : Gtk.ListBoxRow {
2941- private List<NM.AccessPoint> _ap;
2942- public signal void user_action();
2943- public GLib.ByteArray ssid {
2944- get {
2945- return _tmp_ap.get_ssid();
2946- }
2947- }
2948-
2949- public Network.State state { get; set; default = Network.State.DISCONNECTED; }
2950-
2951- public uint8 strength {
2952- get {
2953- uint8 strength = 0;
2954- foreach(var ap in _ap) {
2955- strength = uint8.max(strength, ap.get_strength());
2956- }
2957- return strength;
2958- }
2959- }
2960-
2961- public bool is_secured {
2962- get {
2963- return ap.get_wpa_flags () != NM.@80211ApSecurityFlags.NONE || ap.get_rsn_flags () != NM.@80211ApSecurityFlags.NONE;
2964- }
2965- }
2966-
2967- private bool show_icons = true;
2968-
2969- public NM.AccessPoint ap { get { return _tmp_ap; } }
2970- NM.AccessPoint _tmp_ap;
2971-
2972- Gtk.RadioButton radio_button;
2973- Gtk.Image img_strength;
2974- Gtk.Image lock_img;
2975- Gtk.Image error_img;
2976- Gtk.Spinner spinner;
2977-
2978- public WifiMenuItem (NM.AccessPoint ap, WifiMenuItem? previous = null) {
2979- var main_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
2980- radio_button = new Gtk.RadioButton(null);
2981- radio_button.margin_start = 6;
2982- if (previous != null) radio_button.set_group (previous.get_group ());
2983-
2984- radio_button.button_release_event.connect ( (b, ev) => {
2985- user_action();
2986- return false;
2987- });
2988-
2989- img_strength = new Gtk.Image();
2990- img_strength.margin_end = 6;
2991-
2992- lock_img = new Gtk.Image.from_icon_name ("channel-secure-symbolic", Gtk.IconSize.MENU);
2993- lock_img.margin_start = 6;
2994-
2995- /* TODO: investigate this, it has not been tested yet. */
2996- error_img = new Gtk.Image.from_icon_name ("process-error-symbolic", Gtk.IconSize.MENU);
2997- error_img.margin_start = 6;
2998-
2999- error_img.set_tooltip_text (_("This wireless network could not be connected to."));
3000-
3001- main_box.pack_start(radio_button, true, true);
3002- spinner = new Gtk.Spinner();
3003- spinner.start();
3004- spinner.visible = false;
3005- spinner.no_show_all = !spinner.visible;
3006- main_box.pack_start(spinner, false, false);
3007- main_box.pack_start(error_img, false, false);
3008- main_box.pack_start(lock_img, false, false);
3009- main_box.pack_start(img_strength, false, false);
3010-
3011- _ap = new List<NM.AccessPoint>();
3012-
3013- /* Adding the access point triggers update */
3014- add_ap(ap);
3015-
3016- notify["state"].connect (update);
3017- radio_button.notify["active"].connect (update);
3018- this.add (main_box);
3019- this.get_style_context ().add_class ("menuitem");
3020-
3021- update ();
3022- }
3023-
3024- /**
3025- * Only used for an item which is not displayed: hacky way to have no radio button selected.
3026- **/
3027- public WifiMenuItem.blank () {
3028- radio_button = new Gtk.RadioButton(null);
3029- }
3030-
3031- void update_tmp_ap () {
3032- uint8 strength = 0;
3033- foreach(var ap in _ap) {
3034- _tmp_ap = strength > ap.get_strength () ? _tmp_ap : ap;
3035- strength = uint8.max (strength, ap.get_strength ());
3036- }
3037- }
3038-
3039- public void set_active (bool active) {
3040- radio_button.set_active (active);
3041- }
3042-
3043- unowned SList get_group () {
3044- return radio_button.get_group();
3045- }
3046-
3047- void set_lock_img_tooltip (NM.@80211ApSecurityFlags flags) {
3048- if((flags & NM.@80211ApSecurityFlags.GROUP_WEP40) != 0) {
3049- lock_img.set_tooltip_text(_("This network uses 40/64-bit WEP encryption."));
3050- } else if((flags & NM.@80211ApSecurityFlags.GROUP_WEP104) != 0) {
3051- lock_img.set_tooltip_text(_("This network uses 104/128-bit WEP encryption."));
3052- } else if((flags & NM.@80211ApSecurityFlags.KEY_MGMT_PSK) != 0) {
3053- lock_img.set_tooltip_text(_("This network uses WPA encryption."));
3054- } else {
3055- lock_img.set_tooltip_text(_("This network uses encryption."));
3056- }
3057- }
3058-
3059- private void update () {
3060- radio_button.label = NM.Utils.ssid_to_utf8 (ap.get_ssid ());
3061-
3062-#if PLUG_NETWORK
3063- if (show_icons) {
3064-#endif
3065- img_strength.set_from_icon_name("network-wireless-signal-" + strength_to_string(strength) + "-symbolic", Gtk.IconSize.MENU);
3066- img_strength.show_all();
3067-
3068- lock_img.visible = is_secured;
3069- set_lock_img_tooltip(ap.get_wpa_flags ());
3070- lock_img.no_show_all = !lock_img.visible;
3071-
3072- hide_item(error_img);
3073- hide_item(spinner);
3074-#if PLUG_NETWORK
3075- }
3076-#endif
3077- switch (state) {
3078- case State.FAILED_WIFI:
3079- show_item(error_img);
3080- break;
3081- case State.CONNECTING_WIFI:
3082- show_item(spinner);
3083- if(!radio_button.active) {
3084- critical("An access point is being connected but not active.");
3085- }
3086- break;
3087- }
3088- }
3089-
3090- public void hide_icons () {
3091-#if PLUG_NETWORK
3092- show_icons = false;
3093- hide_item (error_img);
3094- hide_item (lock_img);
3095- hide_item (img_strength);
3096-#endif
3097- }
3098-
3099- void show_item(Gtk.Widget w) {
3100- w.visible = true;
3101- w.no_show_all = !w.visible;
3102- }
3103-
3104- void hide_item(Gtk.Widget w) {
3105- w.visible = false;
3106- w.no_show_all = !w.visible;
3107- w.hide();
3108- }
3109-
3110- public void add_ap(NM.AccessPoint ap) {
3111- _ap.append(ap);
3112- update_tmp_ap();
3113-
3114- update();
3115- }
3116-
3117- string strength_to_string(uint8 strength) {
3118- if(strength < 30)
3119- return "weak";
3120- else if(strength < 55)
3121- return "ok";
3122- else if(strength < 80)
3123- return "good";
3124- else
3125- return "excellent";
3126- }
3127-
3128- public bool remove_ap(NM.AccessPoint ap) {
3129- _ap.remove(ap);
3130-
3131- update_tmp_ap();
3132-
3133- return _ap.length() > 0;
3134- }
3135-}
3136-
3137
3138=== removed file 'src/common/rfkill.vala'
3139--- src/common/rfkill.vala 2015-10-09 19:12:42 +0000
3140+++ src/common/rfkill.vala 1970-01-01 00:00:00 +0000
3141@@ -1,149 +0,0 @@
3142-/*
3143- * Copyright (C) 2012 Canonical Ltd.
3144- * Author: Robert Ancell <robert.ancell@canonical.com>
3145- *
3146- * This program is free software: you can redistribute it and/or modify it under
3147- * the terms of the GNU General Public License as published by the Free Software
3148- * Foundation, either version 3 of the License, or (at your option) any later
3149- * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
3150- * license.
3151- */
3152-
3153-public enum RFKillDeviceType {
3154- ALL = 0,
3155- WLAN,
3156- BLUETOOTH,
3157- UWB,
3158- WIMAX,
3159- WMAN
3160-}
3161-
3162-public class RFKillDevice {
3163- public signal void changed ();
3164-
3165- public bool software_lock {
3166- get { return _software_lock; }
3167- set {
3168- var event = RFKillEvent ();
3169- event.idx = idx;
3170- event.op = RFKillOperation.CHANGE;
3171- event.soft = value ? 1 : 0;
3172- if (Posix.write (manager.fd, &event, 8) != 8)
3173- return;
3174- }
3175- }
3176-
3177- public bool hardware_lock { get { return _hardware_lock; } }
3178-
3179- public RFKillDeviceType device_type { get { return _device_type; } }
3180-
3181- internal RFKillManager manager;
3182- internal uint32 idx;
3183- internal RFKillDeviceType _device_type;
3184- internal bool _software_lock;
3185- internal bool _hardware_lock;
3186-
3187- internal RFKillDevice (RFKillManager manager, uint32 idx, RFKillDeviceType device_type, bool software_lock, bool hardware_lock) {
3188- this.manager = manager;
3189- this.idx = idx;
3190- _device_type = device_type;
3191- _software_lock = software_lock;
3192- _hardware_lock = hardware_lock;
3193- }
3194-}
3195-
3196-public class RFKillManager : Object {
3197- public signal void device_added (RFKillDevice device);
3198- public signal void device_changed (RFKillDevice device);
3199- public signal void device_deleted (RFKillDevice device);
3200-
3201- public RFKillManager () {
3202- _devices = new List<RFKillDevice> ();
3203- }
3204-
3205- public void open () {
3206- fd = Posix.open ("/dev/rfkill", Posix.O_RDWR);
3207- Posix.fcntl (fd, Posix.F_SETFL, Posix.O_NONBLOCK);
3208-
3209- /* Read initial state */
3210- while (read_event ());
3211-
3212- /* Monitor for events */
3213- var channel = new IOChannel.unix_new (fd);
3214- channel.add_watch (IOCondition.IN | IOCondition.HUP | IOCondition.ERR, () => { return read_event (); });
3215- }
3216-
3217- public List<RFKillDevice> get_devices () {
3218- var devices = new List<RFKillDevice> ();
3219- foreach (var device in _devices)
3220- devices.append (device);
3221- return devices;
3222- }
3223-
3224- public void set_software_lock (RFKillDeviceType type, bool lock_enabled) {
3225- var event = RFKillEvent ();
3226- event.type = type;
3227- event.op = RFKillOperation.CHANGE_ALL;
3228- event.soft = lock_enabled ? 1 : 0;
3229- if (Posix.write (fd, &event, 8) != 8)
3230- return;
3231- }
3232-
3233- internal int fd = -1;
3234- private List<RFKillDevice> _devices;
3235-
3236- private bool read_event () {
3237- var event = RFKillEvent ();
3238- if (Posix.read (fd, &event, 8) != 8)
3239- return false;
3240-
3241- switch (event.op) {
3242- case RFKillOperation.ADD:
3243- var device = new RFKillDevice (this, event.idx, (RFKillDeviceType) event.type, event.soft != 0, event.hard != 0);
3244- _devices.append (device);
3245- device_added (device);
3246- break;
3247- case RFKillOperation.DELETE:
3248- var device = get_device (event.idx);
3249- if (device != null) {
3250- _devices.remove (device);
3251- device_deleted (device);
3252- }
3253- break;
3254- case RFKillOperation.CHANGE:
3255- var device = get_device (event.idx);
3256- if (device != null) {
3257- device._software_lock = event.soft != 0;
3258- device._hardware_lock = event.hard != 0;
3259- device.changed ();
3260- device_changed (device);
3261- }
3262- break;
3263- }
3264- return true;
3265- }
3266-
3267- private RFKillDevice? get_device (uint32 idx) {
3268- foreach (var device in _devices) {
3269- if (device.idx == idx)
3270- return device;
3271- }
3272-
3273- return null;
3274- }
3275-}
3276-
3277-private struct RFKillEvent {
3278- uint32 idx;
3279- uint8 type;
3280- uint8 op;
3281- uint8 soft;
3282- uint8 hard;
3283-}
3284-
3285-private enum RFKillOperation {
3286- ADD = 0,
3287- DELETE,
3288- CHANGE,
3289- CHANGE_ALL
3290-}
3291
3292=== added directory 'src/shared'
3293=== added directory 'src/shared/Abstract'
3294=== added file 'src/shared/Abstract/AbstractEthernetView.vala'
3295--- src/shared/Abstract/AbstractEthernetView.vala 1970-01-01 00:00:00 +0000
3296+++ src/shared/Abstract/AbstractEthernetView.vala 2016-11-20 19:56:12 +0000
3297@@ -0,0 +1,71 @@
3298+/*
3299+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
3300+ *
3301+ * This program is free software: you can redistribute it and/or modify
3302+ * it under the terms of the GNU Library General Public License as published by
3303+ * the Free Software Foundation, either version 2.1 of the License, or
3304+ * (at your option) any later version.
3305+ *
3306+ * This program is distributed in the hope that it will be useful,
3307+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3308+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3309+ * GNU Library General Public License for more details.
3310+ *
3311+ * You should have received a copy of the GNU Library General Public License
3312+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3313+ */
3314+
3315+public abstract class Network.Widgets.AbstractEthernetView : Network.Widgets.View {
3316+ public override void update_name (int count) {
3317+ var name = device.get_description ();
3318+
3319+ /* At least for docker related interfaces, which can be fairly common */
3320+ if (name.has_prefix ("veth")) {
3321+ display_title = _("Virtual network: %s").printf (name);
3322+ } else {
3323+ if (count <= 1) {
3324+ display_title = _("Ethernet");
3325+ } else {
3326+ display_title = name;
3327+ }
3328+ }
3329+ }
3330+
3331+ public override void update () {
3332+ base.update ();
3333+
3334+ switch (device.state) {
3335+ case NM.DeviceState.UNKNOWN:
3336+ case NM.DeviceState.UNMANAGED:
3337+ case NM.DeviceState.FAILED:
3338+ case NM.DeviceState.DEACTIVATING:
3339+ state = Network.Utils.State.FAILED_WIRED;
3340+ break;
3341+
3342+ /* Physically not connected */
3343+ case NM.DeviceState.UNAVAILABLE:
3344+ state = Network.Utils.State.WIRED_UNPLUGGED;
3345+ break;
3346+
3347+ /* Virtually not working */
3348+ case NM.DeviceState.DISCONNECTED:
3349+ state = Network.Utils.State.DISCONNECTED;
3350+ break;
3351+
3352+ /* Configuration */
3353+ case NM.DeviceState.PREPARE:
3354+ case NM.DeviceState.CONFIG:
3355+ case NM.DeviceState.NEED_AUTH:
3356+ case NM.DeviceState.IP_CONFIG:
3357+ case NM.DeviceState.IP_CHECK:
3358+ case NM.DeviceState.SECONDARIES:
3359+ state = Network.Utils.State.CONNECTING_WIRED;
3360+ break;
3361+
3362+ /* Working */
3363+ case NM.DeviceState.ACTIVATED:
3364+ state = Network.Utils.State.CONNECTED_WIRED;
3365+ break;
3366+ }
3367+ }
3368+}
3369
3370=== added file 'src/shared/Abstract/AbstractHotspotView.vala'
3371--- src/shared/Abstract/AbstractHotspotView.vala 1970-01-01 00:00:00 +0000
3372+++ src/shared/Abstract/AbstractHotspotView.vala 2016-11-20 19:56:12 +0000
3373@@ -0,0 +1,45 @@
3374+/*
3375+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
3376+ *
3377+ * This program is free software: you can redistribute it and/or modify
3378+ * it under the terms of the GNU Library General Public License as published by
3379+ * the Free Software Foundation, either version 2.1 of the License, or
3380+ * (at your option) any later version.
3381+ *
3382+ * This program is distributed in the hope that it will be useful,
3383+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3384+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3385+ * GNU Library General Public License for more details.
3386+ *
3387+ * You should have received a copy of the GNU Library General Public License
3388+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3389+ */
3390+
3391+public abstract class Network.Widgets.AbstractHotspotView : Network.Widgets.View {
3392+ public NM.RemoteSettings settings;
3393+
3394+ protected NM.Client client;
3395+ protected NM.DeviceWifi wifi_device {
3396+ get {
3397+ return (NM.DeviceWifi)device;
3398+ }
3399+ }
3400+
3401+ public override void update_name (int count) {
3402+ if (count <= 1) {
3403+ display_title = _("Hotspot");
3404+ } else {
3405+ display_title = _("Hotspot %s").printf (device.get_description ());
3406+ }
3407+ }
3408+
3409+ public override void update () {
3410+#if PLUG_NETWORK
3411+ if (Utils.Hotspot.get_device_is_hotspot (wifi_device, settings)) {
3412+ state = Network.Utils.State.CONNECTED_WIFI;
3413+ } else {
3414+ state = Network.Utils.State.DISCONNECTED;
3415+ }
3416+#endif
3417+ }
3418+}
3419
3420=== added file 'src/shared/Abstract/AbstractView.vala'
3421--- src/shared/Abstract/AbstractView.vala 1970-01-01 00:00:00 +0000
3422+++ src/shared/Abstract/AbstractView.vala 2016-11-20 19:56:12 +0000
3423@@ -0,0 +1,34 @@
3424+/*
3425+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
3426+ *
3427+ * This program is free software: you can redistribute it and/or modify
3428+ * it under the terms of the GNU Library General Public License as published by
3429+ * the Free Software Foundation, either version 2.1 of the License, or
3430+ * (at your option) any later version.
3431+ *
3432+ * This program is distributed in the hope that it will be useful,
3433+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3434+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3435+ * GNU Library General Public License for more details.
3436+ *
3437+ * You should have received a copy of the GNU Library General Public License
3438+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3439+ */
3440+
3441+public abstract class Network.Widgets.AbstractView : Gtk.Bin {
3442+ public Network.Utils.State state { get; protected set; default = Network.Utils.State.DISCONNECTED; }
3443+ public string display_title { get; protected set; default = _("Unknown device"); }
3444+
3445+ protected NM.Device? device;
3446+
3447+ public NM.Device? get_device () {
3448+ return device;
3449+ }
3450+
3451+ public virtual void update () {
3452+ }
3453+
3454+ public virtual void update_name (int count) {
3455+ display_title = _("Unknown type: %s").printf (device.get_description ());
3456+ }
3457+}
3458
3459=== added file 'src/shared/Abstract/AbstractWiFiView.vala'
3460--- src/shared/Abstract/AbstractWiFiView.vala 1970-01-01 00:00:00 +0000
3461+++ src/shared/Abstract/AbstractWiFiView.vala 2016-11-20 19:56:12 +0000
3462@@ -0,0 +1,345 @@
3463+/*
3464+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
3465+ *
3466+ * This program is free software: you can redistribute it and/or modify
3467+ * it under the terms of the GNU Library General Public License as published by
3468+ * the Free Software Foundation, either version 2.1 of the License, or
3469+ * (at your option) any later version.
3470+ *
3471+ * This program is distributed in the hope that it will be useful,
3472+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3473+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3474+ * GNU Library General Public License for more details.
3475+ *
3476+ * You should have received a copy of the GNU Library General Public License
3477+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3478+ */
3479+
3480+public abstract class Network.Widgets.AbstractWiFiView : Network.Widgets.View {
3481+ public NM.RemoteSettings settings;
3482+
3483+ protected RFKillManager rfkill;
3484+ protected NM.AccessPoint? active_ap;
3485+
3486+ protected Gtk.ListBox wifi_list;
3487+
3488+ protected NM.DeviceWifi wifi_device {
3489+ get {
3490+ return (NM.DeviceWifi)device;
3491+ }
3492+ }
3493+
3494+ protected NM.Client client;
3495+ protected WifiMenuItem? active_wifi_item;
3496+ protected WifiMenuItem? blank_item = null;
3497+ protected Gtk.Stack placeholder;
3498+
3499+ protected bool software_locked;
3500+
3501+ private uint timeout_scan = 0;
3502+
3503+ private const int WEAK_STRENGH = 30;
3504+ private const int OK_STRENGH = 55;
3505+ private const int GOOD_STRENGH = 80;
3506+
3507+ construct {
3508+ placeholder = new Gtk.Stack ();
3509+ placeholder.visible = true;
3510+
3511+ wifi_list = new Gtk.ListBox ();
3512+ wifi_list.set_sort_func (sort_func);
3513+ wifi_list.set_placeholder (placeholder);
3514+
3515+ blank_item = new WifiMenuItem.blank ();
3516+ active_wifi_item = null;
3517+
3518+ var no_aps_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
3519+ no_aps_box.visible = true;
3520+ no_aps_box.valign = Gtk.Align.CENTER;
3521+
3522+ var no_aps = new PlaceholderLabel (_("No Access Points Available"), true);
3523+
3524+ no_aps_box.add (no_aps);
3525+#if PLUG_NETWORK
3526+ var no_aps_desc = new PlaceholderLabel (_("There are no wireless access points within range."), false);
3527+ no_aps_box.add (no_aps_desc);
3528+#endif
3529+
3530+ var wireless_off_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
3531+ wireless_off_box.visible = true;
3532+ wireless_off_box.valign = Gtk.Align.CENTER;
3533+
3534+#if PLUG_NETWORK
3535+ var wireless_off = new PlaceholderLabel (_("Wireless Is Disabled"), true);
3536+ var wireless_off_desc = new PlaceholderLabel (_("Enable wireless to discover nearby wireless access points."), false);
3537+ wireless_off_box.add (wireless_off);
3538+ wireless_off_box.add (wireless_off_desc);
3539+#endif
3540+
3541+ var spinner = new Gtk.Spinner ();
3542+ spinner.visible = true;
3543+ spinner.halign = spinner.valign = Gtk.Align.CENTER;
3544+ spinner.start ();
3545+
3546+ var scanning_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
3547+ var scanning = new PlaceholderLabel (_("Scanning for Access Points…"), true);
3548+
3549+ scanning_box.add (scanning);
3550+ scanning_box.add (spinner);
3551+ scanning_box.visible = true;
3552+ scanning_box.valign = Gtk.Align.CENTER;
3553+
3554+ placeholder.add_named (no_aps_box, "no-aps");
3555+ placeholder.add_named (wireless_off_box, "wireless-off");
3556+ placeholder.add_named (scanning_box, "scanning");
3557+ placeholder.visible_child_name = "no-aps";
3558+
3559+ /* Monitor killswitch status */
3560+ rfkill = new RFKillManager ();
3561+ rfkill.open ();
3562+ rfkill.device_added.connect (update);
3563+ rfkill.device_changed.connect (update);
3564+ rfkill.device_deleted.connect (update);
3565+ }
3566+
3567+ protected abstract void activate_wifi_item (WifiMenuItem item);
3568+
3569+ protected void populate () {
3570+ settings.connections_read.connect (update);
3571+
3572+ wifi_device.notify["active-access-point"].connect (update);
3573+ wifi_device.access_point_added.connect (add_access_point_internal);
3574+ wifi_device.access_point_removed.connect (remove_access_point_internal);
3575+ wifi_device.state_changed.connect (update);
3576+
3577+ var aps = wifi_device.get_access_points ();
3578+ if (aps.length > 0) {
3579+ aps.foreach (add_access_point_internal);
3580+ }
3581+
3582+ update ();
3583+ }
3584+
3585+ public override void update_name (int count) {
3586+ if (count <= 1) {
3587+ display_title = _("Wireless");
3588+ } else {
3589+ display_title = device.get_description ();
3590+ }
3591+ }
3592+
3593+ private void add_access_point_internal (Object obj) {
3594+ NM.AccessPoint ap = (NM.AccessPoint)obj;
3595+ WifiMenuItem? previous_wifi_item = blank_item;
3596+
3597+ bool found = false;
3598+
3599+ foreach (var child in wifi_list.get_children ()) {
3600+ var menu_item = (WifiMenuItem)child;
3601+ if (menu_item == null) {
3602+ continue;
3603+ }
3604+
3605+ if (NM.Utils.same_ssid (ap.get_ssid (), menu_item.ssid, true)) {
3606+ found = true;
3607+ menu_item.ap = ap;
3608+ break;
3609+ }
3610+
3611+ previous_wifi_item = menu_item;
3612+ }
3613+
3614+ /* Sometimes network manager sends a (fake?) AP without a valid ssid. */
3615+ if (!found && ap.get_ssid () != null) {
3616+ WifiMenuItem item = new WifiMenuItem (ap, previous_wifi_item);
3617+
3618+ previous_wifi_item = item;
3619+ item.activated.connect (activate_wifi_item);
3620+
3621+ wifi_list.add (item);
3622+ wifi_list.show_all ();
3623+
3624+ update ();
3625+ }
3626+ }
3627+
3628+ private void update_active_ap () {
3629+ active_ap = wifi_device.get_active_access_point ();
3630+
3631+ if (active_wifi_item != null) {
3632+ if (active_wifi_item.state == Network.Utils.State.CONNECTING_WIFI) {
3633+ active_wifi_item.state = Network.Utils.State.DISCONNECTED;
3634+ }
3635+
3636+ active_wifi_item = null;
3637+ }
3638+
3639+ if (active_ap == null) {
3640+ blank_item.set_active (true);
3641+ } else {
3642+ bool found = false;
3643+ foreach (var child in wifi_list.get_children ()) {
3644+ var menu_item = (WifiMenuItem)child;
3645+ if (menu_item == null) {
3646+ continue;
3647+ }
3648+
3649+ if (NM.Utils.same_ssid (active_ap.get_ssid (), menu_item.ssid, true)) {
3650+ found = true;
3651+ menu_item.set_active (true);
3652+ active_wifi_item = menu_item;
3653+ active_wifi_item.state = state;
3654+ }
3655+ }
3656+ }
3657+ }
3658+
3659+ private void remove_access_point_internal (Object obj) {
3660+ NM.AccessPoint ap = (NM.AccessPoint)obj;
3661+
3662+ WifiMenuItem? found_item = null;
3663+
3664+ foreach (var child in wifi_list.get_children ()) {
3665+ var menu_item = (WifiMenuItem)child;
3666+ if (menu_item == null) {
3667+ continue;
3668+ }
3669+
3670+ if (NM.Utils.same_ssid (ap.get_ssid (), menu_item.ssid, true)) {
3671+ found_item = menu_item;
3672+ break;
3673+ }
3674+ }
3675+
3676+ if (found_item != null) {
3677+ found_item.ap = null;
3678+ found_item.destroy ();
3679+ }
3680+
3681+ update ();
3682+ }
3683+
3684+ protected Network.Utils.State strength_to_state (uint8 strength) {
3685+ if (strength < WEAK_STRENGH) {
3686+ return Network.Utils.State.CONNECTED_WIFI_WEAK;
3687+ } else if (strength < OK_STRENGH) {
3688+ return Network.Utils.State.CONNECTED_WIFI_OK;
3689+ } else if (strength < GOOD_STRENGH) {
3690+ return Network.Utils.State.CONNECTED_WIFI_GOOD;
3691+ }
3692+
3693+ return Network.Utils.State.CONNECTED_WIFI_EXCELLENT;
3694+ }
3695+
3696+ public override void update () {
3697+#if PLUG_NETWORK
3698+ if (Utils.Hotspot.get_device_is_hotspot (wifi_device, settings)) {
3699+ state = Network.Utils.State.DISCONNECTED;
3700+ return;
3701+ }
3702+#endif
3703+
3704+ switch (wifi_device.state) {
3705+ case NM.DeviceState.UNKNOWN:
3706+ case NM.DeviceState.UNMANAGED:
3707+ case NM.DeviceState.FAILED:
3708+ state = Network.Utils.State.FAILED_WIFI;
3709+ if(active_wifi_item != null) {
3710+ active_wifi_item.state = state;
3711+ }
3712+
3713+ cancel_scan ();
3714+ break;
3715+ case NM.DeviceState.DEACTIVATING:
3716+ case NM.DeviceState.UNAVAILABLE:
3717+ cancel_scan ();
3718+ placeholder.visible_child_name = "wireless-off";
3719+ state = Network.Utils.State.DISCONNECTED;
3720+ break;
3721+ case NM.DeviceState.DISCONNECTED:
3722+ request_scan ();
3723+ state = Network.Utils.State.DISCONNECTED;
3724+ break;
3725+ case NM.DeviceState.PREPARE:
3726+ case NM.DeviceState.CONFIG:
3727+ case NM.DeviceState.NEED_AUTH:
3728+ case NM.DeviceState.IP_CONFIG:
3729+ case NM.DeviceState.IP_CHECK:
3730+ case NM.DeviceState.SECONDARIES:
3731+ request_scan ();
3732+ state = Network.Utils.State.CONNECTING_WIFI;
3733+ break;
3734+ case NM.DeviceState.ACTIVATED:
3735+ request_scan ();
3736+
3737+ /* That can happen if active_ap has not been added yet, at startup. */
3738+ if (active_ap != null) {
3739+ state = strength_to_state (active_ap.get_strength ());
3740+ } else {
3741+ state = Network.Utils.State.CONNECTED_WIFI_WEAK;
3742+ }
3743+
3744+ break;
3745+ }
3746+
3747+ software_locked = false;
3748+ foreach (var device in rfkill.get_devices ()) {
3749+ if (device.device_type != RFKillDeviceType.WLAN) {
3750+ continue;
3751+ }
3752+
3753+ if (!software_locked && device.software_lock) {
3754+ software_locked = true;
3755+ break;
3756+ }
3757+ }
3758+
3759+ update_active_ap ();
3760+ base.update ();
3761+ }
3762+
3763+ private void cancel_scan () {
3764+ if (timeout_scan > 0) {
3765+ Source.remove (timeout_scan);
3766+ timeout_scan = 0;
3767+ }
3768+ }
3769+
3770+ private void request_scan () {
3771+ // this state is the previous state (because this method is called before putting the new state)
3772+ if (state != Network.Utils.State.DISCONNECTED) {
3773+ return;
3774+ }
3775+
3776+ placeholder.visible_child_name = "scanning";
3777+ cancel_scan ();
3778+ wifi_device.request_scan_simple (null);
3779+ timeout_scan = Timeout.add (5000, () => {
3780+#if PLUG_NETWORK
3781+ if (Utils.Hotspot.get_device_is_hotspot (wifi_device, settings)) {
3782+ return false;
3783+ }
3784+#endif
3785+ timeout_scan = 0;
3786+ placeholder.visible_child_name = "no-aps";
3787+ return false;
3788+ });
3789+ }
3790+
3791+ private int sort_func (Gtk.ListBoxRow r1, Gtk.ListBoxRow r2) {
3792+ if (r1 == null || r2 == null) {
3793+ return 0;
3794+ }
3795+
3796+ var w1 = (WifiMenuItem)r1;
3797+ var w2 = (WifiMenuItem)r2;
3798+
3799+ if (w1.ap.get_strength () > w2.ap.get_strength ()) {
3800+ return -1;
3801+ } else if (w1.ap.get_strength () < w2.ap.get_strength ()) {
3802+ return 1;
3803+ }
3804+
3805+ return 0;
3806+ }
3807+}
3808
3809=== added file 'src/shared/HotspotDialog.vala'
3810--- src/shared/HotspotDialog.vala 1970-01-01 00:00:00 +0000
3811+++ src/shared/HotspotDialog.vala 2016-11-20 19:56:12 +0000
3812@@ -0,0 +1,226 @@
3813+/*-
3814+ * Copyright (c) 2015-2016 elementary LLC.
3815+ *
3816+ * This program is free software: you can redistribute it and/or modify
3817+ * it under the terms of the GNU Lesser General Public License as published by
3818+ * the Free Software Foundation, either version 2.1 of the License, or
3819+ * (at your option) any later version.
3820+ *
3821+ * This program is distributed in the hope that it will be useful,
3822+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3823+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3824+ * GNU Lesser General Public License for more details.
3825+ *
3826+ * You should have received a copy of the GNU Lesser General Public License
3827+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3828+ *
3829+ * Authored by: Adam Bieńkowski <donadigos159@gmail.com>
3830+ */
3831+
3832+namespace Network.Widgets {
3833+ public class HotspotDialog : Gtk.Dialog {
3834+ private const string NEW_ID = "0";
3835+ private Gtk.Entry ssid_entry;
3836+ private Gtk.Entry key_entry;
3837+
3838+ private Gtk.Label ssid_label;
3839+ private Gtk.Label key_label;
3840+
3841+ private Gtk.ComboBoxText conn_combo;
3842+
3843+ private Gtk.CheckButton check_btn;
3844+ private Gtk.Label dumb;
3845+
3846+ private Gtk.Button create_btn;
3847+
3848+ private HashTable<string, NM.Connection> conn_hash;
3849+ private unowned List<NM.Connection> available;
3850+
3851+ public HotspotDialog (NM.AccessPoint? active, List<NM.Connection> _available) {
3852+ this.available = _available;
3853+ this.deletable = false;
3854+ this.resizable = false;
3855+ this.border_width = 6;
3856+
3857+ conn_hash = new HashTable<string, NM.Connection> (str_hash, str_equal);
3858+
3859+ var content_area = this.get_content_area ();
3860+ content_area.halign = content_area.valign = Gtk.Align.CENTER;
3861+
3862+ var main_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
3863+ var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
3864+
3865+ vbox.margin_left = vbox.margin_right = 6;
3866+
3867+ string? ssid_str = null;
3868+ if (active != null) {
3869+ ssid_str = NM.Utils.ssid_to_utf8 (active.get_ssid ());
3870+ } else {
3871+ ssid_str = _("current");
3872+ }
3873+
3874+ var title = new Gtk.Label ("<span weight='bold' size='larger'>" + _("Wireless Hotspot") + "</span>");
3875+ title.use_markup = true;
3876+ title.halign = Gtk.Align.START;
3877+
3878+ var image = new Gtk.Image.from_icon_name ("network-wireless-hotspot", Gtk.IconSize.DIALOG);
3879+ image.valign = Gtk.Align.START;
3880+ main_box.add (image);
3881+
3882+ var info_label = new Gtk.Label (_("Enabling Wireless Hotspot will disconnect from %s network.").printf (ssid_str) + "\n" +
3883+ _("You will not be able to connect to a wireless network while Hotspot is active."));
3884+ info_label.halign = Gtk.Align.START;
3885+ info_label.margin_top = 6;
3886+ info_label.use_markup = true;
3887+
3888+ var grid = new Gtk.Grid ();
3889+ grid.hexpand = true;
3890+ grid.row_spacing = 6;
3891+ grid.column_spacing = 12;
3892+ grid.vexpand_set = true;
3893+
3894+ ssid_entry = new Gtk.Entry ();
3895+ ssid_entry.hexpand = true;
3896+ ssid_entry.text = get_ssid_for_hotspot ();
3897+
3898+ key_entry = new Gtk.Entry ();
3899+ key_entry.hexpand = true;
3900+ key_entry.visibility = false;
3901+ key_entry.secondary_icon_tooltip_text = _("Password needs to be at least 8 characters long.");
3902+
3903+ check_btn = new Gtk.CheckButton.with_label (_("Show Password"));
3904+ check_btn.toggled.connect (() => {
3905+ key_entry.visibility = check_btn.active;
3906+ });
3907+
3908+ ssid_entry.changed.connect (update);
3909+ key_entry.changed.connect (update);
3910+
3911+ ssid_label = new Gtk.Label (_("Network Name:"));
3912+ ssid_label.halign = Gtk.Align.END;
3913+
3914+ key_label = new Gtk.Label (_("Password:"));
3915+ key_label.halign = Gtk.Align.END;
3916+
3917+ conn_combo = new Gtk.ComboBoxText ();
3918+ conn_combo.append (NEW_ID, _("New…"));
3919+ int i = 1;
3920+ foreach (var connection in available) {
3921+ var setting_wireless = connection.get_setting_wireless ();
3922+ conn_combo.append (i.to_string (), NM.Utils.ssid_to_utf8 (setting_wireless.get_ssid ()));
3923+ conn_hash.insert (i.to_string (), connection);
3924+ i++;
3925+ }
3926+
3927+ conn_combo.active_id = NEW_ID;
3928+ conn_combo.changed.connect (update);
3929+
3930+ var conn_label = new Gtk.Label (_("Connection:"));
3931+ conn_label.halign = Gtk.Align.END;
3932+
3933+ grid.attach (conn_label, 0, 0, 1, 1);
3934+ grid.attach_next_to (conn_combo, conn_label, Gtk.PositionType.RIGHT, 1, 1);
3935+
3936+ dumb = new Gtk.Label ("");
3937+
3938+ grid.attach_next_to (ssid_label, conn_label, Gtk.PositionType.BOTTOM, 1, 1);
3939+ grid.attach_next_to (ssid_entry, ssid_label, Gtk.PositionType.RIGHT, 1, 1);
3940+ grid.attach_next_to (key_label, ssid_label, Gtk.PositionType.BOTTOM, 1, 1);
3941+ grid.attach_next_to (key_entry, key_label, Gtk.PositionType.RIGHT, 1, 1);
3942+ grid.attach_next_to (dumb, key_label, Gtk.PositionType.BOTTOM, 1, 1);
3943+ grid.attach_next_to (check_btn, dumb, Gtk.PositionType.RIGHT, 1, 1);
3944+
3945+ var cancel_btn = new Gtk.Button.with_label (_("Cancel"));
3946+ create_btn = new Gtk.Button.with_label (_("Enable Hotspot"));
3947+ if (active != null) {
3948+ create_btn.label = _("Switch to Hotspot");
3949+ }
3950+
3951+ create_btn.get_style_context ().add_class ("suggested-action");
3952+
3953+ this.add_action_widget (cancel_btn, 0);
3954+ this.add_action_widget (create_btn, 1);
3955+
3956+ vbox.add (title);
3957+ vbox.add (info_label);
3958+ vbox.add (grid);
3959+
3960+ update ();
3961+
3962+ main_box.add (vbox);
3963+ content_area.add (main_box);
3964+ this.show_all ();
3965+ }
3966+
3967+ public ByteArray get_ssid () {
3968+ var byte_array = new ByteArray ();
3969+ byte_array.append (ssid_entry.get_text ().data);
3970+ return byte_array;
3971+ }
3972+
3973+ public string get_key () {
3974+ return key_entry.get_text ();
3975+ }
3976+
3977+ public NM.Connection? get_selected_connection () {
3978+ return conn_hash[conn_combo.get_active_id ()];
3979+ }
3980+
3981+ private string get_ssid_for_hotspot () {
3982+ string hostname = "";
3983+ try {
3984+ Process.spawn_command_line_sync ("hostname", out hostname, null, null);
3985+ } catch (SpawnError e) {
3986+ warning ("%s\n", e.message);
3987+ }
3988+
3989+ return hostname.strip ().replace ("\n", "");
3990+ }
3991+
3992+ private void update () {
3993+ bool sensitive = (conn_combo.get_active_id () == NEW_ID);
3994+ ssid_label.sensitive = sensitive;
3995+ key_label.sensitive = sensitive;
3996+
3997+ ssid_entry.sensitive = sensitive;
3998+ key_entry.sensitive = sensitive;
3999+
4000+ check_btn.sensitive = sensitive;
4001+ dumb.sensitive = sensitive;
4002+
4003+ string? secret = null;
4004+ if (get_selected_connection () != null) {
4005+ var setting_wireless_security = get_selected_connection ().get_setting_wireless_security ();
4006+
4007+ string key_mgmt = setting_wireless_security.get_key_mgmt ();
4008+ if (key_mgmt == "none") {
4009+ secret = setting_wireless_security.get_wep_key (0);
4010+ } else if (key_mgmt == "wpa-psk" || key_mgmt == "wpa-none") {
4011+ secret = setting_wireless_security.get_psk ();
4012+ }
4013+
4014+ if (secret == null) {
4015+ var connection = get_selected_connection ();
4016+ Utils.Hotspot.update_secrets (((NM.RemoteConnection) connection), update);
4017+ }
4018+ }
4019+
4020+ if (conn_combo.get_active_id () != NEW_ID) {
4021+ ssid_entry.text = NM.Utils.ssid_to_utf8 (get_selected_connection ().get_setting_wireless ().get_ssid ());
4022+ if (secret == null) {
4023+ secret = "";
4024+ }
4025+
4026+ key_entry.text = secret;
4027+ }
4028+
4029+ create_btn.sensitive = ((ssid_entry.get_text () != "" && key_entry.get_text ().to_utf8 ().length >= 8) || !sensitive);
4030+
4031+ if (key_entry.get_text ().to_utf8 ().length < 8 && key_entry.get_text () != "") {
4032+ key_entry.set_icon_from_icon_name (Gtk.EntryIconPosition.SECONDARY, "process-error-symbolic");
4033+ } else {
4034+ key_entry.set_icon_from_icon_name (Gtk.EntryIconPosition.SECONDARY, "");
4035+ }
4036+ }
4037+ }
4038+}
4039\ No newline at end of file
4040
4041=== added file 'src/shared/PlaceholderLabel.vala'
4042--- src/shared/PlaceholderLabel.vala 1970-01-01 00:00:00 +0000
4043+++ src/shared/PlaceholderLabel.vala 2016-11-20 19:56:12 +0000
4044@@ -0,0 +1,34 @@
4045+/*
4046+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
4047+ *
4048+ * This program is free software: you can redistribute it and/or modify
4049+ * it under the terms of the GNU Library General Public License as published by
4050+ * the Free Software Foundation, either version 2.1 of the License, or
4051+ * (at your option) any later version.
4052+ *
4053+ * This program is distributed in the hope that it will be useful,
4054+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4055+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4056+ * GNU Library General Public License for more details.
4057+ *
4058+ * You should have received a copy of the GNU Library General Public License
4059+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4060+ */
4061+
4062+public class Network.Widgets.PlaceholderLabel : Gtk.Label {
4063+ public PlaceholderLabel (string text, bool title) {
4064+ label = text;
4065+ visible = true;
4066+ use_markup = true;
4067+ wrap = true;
4068+ wrap_mode = Pango.WrapMode.WORD_CHAR;
4069+ max_width_chars = 30;
4070+ justify = Gtk.Justification.CENTER;
4071+
4072+#if PLUG_NETWORK
4073+ if (title) {
4074+ get_style_context ().add_class ("h2");
4075+ }
4076+#endif
4077+ }
4078+}
4079\ No newline at end of file
4080
4081=== added file 'src/shared/RFKill.vala'
4082--- src/shared/RFKill.vala 1970-01-01 00:00:00 +0000
4083+++ src/shared/RFKill.vala 2016-11-20 19:56:12 +0000
4084@@ -0,0 +1,168 @@
4085+/*
4086+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
4087+ * Copyright (C) 2012 Canonical Ltd.
4088+ *
4089+ * This program is free software: you can redistribute it and/or modify
4090+ * it under the terms of the GNU Library General Public License as published by
4091+ * the Free Software Foundation, either version 2.1 of the License, or
4092+ * (at your option) any later version.
4093+ *
4094+ * This program is distributed in the hope that it will be useful,
4095+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4096+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4097+ * GNU Library General Public License for more details.
4098+ *
4099+ * You should have received a copy of the GNU Library General Public License
4100+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4101+ */
4102+
4103+/*
4104+ *
4105+ * Author: Robert Ancell <robert.ancell@canonical.com>
4106+ *
4107+ * This program is free software: you can redistribute it and/or modify it under
4108+ * the terms of the GNU General Public License as published by the Free Software
4109+ * Foundation, either version 3 of the License, or (at your option) any later
4110+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
4111+ * license.
4112+ */
4113+
4114+namespace Network {
4115+ public enum RFKillDeviceType {
4116+ ALL = 0,
4117+ WLAN,
4118+ BLUETOOTH,
4119+ UWB,
4120+ WIMAX,
4121+ WMAN
4122+ }
4123+
4124+ private struct RFKillEvent {
4125+ uint32 idx;
4126+ uint8 type;
4127+ uint8 op;
4128+ uint8 soft;
4129+ uint8 hard;
4130+ }
4131+
4132+ private enum RFKillOperation {
4133+ ADD = 0,
4134+ DELETE,
4135+ CHANGE,
4136+ CHANGE_ALL
4137+ }
4138+
4139+ public class RFKillDevice : Object {
4140+ public signal void changed ();
4141+
4142+ private bool _software_lock;
4143+ public bool software_lock {
4144+ get { return _software_lock; }
4145+ set {
4146+ var event = RFKillEvent ();
4147+ event.idx = idx;
4148+ event.op = RFKillOperation.CHANGE;
4149+ event.soft = value ? 1 : 0;
4150+
4151+ _software_lock = value;
4152+ Posix.write (manager.fd, &event, 8);
4153+ }
4154+ }
4155+
4156+ public bool hardware_lock;
4157+ public RFKillDeviceType device_type;
4158+ public uint32 idx;
4159+
4160+ private RFKillManager manager;
4161+
4162+ public RFKillDevice (RFKillManager manager, uint32 idx, RFKillDeviceType device_type, bool software_lock, bool hardware_lock) {
4163+ this.manager = manager;
4164+ this.idx = idx;
4165+ this.device_type = device_type;
4166+ this.software_lock = software_lock;
4167+ this.hardware_lock = hardware_lock;
4168+ }
4169+ }
4170+
4171+ public class RFKillManager : Object {
4172+ public signal void device_added (RFKillDevice device);
4173+ public signal void device_changed (RFKillDevice device);
4174+ public signal void device_deleted (RFKillDevice device);
4175+
4176+ public int fd = -1;
4177+ private List<RFKillDevice> devices;
4178+
4179+ public RFKillManager () {
4180+ devices = new List<RFKillDevice> ();
4181+ }
4182+
4183+ public void open () {
4184+ fd = Posix.open ("/dev/rfkill", Posix.O_RDWR);
4185+ Posix.fcntl (fd, Posix.F_SETFL, Posix.O_NONBLOCK);
4186+
4187+ /* Read initial state */
4188+ while (read_event ());
4189+
4190+ /* Monitor for events */
4191+ var channel = new IOChannel.unix_new (fd);
4192+ channel.add_watch (IOCondition.IN | IOCondition.HUP | IOCondition.ERR, () => { return read_event (); });
4193+ }
4194+
4195+ public unowned List<RFKillDevice> get_devices () {
4196+ return devices;
4197+ }
4198+
4199+ public void set_software_lock (RFKillDeviceType type, bool lock_enabled) {
4200+ var event = RFKillEvent ();
4201+ event.type = type;
4202+ event.op = RFKillOperation.CHANGE_ALL;
4203+ event.soft = lock_enabled ? 1 : 0;
4204+ Posix.write (fd, &event, 8);
4205+ }
4206+
4207+ private bool read_event () {
4208+ var event = RFKillEvent ();
4209+ if (Posix.read (fd, &event, 8) != 8) {
4210+ return false;
4211+ }
4212+
4213+ switch (event.op) {
4214+ case RFKillOperation.ADD:
4215+ var device = new RFKillDevice (this, event.idx, (RFKillDeviceType)event.type, event.soft != 0, event.hard != 0);
4216+ devices.append (device);
4217+ device_added (device);
4218+ break;
4219+ case RFKillOperation.DELETE:
4220+ var device = get_device_from_index (event.idx);
4221+ if (device != null) {
4222+ devices.remove (device);
4223+ device_deleted (device);
4224+ }
4225+
4226+ break;
4227+ case RFKillOperation.CHANGE:
4228+ var device = get_device_from_index (event.idx);
4229+ if (device != null) {
4230+ device.software_lock = event.soft != 0;
4231+ device.hardware_lock = event.hard != 0;
4232+ device.changed ();
4233+ device_changed (device);
4234+ }
4235+
4236+ break;
4237+ }
4238+
4239+ return true;
4240+ }
4241+
4242+ private RFKillDevice? get_device_from_index (uint32 idx) {
4243+ foreach (var device in devices) {
4244+ if (device.idx == idx) {
4245+ return device;
4246+ }
4247+ }
4248+
4249+ return null;
4250+ }
4251+ }
4252+}
4253\ No newline at end of file
4254
4255=== added file 'src/shared/Utils.vala'
4256--- src/shared/Utils.vala 1970-01-01 00:00:00 +0000
4257+++ src/shared/Utils.vala 2016-11-20 19:56:12 +0000
4258@@ -0,0 +1,385 @@
4259+/*
4260+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
4261+ *
4262+ * This program is free software: you can redistribute it and/or modify
4263+ * it under the terms of the GNU Library General Public License as published by
4264+ * the Free Software Foundation, either version 2.1 of the License, or
4265+ * (at your option) any later version.
4266+ *
4267+ * This program is distributed in the hope that it will be useful,
4268+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4269+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4270+ * GNU Library General Public License for more details.
4271+ *
4272+ * You should have received a copy of the GNU Library General Public License
4273+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4274+ */
4275+
4276+namespace Network.Utils {
4277+ public const string UNKNOWN_STR = N_("Unknown");
4278+
4279+ namespace Hotspot {
4280+ public delegate void UpdateSecretCallback ();
4281+
4282+ public static void activate_hotspot (NM.DeviceWifi wifi_device,
4283+ ByteArray ssid,
4284+ string key,
4285+ NM.Connection? selected) {
4286+ if (selected != null) {
4287+ client.activate_connection (selected, wifi_device, null, null);
4288+ return;
4289+ }
4290+
4291+ var hotspot_c = new NM.Connection ();
4292+
4293+ var setting_connection = new NM.SettingConnection ();
4294+ setting_connection.set (NM.SettingConnection.TYPE, "802-11-wireless");
4295+ setting_connection.set (NM.SettingConnection.ID, "Hotspot");
4296+ setting_connection.autoconnect = false;
4297+ hotspot_c.add_setting (setting_connection);
4298+
4299+ var setting_wireless = new NM.SettingWireless ();
4300+
4301+ string? mode = null;
4302+ var caps = wifi_device.get_capabilities ();
4303+ if ((caps & NM.DeviceWifiCapabilities.AP) != 0) {
4304+ mode = NM.SettingWireless.MODE_AP;
4305+ } else {
4306+ mode = NM.SettingWireless.MODE_ADHOC;
4307+ }
4308+
4309+ setting_wireless.mode = mode;
4310+ setting_wireless.security = "802-11-wireless-security";
4311+
4312+ hotspot_c.add_setting (setting_wireless);
4313+
4314+ var ip4_setting = new NM.SettingIP4Config ();
4315+ ip4_setting.method = "shared";
4316+ hotspot_c.add_setting (ip4_setting);
4317+
4318+ setting_wireless.set (NM.SettingWireless.SSID, ssid);
4319+
4320+ var setting_wireless_security = new NM.SettingWirelessSecurity ();
4321+
4322+ if (mode == NM.SettingWireless.MODE_AP) {
4323+ if ((caps & NM.DeviceWifiCapabilities.RSN) != 0) {
4324+ set_wpa_key (setting_wireless_security, key);
4325+ setting_wireless_security.add_proto ("rsn");
4326+ setting_wireless_security.add_pairwise ("ccmp");
4327+ setting_wireless_security.add_group ("ccmp");
4328+ } else if ((caps & NM.DeviceWifiCapabilities.WPA) != 0) {
4329+ set_wpa_key (setting_wireless_security, key);
4330+ setting_wireless_security.add_proto ("wpa");
4331+ setting_wireless_security.add_pairwise ("tkip");
4332+ setting_wireless_security.add_group ("tkip");
4333+ } else {
4334+ set_wep_key (setting_wireless_security, key);
4335+ }
4336+ } else {
4337+ set_wep_key (setting_wireless_security, key);
4338+ }
4339+
4340+ hotspot_c.add_setting (setting_wireless_security);
4341+ client.add_and_activate_connection (hotspot_c,
4342+ wifi_device,
4343+ null,
4344+ finish_connection_cb);
4345+ }
4346+
4347+ public static void update_secrets (NM.RemoteConnection connection, UpdateSecretCallback callback) {
4348+ connection.get_secrets (connection.get_setting_wireless ().get_security (), ((_connection, secrets, error) => {
4349+ var setting_wireless = _connection.get_setting_wireless ();
4350+ try {
4351+ _connection.update_secrets (setting_wireless.get_security (), secrets);
4352+ } catch (Error e) {
4353+ warning ("%s\n", e.message);
4354+ return;
4355+ }
4356+
4357+ callback ();
4358+ }));
4359+ }
4360+
4361+ public static void deactivate_hotspot (NM.DeviceWifi wifi_device) {
4362+ client.get_active_connections ().foreach ((active_connection) => {
4363+ var devices = active_connection.get_devices ();
4364+ if (devices != null && devices.get (0) == wifi_device) {
4365+ client.deactivate_connection (active_connection);
4366+ }
4367+ });
4368+ }
4369+
4370+ private static void set_wpa_key (NM.SettingWirelessSecurity setting, string key) {
4371+ setting.key_mgmt = "wpa-psk";
4372+ setting.psk = key;
4373+ }
4374+
4375+ private static void set_wep_key (NM.SettingWirelessSecurity setting, string key) {
4376+ setting.key_mgmt = "none";
4377+ setting.wep_key0 = key;
4378+ setting.wep_key_type = NM.WepKeyType.PASSPHRASE;
4379+ }
4380+
4381+ public static bool get_device_is_hotspot (NM.DeviceWifi wifi_device, NM.RemoteSettings nm_settings) {
4382+ if (wifi_device.get_active_connection () != null) {
4383+ var connection = nm_settings.get_connection_by_path (wifi_device.get_active_connection ().get_connection ());
4384+ if (connection != null) {
4385+ var ip4_setting = connection.get_setting_ip4_config ();
4386+ return (ip4_setting != null && ip4_setting.get_method () == "shared");
4387+ }
4388+ }
4389+
4390+ return false;
4391+ }
4392+
4393+ public static List<NM.Connection> get_hotspot_connections (NM.RemoteSettings settings) {
4394+ var list = new List<NM.Connection> ();
4395+ var connections = settings.list_connections ();
4396+
4397+ foreach (var connection in connections) {
4398+ if (Utils.Hotspot.get_connection_is_hotspot (connection)) {
4399+ list.append (connection);
4400+ }
4401+ }
4402+
4403+ return list;
4404+ }
4405+
4406+ public static bool get_connection_is_hotspot (NM.Connection connection) {
4407+ var setting_connection = connection.get_setting_connection ();
4408+ if (setting_connection.get_connection_type () != "802-11-wireless") {
4409+ return false;
4410+ }
4411+
4412+ var setting_wireless = connection.get_setting_wireless ();
4413+ if (setting_wireless.get_mode () != "adhoc" && setting_wireless.get_mode () != "ap") {
4414+ return false;
4415+ }
4416+
4417+ if (setting_wireless.get_security () != "802-11-wireless-security") {
4418+ return false;
4419+ }
4420+
4421+ var ip4_config = connection.get_setting_ip4_config ();
4422+ if (ip4_config.get_method () != "shared") {
4423+ return false;
4424+ }
4425+
4426+ return true;
4427+ }
4428+
4429+ private static void finish_connection_cb (NM.Client? cb_client,
4430+ NM.ActiveConnection? cb_connection,
4431+ string? new_connection_path,
4432+ Error? error) {
4433+ if (error != null && error.code != 0) {
4434+ warning ("%s\n", error.message);
4435+ }
4436+ }
4437+ }
4438+
4439+ namespace WiFi {
4440+ public static void activate_secured_access_point (NM.Client client,
4441+ NM.RemoteSettings settings,
4442+ NM.Device wifi_device,
4443+ NM.AccessPoint ap) {
4444+ var connection = new NM.Connection ();
4445+ var s_con = new NM.SettingConnection ();
4446+ s_con.set (NM.SettingConnection.UUID, NM.Utils.uuid_generate ());
4447+ connection.add_setting (s_con);
4448+
4449+ var s_wifi = new NM.SettingWireless ();
4450+ s_wifi.set (NM.SettingWireless.SSID, ap.get_ssid ());
4451+ connection.add_setting (s_wifi);
4452+
4453+ var s_wsec = new NM.SettingWirelessSecurity ();
4454+ s_wsec.set (NM.SettingWirelessSecurity.KEY_MGMT, "wpa-psk");
4455+ connection.add_setting (s_wsec);
4456+
4457+ var wifi_dialog = new NMAWifiDialog (client,
4458+ settings,
4459+ connection,
4460+ wifi_device,
4461+ ap,
4462+ false);
4463+
4464+ wifi_dialog.response.connect ((response) => wifi_dialog_response_cb (wifi_dialog, response, client, settings));
4465+
4466+ wifi_dialog.run ();
4467+ wifi_dialog.destroy ();
4468+ }
4469+
4470+ public static void connect_to_hidden_access_point (NM.Client client, NM.RemoteSettings settings) {
4471+ var hidden_dialog = new NMAWifiDialog.for_other (client, settings);
4472+ hidden_dialog.response.connect ((response) => wifi_dialog_response_cb (hidden_dialog, response, client, settings));
4473+ hidden_dialog.run ();
4474+ hidden_dialog.destroy ();
4475+ }
4476+
4477+ private static void wifi_dialog_response_cb (NMAWifiDialog dialog, int response, NM.Client client, NM.RemoteSettings settings) {
4478+ if (response != Gtk.ResponseType.OK) {
4479+ return;
4480+ }
4481+
4482+ NM.Connection? fuzzy = null;
4483+ NM.Device device;
4484+ NM.AccessPoint ap;
4485+ var connection = dialog.get_connection (out device, out ap);
4486+
4487+ foreach (var possible in settings.list_connections ()) {
4488+ if (connection.compare (possible, NM.SettingCompareFlags.FUZZY | NM.SettingCompareFlags.IGNORE_ID)) {
4489+ fuzzy = possible;
4490+ }
4491+ }
4492+
4493+ if (fuzzy != null) {
4494+ client.activate_connection (fuzzy, device, ap.get_path (), null);
4495+ } else {
4496+ var connection_setting = connection.get_setting (typeof (NM.Setting));;
4497+
4498+ string mode = "";
4499+ var setting_wireless = (NM.SettingWireless) connection.get_setting (typeof (NM.SettingWireless));
4500+ if (setting_wireless != null) {
4501+ mode = setting_wireless.get_mode ();
4502+ }
4503+
4504+ if (mode == "adhoc") {
4505+ if (connection_setting == null) {
4506+ connection_setting = new NM.SettingConnection ();
4507+ }
4508+
4509+ connection.add_setting (connection_setting);
4510+ }
4511+
4512+ client.add_and_activate_connection (connection,
4513+ device,
4514+ ap.get_path (),
4515+ Utils.finish_connection_cb);
4516+ }
4517+ }
4518+ }
4519+
4520+ public enum State {
4521+ DISCONNECTED,
4522+ WIRED_UNPLUGGED,
4523+ CONNECTED_WIRED,
4524+ CONNECTED_VPN,
4525+ CONNECTED_WIFI,
4526+ CONNECTED_WIFI_WEAK,
4527+ CONNECTED_WIFI_OK,
4528+ CONNECTED_WIFI_GOOD,
4529+ CONNECTED_WIFI_EXCELLENT,
4530+ CONNECTING_WIFI,
4531+ CONNECTING_WIRED,
4532+ CONNECTING_VPN,
4533+ FAILED_WIRED,
4534+ FAILED_WIFI,
4535+ FAILED_VPN;
4536+
4537+ public string to_localized_string () {
4538+ switch (this) {
4539+ case Network.Utils.State.DISCONNECTED:
4540+ return _("Disconnected");
4541+ case Network.Utils.State.CONNECTED_WIFI:
4542+ case Network.Utils.State.CONNECTED_WIFI_WEAK:
4543+ case Network.Utils.State.CONNECTED_WIFI_OK:
4544+ case Network.Utils.State.CONNECTED_WIFI_GOOD:
4545+ case Network.Utils.State.CONNECTED_WIFI_EXCELLENT:
4546+ case Network.Utils.State.CONNECTED_WIRED:
4547+ case Network.Utils.State.CONNECTED_VPN:
4548+ return _("Connected");
4549+ case Network.Utils.State.FAILED_WIRED:
4550+ case Network.Utils.State.FAILED_WIFI:
4551+ case Network.Utils.State.FAILED_VPN:
4552+ return _("Failed");
4553+ case Network.Utils.State.CONNECTING_WIFI:
4554+ case Network.Utils.State.CONNECTING_WIRED:
4555+ case Network.Utils.State.CONNECTING_VPN:
4556+ return _("Connecting");
4557+ case Network.Utils.State.WIRED_UNPLUGGED:
4558+ return _("Cable unplugged");
4559+ }
4560+
4561+ return UNKNOWN_STR;
4562+ }
4563+ }
4564+
4565+ public static void set_widget_visible (Gtk.Widget widget, bool visible) {
4566+ widget.no_show_all = !visible;
4567+ widget.visible = visible;
4568+ }
4569+
4570+ public static string device_state_to_string (NM.DeviceState state) {
4571+ switch (state) {
4572+ case NM.DeviceState.ACTIVATED:
4573+ return _("Connected");
4574+ case NM.DeviceState.DISCONNECTED:
4575+ return _("Disconnected");
4576+ case NM.DeviceState.UNMANAGED:
4577+ return _("Unmanaged");
4578+ case NM.DeviceState.PREPARE:
4579+ return _("In preparation");
4580+ case NM.DeviceState.CONFIG:
4581+ return _("Connecting…");
4582+ case NM.DeviceState.NEED_AUTH:
4583+ return _("Requires more information");
4584+ case NM.DeviceState.IP_CONFIG:
4585+ return _("Requesting adresses...");
4586+ case NM.DeviceState.IP_CHECK:
4587+ return _("Checking connection...");
4588+ case NM.DeviceState.SECONDARIES:
4589+ return _("Waiting for connection...");
4590+ case NM.DeviceState.DEACTIVATING:
4591+ return _("Disconnecting...");
4592+ case NM.DeviceState.FAILED:
4593+ return _("Failed to connect");
4594+ case NM.DeviceState.UNKNOWN:
4595+ default:
4596+ return UNKNOWN_STR;
4597+ }
4598+ }
4599+
4600+ public static string device_type_to_string (NM.DeviceType type) {
4601+ switch (type) {
4602+ case NM.DeviceType.ETHERNET:
4603+ return _("Ethernet");
4604+ case NM.DeviceType.WIFI:
4605+ return _("Wi-Fi");
4606+ case NM.DeviceType.UNUSED1:
4607+ return _("Not used");
4608+ case NM.DeviceType.UNUSED2:
4609+ return _("Not used");
4610+ case NM.DeviceType.BT:
4611+ return _("Bluetooth");
4612+ case NM.DeviceType.OLPC_MESH:
4613+ return _("OLPC XO");
4614+ case NM.DeviceType.WIMAX:
4615+ return _("WiMAX Broadband");
4616+ case NM.DeviceType.MODEM:
4617+ return _("Modem");
4618+ case NM.DeviceType.INFINIBAND:
4619+ return _("InfiniBand device");
4620+ case NM.DeviceType.BOND:
4621+ return _("Bond master");
4622+ case NM.DeviceType.VLAN:
4623+ return _("VLAN Interface");
4624+ case NM.DeviceType.ADSL:
4625+ return _("ADSL Modem");
4626+ case NM.DeviceType.BRIDGE:
4627+ return _("Bridge master");
4628+ case NM.DeviceType.UNKNOWN:
4629+ default:
4630+ return UNKNOWN_STR;
4631+ }
4632+ }
4633+
4634+ public static void finish_connection_cb (NM.Client? cb_client,
4635+ NM.ActiveConnection? cb_connection,
4636+ string? new_connection_path,
4637+ Error? error) {
4638+ if (error != null && error.code != 0) {
4639+ warning ("%s\n", error.message);
4640+ }
4641+ }
4642+}
4643+
4644
4645=== added file 'src/shared/VPNMenuItem.vala'
4646--- src/shared/VPNMenuItem.vala 1970-01-01 00:00:00 +0000
4647+++ src/shared/VPNMenuItem.vala 2016-11-20 19:56:12 +0000
4648@@ -0,0 +1,112 @@
4649+/*
4650+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
4651+ *
4652+ * This program is free software: you can redistribute it and/or modify
4653+ * it under the terms of the GNU Library General Public License as published by
4654+ * the Free Software Foundation, either version 2.1 of the License, or
4655+ * (at your option) any later version.
4656+ *
4657+ * This program is distributed in the hope that it will be useful,
4658+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4659+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4660+ * GNU Library General Public License for more details.
4661+ *
4662+ * You should have received a copy of the GNU Library General Public License
4663+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4664+ */
4665+
4666+public class Network.VPNMenuItem : Gtk.ListBoxRow {
4667+ public signal void activated ();
4668+ public NM.RemoteConnection? connection;
4669+
4670+ public Network.Utils.State state { get; set; default = Network.Utils.State.DISCONNECTED; }
4671+
4672+ private Gtk.RadioButton radio_button;
4673+ private Gtk.Spinner spinner;
4674+ private Gtk.Image error_img;
4675+ private Gtk.Button remove_button;
4676+
4677+ public VPNMenuItem (NM.RemoteConnection connection, VPNMenuItem? previous = null) {
4678+ this.connection = connection;
4679+
4680+ var main_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
4681+ main_box.margin_start = main_box.margin_end = 6;
4682+ radio_button = new Gtk.RadioButton (null);
4683+ if (previous != null) {
4684+ radio_button.set_group (previous.get_group ());
4685+ }
4686+
4687+ radio_button.button_release_event.connect (() => {
4688+ activated ();
4689+ return false;
4690+ });
4691+
4692+ error_img = new Gtk.Image.from_icon_name ("process-error-symbolic", Gtk.IconSize.MENU);
4693+ error_img.set_tooltip_text (_("This Virtual Private Network could not be connected to."));
4694+
4695+ spinner = new Gtk.Spinner();
4696+ spinner.visible = false;
4697+ spinner.no_show_all = !spinner.visible;
4698+
4699+ remove_button = new Gtk.Button.from_icon_name ("user-trash-symbolic", Gtk.IconSize.MENU);
4700+ remove_button.get_style_context ().add_class ("flat");
4701+ remove_button.clicked.connect (() => {
4702+ connection.delete (null);
4703+ });
4704+
4705+ main_box.pack_start (radio_button, true, true);
4706+ main_box.pack_start (spinner, false, false);
4707+ main_box.pack_start (error_img, false, false);
4708+ main_box.pack_start (remove_button, false, false);
4709+
4710+ notify["state"].connect (update);
4711+ radio_button.notify["active"].connect (update);
4712+ this.add (main_box);
4713+ this.get_style_context ().add_class ("menuitem");
4714+
4715+ connection.changed.connect (update);
4716+ update ();
4717+ }
4718+
4719+ /**
4720+ * Only used for an item which is not displayed: hacky way to have no radio button selected.
4721+ **/
4722+ public VPNMenuItem.blank () {
4723+ radio_button = new Gtk.RadioButton (null);
4724+ }
4725+
4726+ unowned SList get_group () {
4727+ return radio_button.get_group ();
4728+ }
4729+
4730+ public void set_active (bool active) {
4731+ radio_button.set_active (active);
4732+ }
4733+
4734+ private void update () {
4735+ radio_button.label = connection.get_id ();
4736+
4737+ switch (state) {
4738+ case Network.Utils.State.FAILED_VPN:
4739+ Network.Utils.set_widget_visible (error_img, true);
4740+ break;
4741+ case Network.Utils.State.CONNECTING_VPN:
4742+ Network.Utils.set_widget_visible (spinner, true);
4743+ break;
4744+ default:
4745+ hide_icons ();
4746+ break;
4747+ }
4748+ }
4749+
4750+ public void hide_icons (bool show_remove_button = true) {
4751+#if PLUG_NETWORK
4752+ Network.Utils.set_widget_visible (error_img, false);
4753+ Network.Utils.set_widget_visible (spinner, false);
4754+
4755+ if (!show_remove_button) {
4756+ Network.Utils.set_widget_visible (remove_button, false);
4757+ }
4758+#endif
4759+ }
4760+}
4761\ No newline at end of file
4762
4763=== added file 'src/shared/ViewManager.vala'
4764--- src/shared/ViewManager.vala 1970-01-01 00:00:00 +0000
4765+++ src/shared/ViewManager.vala 2016-11-20 19:56:12 +0000
4766@@ -0,0 +1,144 @@
4767+/*
4768+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
4769+ *
4770+ * This program is free software: you can redistribute it and/or modify
4771+ * it under the terms of the GNU Library General Public License as published by
4772+ * the Free Software Foundation, either version 2.1 of the License, or
4773+ * (at your option) any later version.
4774+ *
4775+ * This program is distributed in the hope that it will be useful,
4776+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4777+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4778+ * GNU Library General Public License for more details.
4779+ *
4780+ * You should have received a copy of the GNU Library General Public License
4781+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4782+ */
4783+
4784+public abstract class Network.ViewManager : Gtk.Bin {
4785+ protected NM.Client client;
4786+ protected NM.RemoteSettings settings;
4787+
4788+ protected GLib.List<Widgets.AbstractView> view_list;
4789+
4790+ public Network.Utils.State state;
4791+
4792+ construct {
4793+ view_list = new GLib.List<Widgets.AbstractView> ();
4794+
4795+ /* Monitor network manager */
4796+ client = new NM.Client ();
4797+ settings = new NM.RemoteSettings (null);
4798+ }
4799+
4800+ /*
4801+ * Objects implementing this class need to call this method after
4802+ * the UI initialization is done
4803+ */
4804+ protected void populate () {
4805+ client.device_added.connect (add_device_internal);
4806+ client.device_removed.connect (remove_device_internal);
4807+
4808+ settings.new_connection.connect (new_connection_cb);
4809+
4810+ var devices = client.get_devices ();
4811+ for (var i = 0; i < devices.length; i++) {
4812+ add_device_internal (devices.get (i));
4813+ }
4814+ }
4815+
4816+ /* Objects using this interface need to implement these methods */
4817+ protected abstract void add_view (Widgets.AbstractView widget_interface);
4818+ protected abstract void remove_view (Widgets.AbstractView widget_interface);
4819+ protected abstract void add_connection (NM.RemoteConnection connection);
4820+ protected abstract void remove_connection (NM.RemoteConnection connection);
4821+
4822+ private void add_device_internal (NM.Device device) {
4823+ if (device.get_iface ().has_prefix ("vmnet") ||
4824+ device.get_iface ().has_prefix ("lo")) {
4825+ return;
4826+ }
4827+
4828+ Widgets.AbstractView? view = null;
4829+
4830+ if (device is NM.DeviceWifi) {
4831+ view = new Widgets.WiFiView (client, settings, device);
4832+#if PLUG_NETWORK
4833+ var hotspot_view = new Widgets.HotspotView (client, settings, device);
4834+ view_list.append (hotspot_view);
4835+ add_view (hotspot_view);
4836+ hotspot_view.notify["state"].connect (update_state);
4837+#endif
4838+ } else if (device is NM.DeviceEthernet) {
4839+ view = new Widgets.EthernetView (client, settings, device);
4840+ } else {
4841+ debug ("Unknown device: %s\n", device.get_device_type ().to_string ());
4842+ }
4843+
4844+ if (view != null) {
4845+ view_list.append (view);
4846+ add_view (view);
4847+ view.notify["state"].connect (update_state);
4848+ }
4849+
4850+ update_interfaces_names ();
4851+ update_all ();
4852+ show_all ();
4853+ }
4854+
4855+ private void remove_device_internal (NM.Device device) {
4856+ foreach (var widget_iface in view_list) {
4857+ if (widget_iface.get_device () == device) {
4858+ view_list.remove (widget_iface);
4859+ remove_view (widget_iface);
4860+ break;
4861+ }
4862+ }
4863+
4864+ update_interfaces_names ();
4865+ }
4866+
4867+ private void update_interfaces_names () {
4868+ var count_type = new Gee.HashMap<string, int?> ();
4869+ foreach (var view in view_list) {
4870+ var type = view.get_type ().name ();
4871+
4872+ if (count_type.has_key (type)) {
4873+ count_type[type] = count_type[type] + 1;
4874+ } else {
4875+ count_type[type] = 1;
4876+ }
4877+ }
4878+
4879+ foreach (var iface in view_list) {
4880+ var type = iface.get_type ().name ();
4881+ iface.update_name (count_type [type]);
4882+ }
4883+ }
4884+
4885+ private void new_connection_cb (Object obj) {
4886+ var connection = (NM.RemoteConnection)obj;
4887+ connection.removed.connect (() => {
4888+ remove_connection (connection);
4889+ });
4890+
4891+ add_connection (connection);
4892+ }
4893+
4894+ private void update_all () {
4895+ foreach (var view in view_list) {
4896+ view.update ();
4897+ }
4898+ }
4899+
4900+ private void update_state () {
4901+ var next_state = Network.Utils.State.DISCONNECTED;
4902+ foreach (var view in view_list) {
4903+ if (view.state != Network.Utils.State.DISCONNECTED) {
4904+ next_state = view.state;
4905+ }
4906+ }
4907+
4908+ state = next_state;
4909+ }
4910+}
4911
4912=== added file 'src/shared/WifiMenuItem.vala'
4913--- src/shared/WifiMenuItem.vala 1970-01-01 00:00:00 +0000
4914+++ src/shared/WifiMenuItem.vala 2016-11-20 19:56:12 +0000
4915@@ -0,0 +1,182 @@
4916+/*
4917+ * Copyright (c) 2015 Wingpanel Developers (http://launchpad.net/wingpanel)
4918+ *
4919+ * This program is free software: you can redistribute it and/or modify
4920+ * it under the terms of the GNU Library General Public License as published by
4921+ * the Free Software Foundation, either version 2.1 of the License, or
4922+ * (at your option) any later version.
4923+ *
4924+ * This program is distributed in the hope that it will be useful,
4925+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4926+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4927+ * GNU Library General Public License for more details.
4928+ *
4929+ * You should have received a copy of the GNU Library General Public License
4930+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
4931+ */
4932+
4933+public class Network.WifiMenuItem : Gtk.ListBoxRow {
4934+ public signal void activated ();
4935+ public Network.Utils.State state { get; set; default = Network.Utils.State.DISCONNECTED; }
4936+
4937+ public GLib.ByteArray ssid {
4938+ get {
4939+ return ap.get_ssid ();
4940+ }
4941+ }
4942+
4943+ public uint8 strength {
4944+ get {
4945+ return ap.get_strength ();
4946+ }
4947+ }
4948+
4949+ public bool is_secured {
4950+ get {
4951+ return ap.get_wpa_flags () != NM.@80211ApSecurityFlags.NONE || ap.get_rsn_flags () != NM.@80211ApSecurityFlags.NONE;
4952+ }
4953+ }
4954+
4955+ public NM.AccessPoint? ap;
4956+
4957+ private bool show_icons = true;
4958+
4959+ private Gtk.RadioButton radio_button;
4960+ private Gtk.Image strength_img;
4961+ private Gtk.Image lock_img;
4962+ private Gtk.Image error_img;
4963+ private Gtk.Spinner spinner;
4964+
4965+ public WifiMenuItem (NM.AccessPoint ap, WifiMenuItem? previous = null) {
4966+ this.ap = ap;
4967+
4968+ var main_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
4969+ radio_button = new Gtk.RadioButton (null);
4970+ radio_button.margin_start = 6;
4971+ if (previous != null) {
4972+ radio_button.set_group (previous.get_group ());
4973+ }
4974+
4975+ radio_button.button_release_event.connect (() => {
4976+ activated ();
4977+ return false;
4978+ });
4979+
4980+ strength_img = new Gtk.Image();
4981+ strength_img.margin_end = 6;
4982+
4983+ lock_img = new Gtk.Image.from_icon_name ("channel-secure-symbolic", Gtk.IconSize.MENU);
4984+ lock_img.margin_start = 6;
4985+
4986+ /* TODO: investigate this, it has not been tested yet. */
4987+ error_img = new Gtk.Image.from_icon_name ("process-error-symbolic", Gtk.IconSize.MENU);
4988+ error_img.margin_start = 6;
4989+
4990+ error_img.set_tooltip_text (_("This wireless network could not be connected to."));
4991+
4992+ main_box.pack_start (radio_button, true, true);
4993+
4994+ spinner = new Gtk.Spinner();
4995+ spinner.start ();
4996+
4997+ Network.Utils.set_widget_visible (spinner, false);
4998+
4999+ main_box.pack_start (spinner, false, false);
5000+ main_box.pack_start (error_img, false, false);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: