~khurshid-alam/unity-control-center/use-usd-schemas

« back to all changes in this revision

Viewing changes to panels/network/cc-network-panel.c

  • Committer: Sebastien Bacher
  • Author(s): Khurshid Alam
  • Date: 2019-05-17 07:34:33 UTC
  • mfrom: (12920.1.1 unity-control-center)
  • Revision ID: seb128@ubuntu.com-20190517073433-ch2kybdhhzpkmvq4
Network: Port to libnm 1.2 (lp: #1744619)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 * Copyright (C) 2010-2012 Richard Hughes <richard@hughsie.com>
4
4
 * Copyright (C) 2012 Thomas Bechtold <thomasbechtold@jpberlin.de>
 
5
 * Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org>
5
6
 *
6
7
 * This program is free software; you can redistribute it and/or modify
7
8
 * it under the terms of the GNU General Public License as published by
14
15
 * GNU General Public License for more details.
15
16
 *
16
17
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19
19
 *
20
20
 */
21
21
 
24
24
#include <stdlib.h>
25
25
 
26
26
#include "cc-network-panel.h"
 
27
#include "cc-network-resources.h"
27
28
 
28
 
#include "nm-remote-settings.h"
29
 
#include "nm-client.h"
30
 
#include "nm-device.h"
31
 
#include "nm-device-modem.h"
 
29
#include <NetworkManager.h>
32
30
 
33
31
#include "net-device.h"
34
32
#include "net-device-mobile.h"
35
33
#include "net-device-wifi.h"
36
 
#include "net-device-wired.h"
 
34
#include "net-device-ethernet.h"
37
35
#include "net-object.h"
38
36
#include "net-proxy.h"
39
37
#include "net-vpn.h"
40
38
 
41
 
#include "rfkill-glib.h"
42
 
 
43
39
#include "panel-common.h"
44
40
 
45
41
#include "network-dialogs.h"
 
42
#include "connection-editor/net-connection-editor.h"
 
43
 
 
44
#include <libmm-glib.h>
46
45
 
47
46
CC_PANEL_REGISTER (CcNetworkPanel, cc_network_panel)
48
47
 
64
63
        GtkBuilder       *builder;
65
64
        GtkWidget        *treeview;
66
65
        NMClient         *client;
67
 
        NMRemoteSettings *remote_settings;
 
66
        MMManager        *modem_manager;
68
67
        gboolean          updating_device;
69
 
        guint             add_header_widgets_idle;
70
 
        guint             nm_warning_idle;
71
 
        guint             refresh_idle;
72
68
 
73
69
        /* Killswitch stuff */
 
70
        GDBusProxy       *rfkill_proxy;
74
71
        GtkWidget        *kill_switch_header;
75
 
        CcRfkillGlib       *rfkill;
76
72
        GtkSwitch        *rfkill_switch;
77
 
        GHashTable       *killswitches;
78
73
 
79
74
        /* wireless dialog stuff */
80
75
        CmdlineOperation  arg_operation;
85
80
 
86
81
enum {
87
82
        PANEL_DEVICES_COLUMN_ICON,
88
 
        PANEL_DEVICES_COLUMN_TITLE,
89
 
        PANEL_DEVICES_COLUMN_SORT,
90
83
        PANEL_DEVICES_COLUMN_OBJECT,
91
84
        PANEL_DEVICES_COLUMN_LAST
92
85
};
96
89
        PROP_ARGV
97
90
};
98
91
 
99
 
static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id);
 
92
static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out);
100
93
static void handle_argv (CcNetworkPanel *panel);
101
94
 
102
95
static void
205
198
                g_cancellable_cancel (priv->cancellable);
206
199
 
207
200
        g_clear_object (&priv->cancellable);
 
201
        g_clear_object (&priv->rfkill_proxy);
208
202
        g_clear_object (&priv->builder);
209
203
        g_clear_object (&priv->client);
210
 
        g_clear_object (&priv->remote_settings);
 
204
        g_clear_object (&priv->modem_manager);
211
205
        g_clear_object (&priv->kill_switch_header);
212
 
        g_clear_object (&priv->rfkill);
213
 
        g_clear_pointer (&priv->killswitches, g_hash_table_destroy);
214
206
        priv->rfkill_switch = NULL;
215
207
 
216
 
        if (priv->refresh_idle != 0) {
217
 
                g_source_remove (priv->refresh_idle);
218
 
                priv->refresh_idle = 0;
219
 
        }
220
 
        if (priv->nm_warning_idle != 0) {
221
 
                g_source_remove (priv->nm_warning_idle);
222
 
                priv->nm_warning_idle = 0;
223
 
        }
224
 
        if (priv->add_header_widgets_idle != 0) {
225
 
                g_source_remove (priv->add_header_widgets_idle);
226
 
                priv->add_header_widgets_idle = 0;
227
 
        }
228
 
 
229
208
        G_OBJECT_CLASS (cc_network_panel_parent_class)->dispose (object);
230
209
}
231
210
 
242
221
static const char *
243
222
cc_network_panel_get_help_uri (CcPanel *panel)
244
223
{
245
 
        return "help:ubuntu-help/net";
 
224
        return "help:gnome-help/net";
 
225
}
 
226
 
 
227
static void
 
228
cc_network_panel_notify_enable_active_cb (GtkSwitch *sw,
 
229
                                          GParamSpec *pspec,
 
230
                                          CcNetworkPanel *panel)
 
231
{
 
232
        CcNetworkPanelPrivate *priv = panel->priv;
 
233
        gboolean enable;
 
234
        enable = gtk_switch_get_active (sw);
 
235
        g_dbus_proxy_call (priv->rfkill_proxy,
 
236
                           "org.freedesktop.DBus.Properties.Set",
 
237
                           g_variant_new_parsed ("('org.gnome.SettingsDaemon.Rfkill',"
 
238
                                                 "'AirplaneMode', %v)",
 
239
                                                 g_variant_new_boolean (enable)),
 
240
                           G_DBUS_CALL_FLAGS_NONE,
 
241
                           -1,
 
242
                           priv->cancellable,
 
243
                           NULL, NULL);
 
244
}
 
245
 
 
246
static void
 
247
sync_airplane_mode_switch (CcNetworkPanel *panel)
 
248
{
 
249
        GVariant *result;
 
250
        gboolean enabled, should_show;
 
251
        gboolean hw_enabled;
 
252
 
 
253
        result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "HasAirplaneMode");
 
254
        enabled = g_variant_get_boolean (result);
 
255
 
 
256
        result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "ShouldShowAirplaneMode");
 
257
        should_show = g_variant_get_boolean (result);
 
258
 
 
259
        gtk_widget_set_visible (GTK_WIDGET (panel->priv->kill_switch_header), enabled && should_show);
 
260
        if (!enabled || !should_show)
 
261
                return;
 
262
 
 
263
        result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "AirplaneMode");
 
264
        enabled = g_variant_get_boolean (result);
 
265
 
 
266
        result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "HardwareAirplaneMode");
 
267
        hw_enabled = !!g_variant_get_boolean (result);
 
268
 
 
269
        enabled |= hw_enabled;
 
270
 
 
271
        if (enabled != gtk_switch_get_active (panel->priv->rfkill_switch)) {
 
272
                g_signal_handlers_block_by_func (panel->priv->rfkill_switch,
 
273
                                                 cc_network_panel_notify_enable_active_cb,
 
274
                                                 panel);
 
275
                gtk_switch_set_active (panel->priv->rfkill_switch, enabled);
 
276
                g_signal_handlers_unblock_by_func (panel->priv->rfkill_switch,
 
277
                                                 cc_network_panel_notify_enable_active_cb,
 
278
                                                 panel);
 
279
        }
 
280
 
 
281
        gtk_widget_set_sensitive (GTK_WIDGET (panel->priv->rfkill_switch), !hw_enabled);
 
282
}
 
283
 
 
284
static void
 
285
on_property_change (GDBusProxy *proxy,
 
286
                    GVariant   *changed_properties,
 
287
                    GVariant   *invalidated_properties,
 
288
                    gpointer    user_data)
 
289
{
 
290
        sync_airplane_mode_switch (CC_NETWORK_PANEL (user_data));
 
291
}
 
292
 
 
293
static void
 
294
got_rfkill_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 
295
{
 
296
        GError *error = NULL;
 
297
        CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
 
298
 
 
299
        panel->priv->rfkill_proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
 
300
        if (panel->priv->rfkill_proxy == NULL) {
 
301
                g_printerr ("Error creating rfkill proxy: %s\n", error->message);
 
302
                g_error_free (error);
 
303
                return;
 
304
        }
 
305
 
 
306
        g_signal_connect (panel->priv->rfkill_proxy, "g-properties-changed",
 
307
                          G_CALLBACK (on_property_change), panel);
 
308
        sync_airplane_mode_switch (panel);
 
309
}
 
310
 
 
311
static void
 
312
cc_network_panel_constructed (GObject *object)
 
313
{
 
314
        CcNetworkPanel *panel = CC_NETWORK_PANEL (object);
 
315
        GtkWidget *box;
 
316
        GtkWidget *label;
 
317
        GtkWidget *widget;
 
318
 
 
319
        G_OBJECT_CLASS (cc_network_panel_parent_class)->constructed (object);
 
320
 
 
321
        /* add kill switch widgets  */
 
322
        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
 
323
        /* TRANSLATORS: this is to disable the radio hardware in the
 
324
         * network panel */
 
325
        label = gtk_label_new_with_mnemonic (_("Air_plane Mode"));
 
326
        gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
 
327
        gtk_widget_set_visible (label, TRUE);
 
328
        widget = gtk_switch_new ();
 
329
        gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
 
330
        gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
 
331
        gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 4);
 
332
        gtk_widget_show_all (box);
 
333
        panel->priv->rfkill_switch = GTK_SWITCH (widget);
 
334
        cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (panel)), box);
 
335
        panel->priv->kill_switch_header = g_object_ref (box);
 
336
 
 
337
        g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
 
338
                                  G_DBUS_PROXY_FLAGS_NONE,
 
339
                                  NULL,
 
340
                                  "org.gnome.SettingsDaemon.Rfkill",
 
341
                                  "/org/gnome/SettingsDaemon/Rfkill",
 
342
                                  "org.gnome.SettingsDaemon.Rfkill",
 
343
                                  panel->priv->cancellable,
 
344
                                  got_rfkill_proxy_cb,
 
345
                                  panel);
 
346
 
 
347
        g_signal_connect (panel->priv->rfkill_switch, "notify::active",
 
348
                          G_CALLBACK (cc_network_panel_notify_enable_active_cb),
 
349
                          panel);
246
350
}
247
351
 
248
352
static void
259
363
        object_class->set_property = cc_network_panel_set_property;
260
364
        object_class->dispose = cc_network_panel_dispose;
261
365
        object_class->finalize = cc_network_panel_finalize;
 
366
        object_class->constructed = cc_network_panel_constructed;
262
367
 
263
368
        g_object_class_override_property (object_class, PROP_ARGV, "argv");
264
369
}
333
438
                if (g_strcmp0 (net_object_get_id (object),
334
439
                               net_object_get_id (object_tmp)) == 0) {
335
440
                        g_object_unref (object_tmp);
336
 
                        if (!gtk_list_store_remove (GTK_LIST_STORE (model), &iter))
337
 
                                gtk_tree_model_get_iter_first (model, &iter);
338
 
                        gtk_tree_selection_select_iter (selection, &iter);
339
 
 
 
441
                        if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) {
 
442
                                if (gtk_tree_model_get_iter_first (model, &iter))
 
443
                                        gtk_tree_selection_select_iter (selection, &iter);
 
444
                        }
340
445
                        break;
341
446
                }
342
447
                g_object_unref (object_tmp);
343
448
        } while (gtk_tree_model_iter_next (model, &iter));
344
449
}
345
450
 
 
451
GPtrArray *
 
452
cc_network_panel_get_devices (CcNetworkPanel *panel)
 
453
{
 
454
        GPtrArray *devices;
 
455
        GtkTreeModel *model;
 
456
        GtkTreeIter iter;
 
457
        NetObject *object;
 
458
 
 
459
        devices = g_ptr_array_new_with_free_func (g_object_unref);
 
460
 
 
461
        model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder,
 
462
                                                        "liststore_devices"));
 
463
        if (!gtk_tree_model_get_iter_first (model, &iter))
 
464
                return devices;
 
465
 
 
466
        do {
 
467
                gtk_tree_model_get (model, &iter,
 
468
                                    PANEL_DEVICES_COLUMN_OBJECT, &object,
 
469
                                    -1);
 
470
                if (NET_IS_DEVICE (object))
 
471
                        g_ptr_array_add (devices, object);
 
472
                else
 
473
                        g_object_unref (object);
 
474
        } while (gtk_tree_model_iter_next (model, &iter));
 
475
 
 
476
        return devices;
 
477
}
 
478
 
 
479
static gint
 
480
panel_net_object_get_sort_category (NetObject *net_object)
 
481
{
 
482
        if (NET_IS_DEVICE (net_object)) {
 
483
                return panel_device_get_sort_category (net_device_get_nm_device (NET_DEVICE (net_object)));
 
484
        } else if (NET_IS_PROXY (net_object)) {
 
485
                return 9;
 
486
        } else if (NET_IS_VPN (net_object)) {
 
487
                return 5;
 
488
        }
 
489
 
 
490
        g_assert_not_reached ();
 
491
}
 
492
 
 
493
static gint
 
494
panel_net_object_sort_func (GtkTreeModel *model, GtkTreeIter *a,
 
495
                            GtkTreeIter *b, void *data)
 
496
{
 
497
        g_autoptr(NetObject) obj_a = NULL;
 
498
        g_autoptr(NetObject) obj_b = NULL;
 
499
        gint cat_a, cat_b;
 
500
 
 
501
        gtk_tree_model_get (model, a,
 
502
                            PANEL_DEVICES_COLUMN_OBJECT, &obj_a,
 
503
                            -1);
 
504
        gtk_tree_model_get (model, b,
 
505
                            PANEL_DEVICES_COLUMN_OBJECT, &obj_b,
 
506
                            -1);
 
507
 
 
508
        cat_a = panel_net_object_get_sort_category (obj_a);
 
509
        cat_b = panel_net_object_get_sort_category (obj_b);
 
510
 
 
511
        if (cat_a != cat_b)
 
512
                return cat_a - cat_b;
 
513
 
 
514
        return g_utf8_collate (net_object_get_title (obj_a), net_object_get_title (obj_b));
 
515
}
 
516
 
 
517
static void
 
518
panel_net_object_notify_title_cb (NetObject *net_object, GParamSpec *pspec, CcNetworkPanel *panel)
 
519
{
 
520
        GtkTreeIter iter;
 
521
        GtkListStore *liststore;
 
522
 
 
523
        if (!find_in_model_by_id (panel, net_object_get_id (net_object), &iter))
 
524
                return;
 
525
 
 
526
        liststore = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
 
527
                                                            "liststore_devices"));
 
528
 
 
529
        /* gtk_tree_model_row_changed would not cause the list store to resort.
 
530
         * Instead set the object column to the current value.
 
531
         * See https://bugzilla.gnome.org/show_bug.cgi?id=782737 */
 
532
        gtk_list_store_set (liststore, &iter,
 
533
                            PANEL_DEVICES_COLUMN_OBJECT, net_object,
 
534
                           -1);
 
535
}
 
536
 
 
537
static void
 
538
panel_refresh_device_titles (CcNetworkPanel *panel)
 
539
{
 
540
        GPtrArray *ndarray, *nmdarray;
 
541
        NetDevice **devices;
 
542
        NMDevice **nm_devices, *nm_device;
 
543
        gchar **titles;
 
544
        gint i, num_devices;
 
545
 
 
546
        ndarray = cc_network_panel_get_devices (panel);
 
547
        if (!ndarray->len) {
 
548
                g_ptr_array_free (ndarray, TRUE);
 
549
                return;
 
550
        }
 
551
 
 
552
        nmdarray = g_ptr_array_new ();
 
553
        for (i = 0; i < ndarray->len; i++) {
 
554
                nm_device = net_device_get_nm_device (ndarray->pdata[i]);
 
555
                if (nm_device)
 
556
                        g_ptr_array_add (nmdarray, nm_device);
 
557
                else
 
558
                        g_ptr_array_remove_index (ndarray, i--);
 
559
        }
 
560
 
 
561
        devices = (NetDevice **)ndarray->pdata;
 
562
        nm_devices = (NMDevice **)nmdarray->pdata;
 
563
        num_devices = ndarray->len;
 
564
 
 
565
        titles = nm_device_disambiguate_names (nm_devices, num_devices);
 
566
        for (i = 0; i < num_devices; i++) {
 
567
                net_object_set_title (NET_OBJECT (devices[i]), titles[i]);
 
568
                g_free (titles[i]);
 
569
        }
 
570
        g_free (titles);
 
571
        g_ptr_array_free (ndarray, TRUE);
 
572
        g_ptr_array_free (nmdarray, TRUE);
 
573
}
 
574
 
346
575
static gboolean
347
576
handle_argv_for_device (CcNetworkPanel *panel,
348
577
                        NMDevice       *device,
350
579
{
351
580
        CcNetworkPanelPrivate *priv = panel->priv;
352
581
        NMDeviceType type;
 
582
        GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)));
353
583
 
354
584
        if (priv->arg_operation == OPERATION_NULL)
355
585
                return TRUE;
363
593
                select_tree_iter (panel, iter);
364
594
 
365
595
                if (priv->arg_operation == OPERATION_CREATE_WIFI)
366
 
                        cc_network_panel_create_wifi_network (panel, priv->client, priv->remote_settings);
 
596
                        cc_network_panel_create_wifi_network (toplevel, priv->client);
367
597
                else
368
 
                        cc_network_panel_connect_to_hidden_network (panel, priv->client, priv->remote_settings);
 
598
                        cc_network_panel_connect_to_hidden_network (toplevel, priv->client);
369
599
 
370
600
                reset_command_line_args (panel); /* done */
371
601
                return TRUE;
372
602
        } else if (g_strcmp0 (nm_object_get_path (NM_OBJECT (device)), priv->arg_device) == 0) {
373
603
                if (priv->arg_operation == OPERATION_CONNECT_MOBILE) {
374
 
                        cc_network_panel_connect_to_3g_network (panel, priv->client, priv->remote_settings, device);
 
604
                        cc_network_panel_connect_to_3g_network (toplevel, priv->client, device);
375
605
 
376
606
                        reset_command_line_args (panel); /* done */
377
607
                        select_tree_iter (panel, iter);
378
608
                        return TRUE;
379
609
                } else if (priv->arg_operation == OPERATION_CONNECT_8021X) {
380
 
                        cc_network_panel_connect_to_8021x_network (panel, priv->client, priv->remote_settings, device, priv->arg_access_point);
 
610
                        cc_network_panel_connect_to_8021x_network (toplevel, priv->client, device, priv->arg_access_point);
381
611
                        reset_command_line_args (panel); /* done */
382
612
                        select_tree_iter (panel, iter);
383
613
                        return TRUE;
392
622
        return FALSE;
393
623
}
394
624
 
 
625
static gboolean
 
626
handle_argv_for_connection (CcNetworkPanel *panel,
 
627
                            NMConnection   *connection,
 
628
                            GtkTreeIter    *iter)
 
629
{
 
630
        CcNetworkPanelPrivate *priv = panel->priv;
 
631
 
 
632
        if (priv->arg_operation == OPERATION_NULL)
 
633
                return TRUE;
 
634
        if (priv->arg_operation != OPERATION_SHOW_DEVICE)
 
635
                return FALSE;
 
636
 
 
637
        if (g_strcmp0 (nm_connection_get_path (connection), priv->arg_device) == 0) {
 
638
                reset_command_line_args (panel);
 
639
                select_tree_iter (panel, iter);
 
640
                return TRUE;
 
641
        }
 
642
 
 
643
        return FALSE;
 
644
}
 
645
 
 
646
 
395
647
static void
396
648
handle_argv (CcNetworkPanel *panel)
397
649
{
408
660
        while (ret) {
409
661
                GObject *object_tmp;
410
662
                NMDevice *device;
 
663
                NMConnection *connection;
411
664
                gboolean done = FALSE;
412
665
 
413
666
                gtk_tree_model_get (model, &iter,
414
667
                                    PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
415
668
                                    -1);
416
 
                if (g_object_class_find_property (G_OBJECT_GET_CLASS (object_tmp), "nm-device") != NULL) {
 
669
                if (NET_IS_DEVICE (object_tmp)) {
417
670
                        g_object_get (object_tmp, "nm-device", &device, NULL);
418
671
                        done = handle_argv_for_device (panel, device, &iter);
419
672
                        g_object_unref (device);
 
673
                } else if (NET_IS_VPN (object_tmp)) {
 
674
                        g_object_get (object_tmp, "connection", &connection, NULL);
 
675
                        done = handle_argv_for_connection (panel, connection, &iter);
 
676
                        g_object_unref (connection);
420
677
                }
421
678
 
422
679
                g_object_unref (object_tmp);
430
687
        g_debug ("Could not handle argv operation, no matching device yet?");
431
688
}
432
689
 
 
690
static void
 
691
state_changed_cb (NMDevice *device,
 
692
                  NMDeviceState new_state,
 
693
                  NMDeviceState old_state,
 
694
                  NMDeviceStateReason reason,
 
695
                  CcNetworkPanel *panel)
 
696
{
 
697
        GtkListStore *store;
 
698
        GtkTreeIter iter;
 
699
 
 
700
        if (!find_in_model_by_id (panel, nm_device_get_udi (device), &iter)) {
 
701
                return;
 
702
        }
 
703
 
 
704
        store = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
 
705
                                                        "liststore_devices"));
 
706
 
 
707
        gtk_list_store_set (store, &iter,
 
708
                            PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE),
 
709
                           -1);
 
710
}
 
711
 
433
712
static gboolean
434
713
panel_add_device (CcNetworkPanel *panel, NMDevice *device)
435
714
{
436
 
        const gchar *title;
437
715
        GtkListStore *liststore_devices;
438
716
        GtkTreeIter iter;
439
717
        NMDeviceType type;
442
720
        GtkNotebook *notebook;
443
721
        GtkSizeGroup *size_group;
444
722
        GType device_g_type;
 
723
        const char *udi;
 
724
 
 
725
        if (!nm_device_get_managed (device))
 
726
                goto out;
445
727
 
446
728
        /* do we have an existing object with this id? */
447
 
        if (find_in_model_by_id (panel, nm_device_get_udi (device)) != NULL)
 
729
        udi = nm_device_get_udi (device);
 
730
        if (find_in_model_by_id (panel, udi, NULL) != NULL)
448
731
                goto out;
449
732
 
450
733
        type = nm_device_get_device_type (device);
451
734
 
452
735
        g_debug ("device %s type %i path %s",
453
 
                 nm_device_get_udi (device), type, nm_object_get_path (NM_OBJECT (device)));
 
736
                 udi, type, nm_object_get_path (NM_OBJECT (device)));
454
737
 
455
 
        /* map the NMDeviceType to the GType */
 
738
        /* map the NMDeviceType to the GType, or ignore */
456
739
        switch (type) {
457
740
        case NM_DEVICE_TYPE_ETHERNET:
458
 
                device_g_type = NET_TYPE_DEVICE_WIRED;
 
741
                device_g_type = NET_TYPE_DEVICE_ETHERNET;
459
742
                break;
460
743
        case NM_DEVICE_TYPE_MODEM:
461
744
                device_g_type = NET_TYPE_DEVICE_MOBILE;
463
746
        case NM_DEVICE_TYPE_WIFI:
464
747
                device_g_type = NET_TYPE_DEVICE_WIFI;
465
748
                break;
 
749
        /* not going to set up a cluster in GNOME */
 
750
        case NM_DEVICE_TYPE_VETH:
 
751
        /* enterprise features */
 
752
        case NM_DEVICE_TYPE_BOND:
 
753
        case NM_DEVICE_TYPE_TEAM:
 
754
        /* Don't need the libvirtd bridge */
 
755
        case NM_DEVICE_TYPE_BRIDGE:
 
756
        /* Don't add VPN devices */
 
757
        case NM_DEVICE_TYPE_TUN:
 
758
                goto out;
466
759
        default:
467
 
                goto out;
 
760
                device_g_type = NET_TYPE_DEVICE_SIMPLE;
 
761
                break;
468
762
        }
469
763
 
470
764
        /* create device */
471
 
        title = panel_device_to_localized_string (device);
472
765
        net_device = g_object_new (device_g_type,
473
766
                                   "panel", panel,
474
767
                                   "removable", FALSE,
475
768
                                   "cancellable", panel->priv->cancellable,
476
769
                                   "client", panel->priv->client,
477
 
                                   "remote-settings", panel->priv->remote_settings,
478
770
                                   "nm-device", device,
479
771
                                   "id", nm_device_get_udi (device),
480
 
                                   "title", title,
481
772
                                   NULL);
482
773
 
 
774
        if (type == NM_DEVICE_TYPE_MODEM &&
 
775
            g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager1/Modem/")) {
 
776
                GDBusObject *modem_object;
 
777
 
 
778
                if (priv->modem_manager == NULL) {
 
779
                        g_warning ("Cannot grab information for modem at %s: No ModemManager support",
 
780
                                   nm_device_get_udi (device));
 
781
                        goto out;
 
782
                }
 
783
 
 
784
                modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (priv->modem_manager),
 
785
                                                                 nm_device_get_udi (device));
 
786
                if (modem_object == NULL) {
 
787
                        g_warning ("Cannot grab information for modem at %s: Not found",
 
788
                                   nm_device_get_udi (device));
 
789
                        goto out;
 
790
                }
 
791
 
 
792
                /* Set the modem object in the NetDeviceMobile */
 
793
                g_object_set (net_device,
 
794
                              "mm-object", modem_object,
 
795
                              NULL);
 
796
                g_object_unref (modem_object);
 
797
        }
 
798
 
483
799
        /* add as a panel */
484
800
        if (device_g_type != NET_TYPE_DEVICE) {
485
801
                notebook = GTK_NOTEBOOK (gtk_builder_get_object (panel->priv->builder,
498
814
        gtk_list_store_append (liststore_devices, &iter);
499
815
        gtk_list_store_set (liststore_devices,
500
816
                            &iter,
501
 
                            PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device),
502
 
                            PANEL_DEVICES_COLUMN_SORT, panel_device_to_sortable_string (device),
503
 
                            PANEL_DEVICES_COLUMN_TITLE, title,
 
817
                            PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE),
504
818
                            PANEL_DEVICES_COLUMN_OBJECT, net_device,
505
819
                            -1);
 
820
        g_signal_connect (net_device, "notify::title",
 
821
                          G_CALLBACK (panel_net_object_notify_title_cb), panel);
 
822
 
 
823
        g_object_unref (net_device);
 
824
        g_signal_connect (device, "state-changed",
 
825
                          G_CALLBACK (state_changed_cb), panel);
506
826
 
507
827
out:
508
828
        return FALSE;
539
859
}
540
860
 
541
861
static void
 
862
get_object_title (GtkTreeViewColumn *column,
 
863
                  GtkCellRenderer   *cell,
 
864
                  GtkTreeModel      *model,
 
865
                  GtkTreeIter       *iter,
 
866
                  gpointer           data)
 
867
{
 
868
        NetObject *object;
 
869
 
 
870
        gtk_tree_model_get (model, iter,
 
871
                            PANEL_DEVICES_COLUMN_OBJECT, &object,
 
872
                            -1);
 
873
        if (!object)
 
874
                return;
 
875
 
 
876
        g_object_set (cell, "text", net_object_get_title (object), NULL);
 
877
        g_object_unref (object);
 
878
}
 
879
 
 
880
static void
542
881
panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview)
543
882
{
544
883
        CcNetworkPanelPrivate *priv = panel->priv;
548
887
 
549
888
        /* image */
550
889
        renderer = gtk_cell_renderer_pixbuf_new ();
551
 
        g_object_set (renderer, "stock-size", gtk_icon_size_from_name ("cc-sidebar-list"), NULL);
552
 
        gtk_cell_renderer_set_padding (renderer, 4, 4);
 
890
        g_object_set (renderer,
 
891
                      "width", 32,
 
892
                      "xalign", 1.0,
 
893
                      "stock-size", GTK_ICON_SIZE_MENU,
 
894
                      "follow-state", TRUE,
 
895
                      NULL);
 
896
        gtk_cell_renderer_set_padding (renderer, 4, 10);
553
897
 
554
898
        column = gtk_tree_view_column_new_with_attributes ("icon", renderer,
555
899
                                                           "icon-name", PANEL_DEVICES_COLUMN_ICON,
562
906
                      "wrap-mode", PANGO_WRAP_WORD,
563
907
                      "ellipsize", PANGO_ELLIPSIZE_END,
564
908
                      NULL);
565
 
        column = gtk_tree_view_column_new_with_attributes ("title", renderer,
566
 
                                                           "markup", PANEL_DEVICES_COLUMN_TITLE,
567
 
                                                           NULL);
568
 
        gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_SORT);
 
909
        column = gtk_tree_view_column_new_with_attributes ("title", renderer, NULL);
 
910
        gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column),
 
911
                                                 renderer,
 
912
                                                 get_object_title,
 
913
                                                 NULL, NULL);
 
914
        gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_OBJECT);
569
915
        liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
570
916
                                            "liststore_devices"));
 
917
        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (liststore_devices),
 
918
                                         PANEL_DEVICES_COLUMN_OBJECT,
 
919
                                         panel_net_object_sort_func, NULL, NULL);
571
920
        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore_devices),
572
 
                                              PANEL_DEVICES_COLUMN_SORT,
 
921
                                              PANEL_DEVICES_COLUMN_OBJECT,
573
922
                                              GTK_SORT_ASCENDING);
574
923
        gtk_tree_view_append_column (treeview, column);
575
924
        gtk_tree_view_column_set_expand (column, TRUE);
616
965
                }
617
966
                i++;
618
967
        }
 
968
        g_object_unref (object);
619
969
out:
620
970
        g_list_free (panels);
621
971
}
623
973
static void
624
974
panel_add_proxy_device (CcNetworkPanel *panel)
625
975
{
626
 
        gchar *title;
627
976
        GtkListStore *liststore_devices;
628
977
        GtkTreeIter iter;
629
978
        NetProxy *proxy;
643
992
        /* add proxy to device list */
644
993
        liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
645
994
                                            "liststore_devices"));
646
 
        title = g_strdup_printf ("%s", _("Network proxy"));
 
995
        net_object_set_title (NET_OBJECT (proxy), _("Network proxy"));
647
996
        gtk_list_store_append (liststore_devices, &iter);
648
997
        gtk_list_store_set (liststore_devices,
649
998
                            &iter,
650
 
                            PANEL_DEVICES_COLUMN_ICON, "preferences-system-network",
651
 
                            PANEL_DEVICES_COLUMN_TITLE, title,
652
 
                            PANEL_DEVICES_COLUMN_SORT, "9",
 
999
                            PANEL_DEVICES_COLUMN_ICON, "preferences-system-network-symbolic",
653
1000
                            PANEL_DEVICES_COLUMN_OBJECT, proxy,
654
1001
                            -1);
655
 
        g_free (title);
 
1002
 
 
1003
        /* NOTE: No connect to notify::title here as it is guaranteed to not
 
1004
         *       be changed by anyone.*/
 
1005
 
656
1006
        g_object_unref (proxy);
657
1007
}
658
1008
 
659
1009
static void
660
 
cc_network_panel_notify_enable_active_cb (GtkSwitch *sw,
661
 
                                          GParamSpec *pspec,
662
 
                                          CcNetworkPanel *panel)
663
 
{
664
 
        gboolean enable;
665
 
        struct rfkill_event event;
666
 
 
667
 
        enable = gtk_switch_get_active (sw);
668
 
        g_debug ("Setting killswitch to %d", enable);
669
 
 
670
 
        memset (&event, 0, sizeof(event));
671
 
        event.op = RFKILL_OP_CHANGE_ALL;
672
 
        event.type = RFKILL_TYPE_ALL;
673
 
        event.soft = enable ? 1 : 0;
674
 
        if (cc_rfkill_glib_send_event (panel->priv->rfkill, &event) < 0)
675
 
                g_warning ("Setting the killswitch %s failed", enable ? "on" : "off");
676
 
}
677
 
 
678
 
static void
679
1010
connection_state_changed (NMActiveConnection *c, GParamSpec *pspec, CcNetworkPanel *panel)
680
1011
{
681
1012
}
699
1030
                for (j = 0; devices && j < devices->len; j++)
700
1031
                        g_debug ("           %s", nm_device_get_udi (g_ptr_array_index (devices, j)));
701
1032
                if (NM_IS_VPN_CONNECTION (connection))
702
 
                        g_debug ("           VPN base connection: %s", nm_active_connection_get_specific_object (connection));
 
1033
                        g_debug ("           VPN base connection: %s", nm_active_connection_get_specific_object_path (connection));
703
1034
 
704
1035
                if (g_object_get_data (G_OBJECT (connection), "has-state-changed-handler") == NULL) {
705
1036
                        g_signal_connect_object (connection, "notify::state",
714
1045
{
715
1046
        g_debug ("New device added");
716
1047
        panel_add_device (panel, device);
 
1048
        panel_refresh_device_titles (panel);
717
1049
}
718
1050
 
719
1051
static void
721
1053
{
722
1054
        g_debug ("Device removed");
723
1055
        panel_remove_device (panel, device);
 
1056
        panel_refresh_device_titles (panel);
724
1057
}
725
1058
 
726
1059
static void
734
1067
        CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
735
1068
 
736
1069
        /* clear all devices we added */
737
 
        if (!nm_client_get_manager_running (client)) {
 
1070
        if (!nm_client_get_nm_running (client)) {
738
1071
                g_debug ("NM disappeared");
739
1072
                liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
740
1073
                                                    "liststore_devices"));
759
1092
                select_first_device (panel);
760
1093
        }
761
1094
 
 
1095
        panel_refresh_device_titles (panel);
 
1096
 
762
1097
        g_debug ("Calling handle_argv() after cold-plugging devices");
763
1098
        handle_argv (panel);
764
1099
}
765
1100
 
766
1101
static NetObject *
767
 
find_in_model_by_id (CcNetworkPanel *panel, const gchar *id)
 
1102
find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out)
768
1103
{
769
1104
        gboolean ret;
770
1105
        NetObject *object_tmp;
793
1128
                }
794
1129
        } while (object == NULL && gtk_tree_model_iter_next (model, &iter));
795
1130
out:
 
1131
        if (iter_out)
 
1132
                *iter_out = iter;
796
1133
        return object;
797
1134
}
798
1135
 
800
1137
panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
801
1138
{
802
1139
        gchar *title;
803
 
        gchar *title_markup;
804
1140
        GtkListStore *liststore_devices;
805
1141
        GtkTreeIter iter;
806
1142
        NetVpn *net_vpn;
810
1146
 
811
1147
        /* does already exist */
812
1148
        id = nm_connection_get_path (connection);
813
 
        if (find_in_model_by_id (panel, id) != NULL)
 
1149
        if (find_in_model_by_id (panel, id, NULL) != NULL)
814
1150
                return;
815
1151
 
816
 
        /* add as a virtual object */
 
1152
        /* add as a VPN object */
817
1153
        net_vpn = g_object_new (NET_TYPE_VPN,
818
1154
                                "panel", panel,
819
1155
                                "removable", TRUE,
836
1172
        liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
837
1173
                                            "liststore_devices"));
838
1174
        title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (connection));
839
 
        title_markup = g_strdup (title);
840
1175
 
841
1176
        net_object_set_title (NET_OBJECT (net_vpn), title);
842
1177
        gtk_list_store_append (liststore_devices, &iter);
843
1178
        gtk_list_store_set (liststore_devices,
844
1179
                            &iter,
845
 
                            PANEL_DEVICES_COLUMN_ICON, "network-vpn",
846
 
                            PANEL_DEVICES_COLUMN_TITLE, title_markup,
847
 
                            PANEL_DEVICES_COLUMN_SORT, "5",
 
1180
                            PANEL_DEVICES_COLUMN_ICON, "network-vpn-symbolic",
848
1181
                            PANEL_DEVICES_COLUMN_OBJECT, net_vpn,
849
1182
                            -1);
 
1183
        g_signal_connect (net_vpn, "notify::title",
 
1184
                          G_CALLBACK (panel_net_object_notify_title_cb), panel);
 
1185
 
850
1186
        g_free (title);
851
 
        g_free (title_markup);
 
1187
        g_object_unref (net_vpn);
852
1188
}
853
1189
 
854
1190
static void
856
1192
                NMConnection *connection)
857
1193
{
858
1194
        NMSettingConnection *s_con;
859
 
        const gchar *type;
 
1195
        const gchar *type, *iface;
860
1196
 
861
1197
        s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection,
862
1198
                                                                  NM_TYPE_SETTING_CONNECTION));
863
1199
        type = nm_setting_connection_get_connection_type (s_con);
864
 
        if (g_strcmp0 (type, "vpn") != 0)
865
 
                return;
 
1200
        iface = nm_connection_get_interface_name (connection);
 
1201
        if (g_strcmp0 (type, "vpn") != 0 && iface == NULL)
 
1202
                return;
 
1203
 
 
1204
        /* Don't add the libvirtd bridge to the UI */
 
1205
        if (g_strcmp0 (nm_setting_connection_get_interface_name (s_con), "virbr0") == 0)
 
1206
                return;
 
1207
 
866
1208
        g_debug ("add %s/%s remote connection: %s",
867
1209
                 type, g_type_name_from_instance ((GTypeInstance*)connection),
868
1210
                 nm_connection_get_path (connection));
869
 
        panel_add_vpn_device (panel, connection);
 
1211
        if (!iface)
 
1212
                panel_add_vpn_device (panel, connection);
870
1213
}
871
1214
 
872
1215
static void
873
 
notify_new_connection_cb (NMRemoteSettings *settings,
874
 
                          NMRemoteConnection *connection,
875
 
                          CcNetworkPanel *panel)
 
1216
notify_connection_added_cb (NMClient           *client,
 
1217
                            NMRemoteConnection *connection,
 
1218
                            CcNetworkPanel     *panel)
876
1219
{
877
1220
        add_connection (panel, NM_CONNECTION (connection));
878
1221
}
879
1222
 
880
1223
static void
881
 
notify_connections_read_cb (NMRemoteSettings *settings,
882
 
                            CcNetworkPanel *panel)
883
 
{
884
 
        GSList *list, *iter;
885
 
        NMConnection *connection;
886
 
 
887
 
        list = nm_remote_settings_list_connections (settings);
888
 
        g_debug ("%p has %i remote connections",
889
 
                 panel, g_slist_length (list));
890
 
        for (iter = list; iter; iter = g_slist_next (iter)) {
891
 
                connection = NM_CONNECTION (iter->data);
892
 
                add_connection (panel, connection);
893
 
        }
894
 
}
895
 
 
896
 
static gboolean
897
 
display_version_warning_idle (CcNetworkPanel *panel)
898
 
{
899
 
        GtkWidget  *dialog;
900
 
        GtkWidget  *image;
901
 
        GtkWindow  *window;
902
 
        const char *message;
903
 
 
904
 
        /* TRANSLATORS: the user is running a NM that is not API compatible */
905
 
        message = _("The system network services are not compatible with this version.");
906
 
 
907
 
        window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
908
 
        dialog = gtk_message_dialog_new (window,
909
 
                                         GTK_DIALOG_MODAL,
910
 
                                         GTK_MESSAGE_ERROR,
911
 
                                         GTK_BUTTONS_CLOSE,
912
 
                                         "%s",
913
 
                                         message);
914
 
        image = gtk_image_new_from_icon_name ("computer-fail", GTK_ICON_SIZE_DIALOG);
915
 
        gtk_widget_show (image);
916
 
        gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
917
 
 
918
 
        gtk_dialog_run (GTK_DIALOG (dialog));
919
 
        gtk_widget_destroy (dialog);
920
 
 
921
 
        return FALSE;
922
 
}
923
 
 
924
 
static gboolean
925
1224
panel_check_network_manager_version (CcNetworkPanel *panel)
926
1225
{
 
1226
        GtkWidget *box;
 
1227
        GtkWidget *label;
 
1228
        gchar *markup;
927
1229
        const gchar *version;
928
 
        guint minor = 0;
929
 
        gboolean ret = TRUE;
930
1230
 
931
1231
        /* parse running version */
932
1232
        version = nm_client_get_version (panel->priv->client);
933
1233
        if (version == NULL) {
934
 
                ret = FALSE;
935
 
 
936
 
                /* do modal dialog in idle so we don't block startup */
937
 
                panel->priv->nm_warning_idle = g_idle_add ((GSourceFunc)display_version_warning_idle, panel);
 
1234
                gtk_container_remove (GTK_CONTAINER (panel), gtk_bin_get_child (GTK_BIN (panel)));
 
1235
 
 
1236
                box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20);
 
1237
                gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
 
1238
                gtk_widget_set_vexpand (box, TRUE);
 
1239
                gtk_container_add (GTK_CONTAINER (panel), box);
 
1240
 
 
1241
                label = gtk_label_new (_("Oops, something has gone wrong. Please contact your software vendor."));
 
1242
                gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
 
1243
                gtk_widget_set_valign (label, GTK_ALIGN_END);
 
1244
                gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
 
1245
 
 
1246
                markup = g_strdup_printf ("<small><tt>%s</tt></small>",
 
1247
                                          _("NetworkManager needs to be running."));
 
1248
                label = gtk_label_new (NULL);
 
1249
                gtk_label_set_markup (GTK_LABEL (label), markup);
 
1250
                gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
 
1251
                gtk_widget_set_valign (label, GTK_ALIGN_START);
 
1252
                gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
 
1253
 
 
1254
                gtk_widget_show_all (box);
 
1255
                g_free (markup);
 
1256
        } else {
 
1257
                manager_running (panel->priv->client, NULL, panel);
938
1258
        }
 
1259
}
939
1260
 
940
 
        return ret;
 
1261
static void
 
1262
editor_done (NetConnectionEditor *editor,
 
1263
             gboolean             success,
 
1264
             gpointer             user_data)
 
1265
{
 
1266
        g_object_unref (editor);
941
1267
}
942
1268
 
943
1269
static void
944
1270
add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel)
945
1271
{
946
 
        GtkWidget *dialog;
947
 
        gint response;
948
 
 
949
 
        dialog = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
950
 
                                                     "connection_type_dialog"));
951
 
        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))));
952
 
 
953
 
        response = gtk_dialog_run (GTK_DIALOG (dialog));
954
 
 
955
 
        gtk_widget_hide (dialog);
956
 
 
957
 
        if (response == GTK_RESPONSE_OK) {
958
 
                GtkComboBox *combo;
959
 
                GtkTreeModel *model;
960
 
                GtkTreeIter iter;
961
 
                gchar *type;
962
 
                gchar *cmdline;
963
 
                GError *error;
964
 
 
965
 
                combo = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder,
966
 
                                                               "connection_type_combo"));
967
 
                model = gtk_combo_box_get_model (combo);
968
 
                gtk_combo_box_get_active_iter (combo, &iter);
969
 
                type = NULL;
970
 
                gtk_tree_model_get (model, &iter, 1, &type, -1);
971
 
 
972
 
                cmdline = g_strdup_printf ("nm-connection-editor --create --type %s", type);
973
 
                g_debug ("Launching '%s'\n", cmdline);
974
 
 
975
 
                error = NULL;
976
 
                if (!g_spawn_command_line_async (cmdline, &error)) {
977
 
                        g_warning ("Failed to launch nm-connection-editor: %s", error->message);
978
 
                        g_error_free (error);
979
 
                }
980
 
                g_free (cmdline);
981
 
                g_free (type);
982
 
        }
 
1272
        NetConnectionEditor *editor;
 
1273
        GtkWindow *toplevel;
 
1274
 
 
1275
        toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
 
1276
        editor = net_connection_editor_new (toplevel, NULL, NULL, NULL,
 
1277
                                            panel->priv->client);
 
1278
        g_signal_connect (editor, "done", G_CALLBACK (editor_done), panel);
 
1279
        net_connection_editor_run (editor);
983
1280
}
984
1281
 
985
1282
static void
994
1291
 
995
1292
        /* delete the object */
996
1293
        net_object_delete (object);
 
1294
        g_object_unref (object);
997
1295
}
998
1296
 
999
1297
static void
1000
1298
on_toplevel_map (GtkWidget      *widget,
1001
1299
                 CcNetworkPanel *panel)
1002
1300
{
1003
 
        gboolean ret;
1004
 
 
1005
1301
        /* is the user compiling against a new version, but not running
1006
1302
         * the daemon? */
1007
 
        ret = panel_check_network_manager_version (panel);
1008
 
        if (ret) {
1009
 
                manager_running (panel->priv->client, NULL, panel);
1010
 
        } else {
1011
 
                /* just select the proxy settings */
1012
 
                select_first_device (panel);
1013
 
        }
1014
 
}
1015
 
 
1016
 
static void
1017
 
rfkill_changed (CcRfkillGlib     *rfkill,
1018
 
                GList          *events,
1019
 
                CcNetworkPanel *panel)
1020
 
{
1021
 
        gboolean enabled;
1022
 
        GList *l;
1023
 
        GHashTableIter iter;
1024
 
        gpointer key, value;
1025
 
 
1026
 
        enabled = TRUE;
1027
 
 
1028
 
        for (l = events; l != NULL; l = l->next) {
1029
 
                struct rfkill_event *event = l->data;
1030
 
 
1031
 
                if (event->op == RFKILL_OP_ADD)
1032
 
                        g_hash_table_insert (panel->priv->killswitches,
1033
 
                                             GINT_TO_POINTER (event->idx),
1034
 
                                             GINT_TO_POINTER (event->soft || event->hard));
1035
 
                else if (event->op == RFKILL_OP_CHANGE)
1036
 
                        g_hash_table_insert (panel->priv->killswitches,
1037
 
                                             GINT_TO_POINTER (event->idx),
1038
 
                                             GINT_TO_POINTER (event->soft || event->hard));
1039
 
                else if (event->op == RFKILL_OP_DEL)
1040
 
                        g_hash_table_remove (panel->priv->killswitches,
1041
 
                                             GINT_TO_POINTER (event->idx));
1042
 
        }
1043
 
 
1044
 
        g_hash_table_iter_init (&iter, panel->priv->killswitches);
1045
 
        while (g_hash_table_iter_next (&iter, &key, &value)) {
1046
 
                int idx, state;
1047
 
 
1048
 
                idx = GPOINTER_TO_INT (key);
1049
 
                state = GPOINTER_TO_INT (value);
1050
 
                g_debug ("Killswitch %d is %s", idx, state ? "enabled" : "disabled");
1051
 
 
1052
 
                /* A single device that's enabled? airplane mode is off */
1053
 
                if (state == FALSE) {
1054
 
                        enabled = FALSE;
1055
 
                        break;
1056
 
                }
1057
 
        }
1058
 
 
1059
 
        if (enabled != gtk_switch_get_active (panel->priv->rfkill_switch)) {
1060
 
                g_signal_handlers_block_by_func (panel->priv->rfkill_switch,
1061
 
                                                 cc_network_panel_notify_enable_active_cb,
1062
 
                                                 panel);
1063
 
                gtk_switch_set_active (panel->priv->rfkill_switch, enabled);
1064
 
                g_signal_handlers_unblock_by_func (panel->priv->rfkill_switch,
1065
 
                                                 cc_network_panel_notify_enable_active_cb,
1066
 
                                                 panel);
1067
 
        }
1068
 
}
1069
 
 
1070
 
static gboolean
1071
 
network_add_shell_header_widgets_cb (gpointer user_data)
1072
 
{
1073
 
        CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
1074
 
        GtkWidget *box;
1075
 
        GtkWidget *label;
1076
 
        GtkWidget *widget;
1077
 
 
1078
 
        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
1079
 
        /* TRANSLATORS: this is to disable the radio hardware in the
1080
 
         * network panel */
1081
 
        label = gtk_label_new_with_mnemonic (_("Air_plane Mode"));
1082
 
        gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
1083
 
        gtk_widget_set_visible (label, TRUE);
1084
 
        widget = gtk_switch_new ();
1085
 
        gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
1086
 
        gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
1087
 
        gtk_widget_show_all (box);
1088
 
        panel->priv->rfkill_switch = GTK_SWITCH (widget);
1089
 
        cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (panel)), box);
1090
 
        panel->priv->kill_switch_header = g_object_ref (box);
1091
 
 
1092
 
        panel->priv->killswitches = g_hash_table_new (g_direct_hash, g_direct_equal);
1093
 
        panel->priv->rfkill = cc_rfkill_glib_new ();
1094
 
        g_signal_connect (G_OBJECT (panel->priv->rfkill), "changed",
1095
 
                          G_CALLBACK (rfkill_changed), panel);
1096
 
        if (cc_rfkill_glib_open (panel->priv->rfkill) < 0)
1097
 
                gtk_widget_hide (box);
1098
 
 
1099
 
        g_signal_connect (panel->priv->rfkill_switch, "notify::active",
1100
 
                          G_CALLBACK (cc_network_panel_notify_enable_active_cb),
1101
 
                          panel);
1102
 
 
1103
 
        return FALSE;
 
1303
        panel_check_network_manager_version (panel);
1104
1304
}
1105
1305
 
1106
1306
static void
1107
1307
cc_network_panel_init (CcNetworkPanel *panel)
1108
1308
{
1109
 
        DBusGConnection *bus = NULL;
1110
1309
        GError *error = NULL;
1111
1310
        GtkStyleContext *context;
1112
1311
        GtkTreeSelection *selection;
1113
1312
        GtkWidget *widget;
1114
1313
        GtkWidget *toplevel;
 
1314
        GDBusConnection *system_bus;
 
1315
        GtkCssProvider *provider;
 
1316
        const GPtrArray *connections;
 
1317
        guint i;
1115
1318
 
1116
1319
        panel->priv = NETWORK_PANEL_PRIVATE (panel);
 
1320
        g_resources_register (cc_network_get_resource ());
1117
1321
 
1118
1322
        panel->priv->builder = gtk_builder_new ();
1119
 
        gtk_builder_add_from_file (panel->priv->builder,
1120
 
                                   GNOMECC_UI_DIR "/network.ui",
1121
 
                                   &error);
 
1323
        gtk_builder_add_from_resource (panel->priv->builder,
 
1324
                                       "/org/gnome/control-center/network/network.ui",
 
1325
                                       &error);
1122
1326
        if (error != NULL) {
1123
1327
                g_warning ("Could not load interface file: %s", error->message);
1124
1328
                g_error_free (error);
1150
1354
        panel_add_proxy_device (panel);
1151
1355
 
1152
1356
        /* use NetworkManager client */
1153
 
        panel->priv->client = nm_client_new ();
1154
 
        g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_MANAGER_RUNNING,
 
1357
        panel->priv->client = nm_client_new (NULL, NULL);
 
1358
        g_signal_connect (panel->priv->client, "notify::nm-running" ,
1155
1359
                          G_CALLBACK (manager_running), panel);
1156
 
        g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS,
 
1360
        g_signal_connect (panel->priv->client, "notify::active-connections",
1157
1361
                          G_CALLBACK (active_connections_changed), panel);
1158
1362
        g_signal_connect (panel->priv->client, "device-added",
1159
1363
                          G_CALLBACK (device_added_cb), panel);
1160
1364
        g_signal_connect (panel->priv->client, "device-removed",
1161
1365
                          G_CALLBACK (device_removed_cb), panel);
1162
1366
 
 
1367
        /* Setup ModemManager client */
 
1368
        system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
 
1369
        if (system_bus == NULL) {
 
1370
                g_warning ("Error connecting to system D-Bus: %s",
 
1371
                           error->message);
 
1372
                g_clear_error (&error);
 
1373
        } else {
 
1374
                panel->priv->modem_manager = mm_manager_new_sync (system_bus,
 
1375
                                                                  G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
 
1376
                                                                  NULL,
 
1377
                                                                  &error);
 
1378
                if (panel->priv->modem_manager == NULL) {
 
1379
                        g_warning ("Error connecting to ModemManager: %s",
 
1380
                                   error->message);
 
1381
                        g_clear_error (&error);
 
1382
                }
 
1383
                g_object_unref (system_bus);
 
1384
        }
 
1385
 
1163
1386
        widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
1164
1387
                                                     "add_toolbutton"));
1165
1388
        g_signal_connect (widget, "clicked",
1172
1395
                          G_CALLBACK (remove_connection), panel);
1173
1396
 
1174
1397
        /* add remote settings such as VPN settings as virtual devices */
1175
 
        bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
1176
 
        if (bus == NULL) {
1177
 
                g_warning ("Error connecting to system D-Bus: %s",
1178
 
                           error->message);
1179
 
                g_error_free (error);
1180
 
        }
1181
 
        panel->priv->remote_settings = nm_remote_settings_new (bus);
1182
 
        g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ,
1183
 
                          G_CALLBACK (notify_connections_read_cb), panel);
1184
 
        g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_NEW_CONNECTION,
1185
 
                          G_CALLBACK (notify_new_connection_cb), panel);
 
1398
        g_signal_connect (panel->priv->client, NM_CLIENT_CONNECTION_ADDED,
 
1399
                          G_CALLBACK (notify_connection_added_cb), panel);
1186
1400
 
1187
1401
        toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel));
1188
1402
        g_signal_connect_after (toplevel, "map", G_CALLBACK (on_toplevel_map), panel);
1194
1408
 
1195
1409
        widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
1196
1410
                                                     "vbox1"));
1197
 
        gtk_widget_reparent (widget, (GtkWidget *) panel);
1198
 
 
1199
 
        /* add kill switch widgets when dialog activated */
1200
 
        panel->priv->add_header_widgets_idle = g_idle_add (network_add_shell_header_widgets_cb, panel);
 
1411
        gtk_container_add (GTK_CONTAINER (panel), widget);
 
1412
 
 
1413
        provider = gtk_css_provider_new ();
 
1414
        gtk_css_provider_load_from_data (provider, ".circular-button { border-radius: 20px; -gtk-outline-radius: 20px; }", -1, NULL);
 
1415
        gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
 
1416
                                                   GTK_STYLE_PROVIDER (provider),
 
1417
                                                   GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
 
1418
        g_object_unref (provider);
 
1419
        
 
1420
        /* Cold-plug existing connections */
 
1421
        connections = nm_client_get_connections (panel->priv->client);
 
1422
        for (i = 0; i < connections->len; i++)
 
1423
                add_connection (panel, connections->pdata[i]);
 
1424
 
 
1425
        g_debug ("Calling handle_argv() after cold-plugging connections");
 
1426
        handle_argv (panel);
1201
1427
}
1202
1428
 
1203
1429
void