We were not listening for state changes on the ActiveConnection objects representing actual connections, but only listened for active connections appearing or disappearing. This caused the VPN tab to get stuck on 'Authentication required' or similar 'intermediate' states until you manually switch tabs and back. Also keep the switch from jumping back to off while the vpn auth dialog is up, by adjusting the states we consider 'off'.
2397 lines
92 KiB
C
2397 lines
92 KiB
C
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
|
*
|
|
* Copyright (C) 2010-2011 Richard Hughes <richard@hughsie.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <glib/gi18n.h>
|
|
#include <arpa/inet.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "cc-network-panel.h"
|
|
|
|
#include "nm-remote-settings.h"
|
|
#include "nm-client.h"
|
|
#include "nm-device.h"
|
|
#include "nm-device-ethernet.h"
|
|
#include "nm-device-modem.h"
|
|
#include "nm-device-wifi.h"
|
|
#include "nm-utils.h"
|
|
#include "nm-active-connection.h"
|
|
#include "nm-vpn-connection.h"
|
|
#include "nm-setting-ip4-config.h"
|
|
#include "nm-setting-ip6-config.h"
|
|
#include "nm-setting-connection.h"
|
|
#include "nm-setting-vpn.h"
|
|
#include "nm-setting-wireless.h"
|
|
|
|
#include "net-object.h"
|
|
#include "net-device.h"
|
|
#include "net-vpn.h"
|
|
|
|
#include "panel-common.h"
|
|
#include "panel-cell-renderer-mode.h"
|
|
#include "panel-cell-renderer-signal.h"
|
|
#include "panel-cell-renderer-security.h"
|
|
|
|
G_DEFINE_DYNAMIC_TYPE (CcNetworkPanel, cc_network_panel, CC_TYPE_PANEL)
|
|
|
|
#define NETWORK_PANEL_PRIVATE(o) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_NETWORK_PANEL, CcNetworkPanelPrivate))
|
|
|
|
struct _CcNetworkPanelPrivate
|
|
{
|
|
GCancellable *cancellable;
|
|
GSettings *proxy_settings;
|
|
GtkBuilder *builder;
|
|
NMClient *client;
|
|
NMRemoteSettings *remote_settings;
|
|
gboolean updating_device;
|
|
};
|
|
|
|
enum {
|
|
PANEL_DEVICES_COLUMN_ICON,
|
|
PANEL_DEVICES_COLUMN_TITLE,
|
|
PANEL_DEVICES_COLUMN_SORT,
|
|
PANEL_DEVICES_COLUMN_OBJECT,
|
|
PANEL_DEVICES_COLUMN_LAST
|
|
};
|
|
|
|
enum {
|
|
PANEL_WIRELESS_COLUMN_ID,
|
|
PANEL_WIRELESS_COLUMN_TITLE,
|
|
PANEL_WIRELESS_COLUMN_SORT,
|
|
PANEL_WIRELESS_COLUMN_STRENGTH,
|
|
PANEL_WIRELESS_COLUMN_MODE,
|
|
PANEL_WIRELESS_COLUMN_SECURITY,
|
|
PANEL_WIRELESS_COLUMN_LAST
|
|
};
|
|
|
|
static void refresh_ui (CcNetworkPanel *panel);
|
|
|
|
static void
|
|
cc_network_panel_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cc_network_panel_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id) {
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cc_network_panel_dispose (GObject *object)
|
|
{
|
|
CcNetworkPanelPrivate *priv = CC_NETWORK_PANEL (object)->priv;
|
|
|
|
if (priv->proxy_settings) {
|
|
g_object_unref (priv->proxy_settings);
|
|
priv->proxy_settings = NULL;
|
|
}
|
|
if (priv->cancellable != NULL) {
|
|
g_cancellable_cancel (priv->cancellable);
|
|
g_object_unref (priv->cancellable);
|
|
priv->cancellable = NULL;
|
|
}
|
|
if (priv->builder != NULL) {
|
|
g_object_unref (priv->builder);
|
|
priv->builder = NULL;
|
|
}
|
|
if (priv->client != NULL) {
|
|
g_object_unref (priv->client);
|
|
priv->client = NULL;
|
|
}
|
|
if (priv->remote_settings != NULL) {
|
|
g_object_unref (priv->remote_settings);
|
|
priv->remote_settings = NULL;
|
|
}
|
|
|
|
G_OBJECT_CLASS (cc_network_panel_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
cc_network_panel_finalize (GObject *object)
|
|
{
|
|
G_OBJECT_CLASS (cc_network_panel_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
cc_network_panel_class_init (CcNetworkPanelClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
g_type_class_add_private (klass, sizeof (CcNetworkPanelPrivate));
|
|
|
|
object_class->get_property = cc_network_panel_get_property;
|
|
object_class->set_property = cc_network_panel_set_property;
|
|
object_class->dispose = cc_network_panel_dispose;
|
|
object_class->finalize = cc_network_panel_finalize;
|
|
}
|
|
|
|
static void
|
|
cc_network_panel_class_finalize (CcNetworkPanelClass *klass)
|
|
{
|
|
}
|
|
|
|
static void
|
|
check_wpad_warning (CcNetworkPanel *panel)
|
|
{
|
|
GtkWidget *widget;
|
|
gchar *autoconfig_url = NULL;
|
|
GString *string = NULL;
|
|
gboolean ret = FALSE;
|
|
guint mode;
|
|
|
|
string = g_string_new ("");
|
|
|
|
/* check we're using 'Automatic' */
|
|
mode = g_settings_get_enum (panel->priv->proxy_settings, "mode");
|
|
if (mode != 2)
|
|
goto out;
|
|
|
|
/* see if the PAC is blank */
|
|
autoconfig_url = g_settings_get_string (panel->priv->proxy_settings,
|
|
"autoconfig-url");
|
|
ret = autoconfig_url == NULL ||
|
|
autoconfig_url[0] == '\0';
|
|
if (!ret)
|
|
goto out;
|
|
|
|
g_string_append (string, "<small>");
|
|
|
|
/* TRANSLATORS: this is when the use leaves the PAC textbox blank */
|
|
g_string_append (string, _("Web Proxy Autodiscovery is used when a Configuration URL is not provided."));
|
|
|
|
g_string_append (string, " ");
|
|
|
|
/* TRANSLATORS: WPAD is bad: if you enable it on an untrusted
|
|
* network, then anyone else on that network can tell your
|
|
* machine that it should proxy all of your web traffic
|
|
* through them. */
|
|
g_string_append (string, _("This is not recommended for untrusted public networks."));
|
|
g_string_append (string, "</small>");
|
|
out:
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"label_proxy_warning"));
|
|
gtk_label_set_markup (GTK_LABEL (widget), string->str);
|
|
g_free (autoconfig_url);
|
|
g_string_free (string, TRUE);
|
|
}
|
|
|
|
static void
|
|
panel_settings_changed (GSettings *settings,
|
|
const gchar *key,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
check_wpad_warning (panel);
|
|
}
|
|
|
|
static NetObject *
|
|
get_selected_object (CcNetworkPanel *panel)
|
|
{
|
|
GtkWidget *widget;
|
|
GtkTreeSelection *selection;
|
|
GtkTreeModel *model;
|
|
GtkTreeIter iter;
|
|
NetObject *object = NULL;
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"treeview_devices"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
|
|
return NULL;
|
|
}
|
|
|
|
gtk_tree_model_get (model, &iter,
|
|
PANEL_DEVICES_COLUMN_OBJECT, &object,
|
|
-1);
|
|
|
|
return object;
|
|
}
|
|
|
|
static void
|
|
panel_proxy_mode_combo_setup_widgets (CcNetworkPanel *panel, guint value)
|
|
{
|
|
GtkWidget *widget;
|
|
|
|
/* hide or show the PAC text box */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"hbox_proxy_url"));
|
|
gtk_widget_set_visible (widget, value == 2);
|
|
|
|
/* hide or show the manual entry text boxes */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"hbox_proxy_http"));
|
|
gtk_widget_set_visible (widget, value == 1);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"hbox_proxy_shttp"));
|
|
gtk_widget_set_visible (widget, value == 1);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"hbox_proxy_ftp"));
|
|
gtk_widget_set_visible (widget, value == 1);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"hbox_proxy_socks"));
|
|
gtk_widget_set_visible (widget, value == 1);
|
|
|
|
/* perhaps show the wpad warning */
|
|
check_wpad_warning (panel);
|
|
}
|
|
|
|
static void
|
|
panel_proxy_mode_combo_changed_cb (GtkWidget *widget, CcNetworkPanel *panel)
|
|
{
|
|
gboolean ret;
|
|
gint value;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
|
|
/* no selection */
|
|
ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter);
|
|
if (!ret)
|
|
return;
|
|
|
|
/* get entry */
|
|
model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
|
|
gtk_tree_model_get (model, &iter,
|
|
1, &value,
|
|
-1);
|
|
|
|
/* set */
|
|
g_settings_set_enum (panel->priv->proxy_settings, "mode", value);
|
|
|
|
/* hide or show the correct widgets */
|
|
panel_proxy_mode_combo_setup_widgets (panel, value);
|
|
}
|
|
|
|
static void
|
|
panel_set_value_for_combo (CcNetworkPanel *panel, GtkComboBox *combo_box, gint value)
|
|
{
|
|
gboolean ret;
|
|
gint value_tmp;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
|
|
/* get entry */
|
|
model = gtk_combo_box_get_model (combo_box);
|
|
ret = gtk_tree_model_get_iter_first (model, &iter);
|
|
if (!ret)
|
|
return;
|
|
|
|
/* try to make the UI match the setting */
|
|
do {
|
|
gtk_tree_model_get (model, &iter,
|
|
1, &value_tmp,
|
|
-1);
|
|
if (value == value_tmp) {
|
|
gtk_combo_box_set_active_iter (combo_box, &iter);
|
|
break;
|
|
}
|
|
} while (gtk_tree_model_iter_next (model, &iter));
|
|
|
|
/* hide or show the correct widgets */
|
|
panel_proxy_mode_combo_setup_widgets (panel, value);
|
|
}
|
|
|
|
static void
|
|
select_first_device (CcNetworkPanel *panel)
|
|
{
|
|
GtkTreePath *path;
|
|
GtkWidget *widget;
|
|
GtkTreeSelection *selection;
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"treeview_devices"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
|
|
/* select the first device */
|
|
path = gtk_tree_path_new_from_string ("0");
|
|
gtk_tree_selection_select_path (selection, path);
|
|
gtk_tree_path_free (path);
|
|
}
|
|
|
|
static void
|
|
panel_device_got_modem_manager_cb (GObject *source_object,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
GVariant *result = NULL;
|
|
GDBusProxy *proxy;
|
|
NMDevice *device = (NMDevice *) user_data;
|
|
|
|
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
|
if (proxy == NULL) {
|
|
g_warning ("Error creating ModemManager proxy: %s",
|
|
error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
/* get the IMEI */
|
|
result = g_dbus_proxy_get_cached_property (proxy,
|
|
"EquipmentIdentifier");
|
|
|
|
/* save */
|
|
g_object_set_data_full (G_OBJECT (device),
|
|
"ControlCenter::EquipmentIdentifier",
|
|
g_variant_dup_string (result, NULL),
|
|
g_free);
|
|
out:
|
|
if (result != NULL)
|
|
g_variant_unref (result);
|
|
if (proxy != NULL)
|
|
g_object_unref (proxy);
|
|
return;
|
|
}
|
|
|
|
static void
|
|
panel_get_registration_info_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
{
|
|
gchar *operator_code = NULL;
|
|
GError *error = NULL;
|
|
guint registration_status;
|
|
GVariant *result = NULL;
|
|
gchar *operator_name = NULL;
|
|
gchar *operator_name_safe = NULL;
|
|
NMDevice *device = (NMDevice *) user_data;
|
|
|
|
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
|
|
if (result == NULL) {
|
|
g_warning ("Error getting registration info: %s\n",
|
|
error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
/* get values */
|
|
g_variant_get (result, "((uss))",
|
|
®istration_status,
|
|
&operator_code,
|
|
&operator_name);
|
|
if (operator_name != NULL && operator_name[0] != '\0')
|
|
operator_name_safe = g_strescape (operator_name, NULL);
|
|
|
|
/* save */
|
|
g_object_set_data_full (G_OBJECT (device),
|
|
"ControlCenter::OperatorName",
|
|
operator_name_safe,
|
|
g_free);
|
|
|
|
g_free (operator_name);
|
|
g_free (operator_name_safe);
|
|
g_free (operator_code);
|
|
g_variant_unref (result);
|
|
}
|
|
|
|
static void
|
|
panel_device_got_modem_manager_gsm_cb (GObject *source_object,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
GDBusProxy *proxy;
|
|
NMDevice *device = (NMDevice *) user_data;
|
|
|
|
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
|
if (proxy == NULL) {
|
|
g_warning ("Error creating ModemManager GSM proxy: %s\n",
|
|
error->message);
|
|
g_error_free (error);
|
|
goto out;
|
|
}
|
|
|
|
g_dbus_proxy_call (proxy,
|
|
"GetRegistrationInfo",
|
|
NULL,
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
NULL,
|
|
panel_get_registration_info_cb,
|
|
device);
|
|
out:
|
|
if (proxy != NULL)
|
|
g_object_unref (proxy);
|
|
return;
|
|
}
|
|
|
|
static void
|
|
device_state_notify_changed_cb (NMDevice *device,
|
|
GParamSpec *pspec,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
refresh_ui (panel);
|
|
}
|
|
|
|
static void
|
|
object_changed_cb (NetObject *object, CcNetworkPanel *panel)
|
|
{
|
|
refresh_ui (panel);
|
|
}
|
|
|
|
static void
|
|
object_removed_cb (NetObject *object, CcNetworkPanel *panel)
|
|
{
|
|
gboolean ret;
|
|
NetObject *object_tmp;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkWidget *widget;
|
|
GtkTreeSelection *selection;
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"treeview_devices"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
|
|
/* remove device from model */
|
|
model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder,
|
|
"liststore_devices"));
|
|
ret = gtk_tree_model_get_iter_first (model, &iter);
|
|
if (!ret)
|
|
return;
|
|
|
|
/* get the other elements */
|
|
do {
|
|
gtk_tree_model_get (model, &iter,
|
|
PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
|
|
-1);
|
|
if (g_strcmp0 (net_object_get_id (object),
|
|
net_object_get_id (object_tmp)) == 0) {
|
|
g_object_unref (object_tmp);
|
|
if (!gtk_list_store_remove (GTK_LIST_STORE (model), &iter))
|
|
gtk_tree_model_get_iter_first (model, &iter);
|
|
gtk_tree_selection_select_iter (selection, &iter);
|
|
|
|
break;
|
|
}
|
|
g_object_unref (object_tmp);
|
|
} while (gtk_tree_model_iter_next (model, &iter));
|
|
}
|
|
|
|
static void
|
|
register_object_interest (CcNetworkPanel *panel, NetObject *object)
|
|
{
|
|
g_signal_connect (object,
|
|
"changed",
|
|
G_CALLBACK (object_changed_cb),
|
|
panel);
|
|
g_signal_connect (object,
|
|
"removed",
|
|
G_CALLBACK (object_removed_cb),
|
|
panel);
|
|
}
|
|
|
|
static void
|
|
panel_add_device (CcNetworkPanel *panel, NMDevice *device)
|
|
{
|
|
GtkListStore *liststore_devices;
|
|
GtkTreeIter iter;
|
|
gchar *title = NULL;
|
|
NMDeviceType type;
|
|
NetDevice *net_device;
|
|
CcNetworkPanelPrivate *priv = panel->priv;
|
|
|
|
g_debug ("device %s type %i",
|
|
nm_device_get_udi (device),
|
|
nm_device_get_device_type (device));
|
|
g_signal_connect (G_OBJECT (device), "notify::state",
|
|
(GCallback) device_state_notify_changed_cb, panel);
|
|
|
|
/* do we have to get additonal data from ModemManager */
|
|
type = nm_device_get_device_type (device);
|
|
if (type == NM_DEVICE_TYPE_MODEM) {
|
|
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"org.freedesktop.ModemManager",
|
|
nm_device_get_udi (device),
|
|
"org.freedesktop.ModemManager.Modem",
|
|
panel->priv->cancellable,
|
|
panel_device_got_modem_manager_cb,
|
|
device);
|
|
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"org.freedesktop.ModemManager",
|
|
nm_device_get_udi (device),
|
|
"org.freedesktop.ModemManager.Modem.Gsm.Network",
|
|
panel->priv->cancellable,
|
|
panel_device_got_modem_manager_gsm_cb,
|
|
device);
|
|
}
|
|
|
|
/* make title a bit bigger */
|
|
title = g_strdup_printf ("<span size=\"large\">%s</span>",
|
|
panel_device_to_localized_string (device));
|
|
|
|
liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
|
|
"liststore_devices"));
|
|
net_device = net_device_new ();
|
|
net_device_set_nm_device (net_device, device);
|
|
net_object_set_id (NET_OBJECT (net_device), nm_device_get_udi (device));
|
|
register_object_interest (panel, NET_OBJECT (net_device));
|
|
gtk_list_store_append (liststore_devices, &iter);
|
|
gtk_list_store_set (liststore_devices,
|
|
&iter,
|
|
PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device),
|
|
PANEL_DEVICES_COLUMN_SORT, panel_device_to_sortable_string (device),
|
|
PANEL_DEVICES_COLUMN_TITLE, title,
|
|
PANEL_DEVICES_COLUMN_OBJECT, net_device,
|
|
-1);
|
|
g_free (title);
|
|
}
|
|
|
|
static void
|
|
panel_remove_device (CcNetworkPanel *panel, NMDevice *device)
|
|
{
|
|
gboolean ret;
|
|
NetObject *object_tmp;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
|
|
/* remove device from model */
|
|
model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder,
|
|
"liststore_devices"));
|
|
ret = gtk_tree_model_get_iter_first (model, &iter);
|
|
if (!ret)
|
|
return;
|
|
|
|
/* get the other elements */
|
|
do {
|
|
gtk_tree_model_get (model, &iter,
|
|
PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
|
|
-1);
|
|
if (g_strcmp0 (net_object_get_id (object_tmp),
|
|
nm_device_get_udi (device)) == 0) {
|
|
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
|
|
g_object_unref (object_tmp);
|
|
break;
|
|
}
|
|
g_object_unref (object_tmp);
|
|
} while (gtk_tree_model_iter_next (model, &iter));
|
|
}
|
|
|
|
static void
|
|
panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview)
|
|
{
|
|
CcNetworkPanelPrivate *priv = panel->priv;
|
|
GtkCellRenderer *renderer;
|
|
GtkListStore *liststore_devices;
|
|
GtkTreeViewColumn *column;
|
|
|
|
/* image */
|
|
renderer = gtk_cell_renderer_pixbuf_new ();
|
|
g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DND, NULL);
|
|
column = gtk_tree_view_column_new_with_attributes ("", renderer,
|
|
"icon-name", PANEL_DEVICES_COLUMN_ICON,
|
|
NULL);
|
|
gtk_tree_view_append_column (treeview, column);
|
|
|
|
/* column for text */
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
g_object_set (renderer,
|
|
"wrap-mode", PANGO_WRAP_WORD,
|
|
NULL);
|
|
column = gtk_tree_view_column_new_with_attributes ("", renderer,
|
|
"markup", PANEL_DEVICES_COLUMN_TITLE,
|
|
NULL);
|
|
gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_SORT);
|
|
liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
|
|
"liststore_devices"));
|
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore_devices),
|
|
PANEL_DEVICES_COLUMN_SORT,
|
|
GTK_SORT_ASCENDING);
|
|
gtk_tree_view_append_column (treeview, column);
|
|
gtk_tree_view_column_set_expand (column, TRUE);
|
|
}
|
|
|
|
static void
|
|
panel_set_widget_data (CcNetworkPanel *panel,
|
|
const gchar *sub_pane,
|
|
const gchar *widget_suffix,
|
|
const gchar *value)
|
|
{
|
|
gchar *hbox_id;
|
|
gchar *label_id = NULL;
|
|
GtkWidget *widget;
|
|
CcNetworkPanelPrivate *priv = panel->priv;
|
|
|
|
/* hide the parent bix if there is no value */
|
|
hbox_id = g_strdup_printf ("hbox_%s_%s", sub_pane, widget_suffix);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, hbox_id));
|
|
if (widget == NULL) {
|
|
g_warning ("no %s widget", hbox_id);
|
|
goto out;
|
|
}
|
|
if (value == NULL) {
|
|
gtk_widget_hide (widget);
|
|
goto out;
|
|
}
|
|
|
|
/* there exists a value */
|
|
gtk_widget_show (widget);
|
|
label_id = g_strdup_printf ("label_%s_%s", sub_pane, widget_suffix);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, label_id));
|
|
gtk_label_set_label (GTK_LABEL (widget), value);
|
|
out:
|
|
g_free (hbox_id);
|
|
g_free (label_id);
|
|
}
|
|
|
|
static void
|
|
panel_set_widget_heading (CcNetworkPanel *panel,
|
|
const gchar *sub_pane,
|
|
const gchar *widget_suffix,
|
|
const gchar *heading)
|
|
{
|
|
gchar *label_id = NULL;
|
|
GtkWidget *widget;
|
|
|
|
label_id = g_strdup_printf ("heading_%s_%s", sub_pane, widget_suffix);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, label_id));
|
|
if (widget)
|
|
gtk_label_set_label (GTK_LABEL (widget), heading);
|
|
g_free (label_id);
|
|
}
|
|
|
|
static guint
|
|
get_access_point_security (NMAccessPoint *ap)
|
|
{
|
|
NM80211ApFlags flags;
|
|
NM80211ApSecurityFlags wpa_flags;
|
|
NM80211ApSecurityFlags rsn_flags;
|
|
guint type;
|
|
|
|
flags = nm_access_point_get_flags (ap);
|
|
wpa_flags = nm_access_point_get_wpa_flags (ap);
|
|
rsn_flags = nm_access_point_get_rsn_flags (ap);
|
|
|
|
if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) &&
|
|
wpa_flags == NM_802_11_AP_SEC_NONE &&
|
|
rsn_flags == NM_802_11_AP_SEC_NONE)
|
|
type = NM_AP_SEC_NONE;
|
|
else if ((flags & NM_802_11_AP_FLAGS_PRIVACY) &&
|
|
wpa_flags == NM_802_11_AP_SEC_NONE &&
|
|
rsn_flags == NM_802_11_AP_SEC_NONE)
|
|
type = NM_AP_SEC_WEP;
|
|
else if (!(flags & NM_802_11_AP_FLAGS_PRIVACY) &&
|
|
wpa_flags != NM_802_11_AP_SEC_NONE &&
|
|
rsn_flags != NM_802_11_AP_SEC_NONE)
|
|
type = NM_AP_SEC_WPA;
|
|
else
|
|
type = NM_AP_SEC_WPA2;
|
|
|
|
return type;
|
|
}
|
|
|
|
static void
|
|
add_access_point (CcNetworkPanel *panel, NMAccessPoint *ap, NMAccessPoint *active)
|
|
{
|
|
CcNetworkPanelPrivate *priv = panel->priv;
|
|
const GByteArray *ssid;
|
|
const gchar *ssid_text;
|
|
const gchar *object_path;
|
|
GtkListStore *liststore_wireless_network;
|
|
GtkTreeIter treeiter;
|
|
GtkWidget *widget;
|
|
|
|
ssid = nm_access_point_get_ssid (ap);
|
|
if (ssid == NULL)
|
|
return;
|
|
ssid_text = nm_utils_escape_ssid (ssid->data, ssid->len);
|
|
|
|
liststore_wireless_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
|
|
"liststore_wireless_network"));
|
|
|
|
object_path = nm_object_get_path (NM_OBJECT (ap));
|
|
gtk_list_store_append (liststore_wireless_network, &treeiter);
|
|
gtk_list_store_set (liststore_wireless_network,
|
|
&treeiter,
|
|
PANEL_WIRELESS_COLUMN_ID, object_path,
|
|
PANEL_WIRELESS_COLUMN_TITLE, ssid_text,
|
|
PANEL_WIRELESS_COLUMN_SORT, ssid_text,
|
|
PANEL_WIRELESS_COLUMN_STRENGTH, nm_access_point_get_strength (ap),
|
|
PANEL_WIRELESS_COLUMN_MODE, nm_access_point_get_mode (ap),
|
|
PANEL_WIRELESS_COLUMN_SECURITY, get_access_point_security (ap),
|
|
-1);
|
|
|
|
/* is this what we're on already? */
|
|
if (active == NULL)
|
|
return;
|
|
if (g_strcmp0 (object_path,
|
|
nm_object_get_path (NM_OBJECT (active))) == 0) {
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"combobox_network_name"));
|
|
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (widget), &treeiter);
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
static gchar *
|
|
ip4_address_as_string (guint32 ip)
|
|
{
|
|
char buf[INET_ADDRSTRLEN+1];
|
|
struct in_addr tmp_addr;
|
|
|
|
memset (&buf, '\0', sizeof (buf));
|
|
tmp_addr.s_addr = ip;
|
|
|
|
if (inet_ntop (AF_INET, &tmp_addr, buf, INET_ADDRSTRLEN)) {
|
|
return g_strdup (buf);
|
|
} else {
|
|
g_warning ("error converting IP4 address 0x%X",
|
|
ntohl (tmp_addr.s_addr));
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static void
|
|
panel_show_ip4_config (NMIP4Config *cfg)
|
|
{
|
|
gchar *tmp;
|
|
const GArray *array;
|
|
const GPtrArray *ptr_array;
|
|
GSList *iter;
|
|
int i;
|
|
|
|
for (iter = (GSList *) nm_ip4_config_get_addresses (cfg); iter; iter = g_slist_next (iter)) {
|
|
NMIP4Address *addr = iter->data;
|
|
guint32 u;
|
|
|
|
tmp = ip4_address_as_string (nm_ip4_address_get_address (addr));
|
|
g_debug ("IP4 address: %s", tmp);
|
|
g_free (tmp);
|
|
|
|
u = nm_ip4_address_get_prefix (addr);
|
|
tmp = ip4_address_as_string (nm_utils_ip4_prefix_to_netmask (u));
|
|
g_debug ("IP4 prefix: %d (%s)", u, tmp);
|
|
g_free (tmp);
|
|
|
|
tmp = ip4_address_as_string (nm_ip4_address_get_gateway (addr));
|
|
g_debug ("IP4 gateway: %s", tmp);
|
|
g_free (tmp);
|
|
}
|
|
|
|
array = nm_ip4_config_get_nameservers (cfg);
|
|
if (array) {
|
|
g_debug ("IP4 DNS:");
|
|
for (i = 0; i < array->len; i++) {
|
|
tmp = ip4_address_as_string (g_array_index (array, guint32, i));
|
|
g_debug ("\t%s", tmp);
|
|
g_free (tmp);
|
|
}
|
|
}
|
|
|
|
ptr_array = nm_ip4_config_get_domains (cfg);
|
|
if (ptr_array) {
|
|
g_debug ("IP4 domains:");
|
|
for (i = 0; i < ptr_array->len; i++)
|
|
g_debug ("\t%s", (const char *) g_ptr_array_index (ptr_array, i));
|
|
}
|
|
|
|
array = nm_ip4_config_get_wins_servers (cfg);
|
|
if (array) {
|
|
g_debug ("IP4 WINS:");
|
|
for (i = 0; i < array->len; i++) {
|
|
tmp = ip4_address_as_string (g_array_index (array, guint32, i));
|
|
g_debug ("\t%s", tmp);
|
|
g_free (tmp);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static GPtrArray *
|
|
panel_get_strongest_unique_aps (const GPtrArray *aps)
|
|
{
|
|
const GByteArray *ssid;
|
|
const GByteArray *ssid_tmp;
|
|
GPtrArray *aps_unique = NULL;
|
|
gboolean add_ap;
|
|
guint i;
|
|
guint j;
|
|
NMAccessPoint *ap;
|
|
NMAccessPoint *ap_tmp;
|
|
|
|
/* we will have multiple entries for typical hotspots, just
|
|
* filter to the one with the strongest signal */
|
|
aps_unique = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
|
if (aps != NULL)
|
|
for (i = 0; i < aps->len; i++) {
|
|
ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
|
|
ssid = nm_access_point_get_ssid (ap);
|
|
add_ap = TRUE;
|
|
|
|
/* get already added list */
|
|
for (j=0; j<aps_unique->len; j++) {
|
|
ap_tmp = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, j));
|
|
ssid_tmp = nm_access_point_get_ssid (ap_tmp);
|
|
|
|
/* is this the same type and data? */
|
|
if (nm_utils_same_ssid (ssid, ssid_tmp, TRUE)) {
|
|
|
|
g_debug ("found duplicate: %s",
|
|
nm_utils_escape_ssid (ssid_tmp->data,
|
|
ssid_tmp->len));
|
|
|
|
/* the new access point is stronger */
|
|
if (nm_access_point_get_strength (ap) >
|
|
nm_access_point_get_strength (ap_tmp)) {
|
|
g_debug ("removing %s",
|
|
nm_utils_escape_ssid (ssid_tmp->data,
|
|
ssid_tmp->len));
|
|
g_ptr_array_remove (aps_unique, ap_tmp);
|
|
add_ap = TRUE;
|
|
} else {
|
|
add_ap = FALSE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
if (add_ap) {
|
|
g_debug ("adding %s",
|
|
nm_utils_escape_ssid (ssid->data,
|
|
ssid->len));
|
|
g_ptr_array_add (aps_unique, g_object_ref (ap));
|
|
}
|
|
}
|
|
return aps_unique;
|
|
}
|
|
|
|
static gchar *
|
|
get_ap_security_string (NMAccessPoint *ap)
|
|
{
|
|
NM80211ApSecurityFlags wpa_flags, rsn_flags;
|
|
NM80211ApFlags flags;
|
|
GString *str;
|
|
|
|
flags = nm_access_point_get_flags (ap);
|
|
wpa_flags = nm_access_point_get_wpa_flags (ap);
|
|
rsn_flags = nm_access_point_get_rsn_flags (ap);
|
|
|
|
str = g_string_new ("");
|
|
if ((flags & NM_802_11_AP_FLAGS_PRIVACY) &&
|
|
(wpa_flags == NM_802_11_AP_SEC_NONE) &&
|
|
(rsn_flags == NM_802_11_AP_SEC_NONE)) {
|
|
/* TRANSLATORS: this WEP WiFi security */
|
|
g_string_append_printf (str, "%s, ", _("WEP"));
|
|
}
|
|
if (wpa_flags != NM_802_11_AP_SEC_NONE) {
|
|
/* TRANSLATORS: this WPA WiFi security */
|
|
g_string_append_printf (str, "%s, ", _("WPA"));
|
|
}
|
|
if (rsn_flags != NM_802_11_AP_SEC_NONE) {
|
|
/* TRANSLATORS: this WPA WiFi security */
|
|
g_string_append_printf (str, "%s, ", _("WPA2"));
|
|
}
|
|
if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) ||
|
|
(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
|
|
/* TRANSLATORS: this Enterprise WiFi security */
|
|
g_string_append_printf (str, "%s, ", _("Enterprise"));
|
|
}
|
|
if (str->len > 0)
|
|
g_string_set_size (str, str->len - 2);
|
|
else {
|
|
/* TRANSLATORS: this no (!) WiFi security */
|
|
g_string_append (str, _("None"));
|
|
}
|
|
return g_string_free (str, FALSE);
|
|
}
|
|
|
|
static gchar *
|
|
get_ipv6_config_address_as_string (NMIP6Config *ip6_config)
|
|
{
|
|
const GSList *list;
|
|
const struct in6_addr *addr;
|
|
gchar *str = NULL;
|
|
gchar tmp[1024];
|
|
NMIP6Address *address;
|
|
|
|
/* get address */
|
|
list = nm_ip6_config_get_addresses (ip6_config);
|
|
if (list == NULL)
|
|
goto out;
|
|
|
|
/* we only care about one address */
|
|
address = list->data;
|
|
addr = nm_ip6_address_get_address (address);
|
|
if (addr == NULL)
|
|
goto out;
|
|
inet_ntop (AF_INET6, addr, tmp, sizeof(tmp));
|
|
str = g_strdup (tmp);
|
|
out:
|
|
return str;
|
|
}
|
|
|
|
static NMConnection *
|
|
find_connection_for_device (CcNetworkPanel *panel,
|
|
NMDevice *device)
|
|
{
|
|
const GPtrArray *connections;
|
|
const GPtrArray *devices;
|
|
NMActiveConnection *c;
|
|
gint i;
|
|
|
|
connections = nm_client_get_active_connections (panel->priv->client);
|
|
|
|
for (i = 0; i < connections->len; i++) {
|
|
c = (NMActiveConnection *)connections->pdata[i];
|
|
|
|
devices = nm_active_connection_get_devices (c);
|
|
if (devices->pdata[0] == device) {
|
|
return (NMConnection *)nm_remote_settings_get_connection_by_path (panel->priv->remote_settings, nm_active_connection_get_connection (c));
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
device_off_toggled (GtkSwitch *sw,
|
|
GParamSpec *pspec,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
NMDevice *device;
|
|
gboolean active;
|
|
NetObject *object;
|
|
|
|
if (panel->priv->updating_device)
|
|
return;
|
|
|
|
active = gtk_switch_get_active (sw);
|
|
|
|
object = get_selected_object (panel);
|
|
if (NET_IS_VPN (object)) {
|
|
|
|
NMConnection *connection;
|
|
|
|
connection = net_vpn_get_connection (NET_VPN (object));
|
|
if (active)
|
|
nm_client_activate_connection (panel->priv->client,
|
|
connection, NULL, NULL,
|
|
NULL, NULL);
|
|
else {
|
|
const gchar *path;
|
|
NMActiveConnection *a;
|
|
const GPtrArray *acs;
|
|
gint i;
|
|
|
|
path = nm_connection_get_path (connection);
|
|
|
|
acs = nm_client_get_active_connections (panel->priv->client);
|
|
for (i = 0; i < acs->len; i++) {
|
|
a = (NMActiveConnection*)acs->pdata[i];
|
|
if (strcmp (nm_active_connection_get_connection (a), path) == 0) {
|
|
nm_client_deactivate_connection (panel->priv->client, a);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (NET_IS_DEVICE (object)) {
|
|
device = net_device_get_nm_device (NET_DEVICE (object));
|
|
switch (nm_device_get_device_type (device)) {
|
|
case NM_DEVICE_TYPE_ETHERNET:
|
|
if (active) {
|
|
GSList *list, *filtered;
|
|
|
|
/* look for an existing connection we can use */
|
|
list = nm_remote_settings_list_connections (panel->priv->remote_settings);
|
|
filtered = nm_device_filter_connections (device, list);
|
|
if (filtered) {
|
|
nm_client_activate_connection (panel->priv->client,
|
|
(NMConnection *)filtered->data,
|
|
device,
|
|
NULL,
|
|
NULL, NULL);
|
|
}
|
|
else {
|
|
nm_client_add_and_activate_connection (panel->priv->client,
|
|
NULL,
|
|
device,
|
|
NULL,
|
|
NULL, NULL);
|
|
}
|
|
|
|
g_slist_free (list);
|
|
g_slist_free (filtered);
|
|
} else {
|
|
nm_device_disconnect (device, NULL, NULL);
|
|
}
|
|
break;
|
|
case NM_DEVICE_TYPE_WIFI:
|
|
nm_client_wireless_set_enabled (panel->priv->client, active);
|
|
break;
|
|
case NM_DEVICE_TYPE_WIMAX:
|
|
nm_client_wimax_set_enabled (panel->priv->client, active);
|
|
break;
|
|
default: ;
|
|
/* FIXME: handle other device types */
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
wireless_enabled_toggled (NMClient *client,
|
|
GParamSpec *pspec,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
gboolean enabled;
|
|
GtkSwitch *sw;
|
|
NMDevice *device;
|
|
NetObject *object;
|
|
|
|
object = get_selected_object (panel);
|
|
if (object == NULL)
|
|
return;
|
|
device = net_device_get_nm_device (NET_DEVICE (object));
|
|
|
|
if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIFI)
|
|
return;
|
|
|
|
enabled = nm_client_wireless_get_enabled (client);
|
|
sw = GTK_SWITCH (gtk_builder_get_object (panel->priv->builder,
|
|
"device_off_switch"));
|
|
|
|
panel->priv->updating_device = TRUE;
|
|
gtk_switch_set_active (sw, enabled);
|
|
panel->priv->updating_device = FALSE;
|
|
}
|
|
|
|
static void
|
|
wimax_enabled_toggled (NMClient *client,
|
|
GParamSpec *pspec,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
gboolean enabled;
|
|
GtkSwitch *sw;
|
|
NMDevice *device;
|
|
NetObject *object;
|
|
|
|
object = get_selected_object (panel);
|
|
if (object == NULL)
|
|
return;
|
|
device = net_device_get_nm_device (NET_DEVICE (object));
|
|
|
|
if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_WIMAX)
|
|
return;
|
|
|
|
enabled = nm_client_wimax_get_enabled (client);
|
|
sw = GTK_SWITCH (gtk_builder_get_object (panel->priv->builder,
|
|
"device_off_switch"));
|
|
|
|
panel->priv->updating_device = TRUE;
|
|
gtk_switch_set_active (sw, enabled);
|
|
panel->priv->updating_device = FALSE;
|
|
}
|
|
|
|
static void
|
|
update_off_switch_from_device_state (GtkSwitch *sw, NMDeviceState state, CcNetworkPanel *panel)
|
|
{
|
|
panel->priv->updating_device = TRUE;
|
|
switch (state) {
|
|
case NM_DEVICE_STATE_UNMANAGED:
|
|
case NM_DEVICE_STATE_UNAVAILABLE:
|
|
case NM_DEVICE_STATE_DISCONNECTED:
|
|
case NM_DEVICE_STATE_DEACTIVATING:
|
|
case NM_DEVICE_STATE_FAILED:
|
|
gtk_switch_set_active (sw, FALSE);
|
|
break;
|
|
default:
|
|
gtk_switch_set_active (sw, TRUE);
|
|
break;
|
|
}
|
|
panel->priv->updating_device = FALSE;
|
|
}
|
|
|
|
static void
|
|
nm_device_refresh_device_ui (CcNetworkPanel *panel, NetDevice *device)
|
|
{
|
|
CcNetworkPanelPrivate *priv = panel->priv;
|
|
const gchar *str;
|
|
const gchar *sub_pane = NULL;
|
|
gchar *str_tmp;
|
|
GHashTable *options = NULL;
|
|
GtkListStore *liststore_wireless_network;
|
|
GtkWidget *widget;
|
|
GtkWidget *sw;
|
|
guint i;
|
|
guint speed;
|
|
NMAccessPoint *ap;
|
|
NMAccessPoint *active_ap;
|
|
NMDeviceState state;
|
|
NMDeviceType type;
|
|
NMDHCP4Config *config_dhcp4 = NULL;
|
|
NMIP6Config *ip6_config = NULL;
|
|
NMDevice *nm_device;
|
|
gboolean has_ip4;
|
|
gboolean has_ip6;
|
|
|
|
/* we have a new device */
|
|
nm_device = net_device_get_nm_device (device);
|
|
type = nm_device_get_device_type (nm_device);
|
|
g_debug ("device %s type %i", nm_device_get_udi (nm_device), type);
|
|
|
|
/* set header icon */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"image_device"));
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (widget),
|
|
panel_device_to_icon_name (nm_device),
|
|
GTK_ICON_SIZE_DIALOG);
|
|
|
|
/* set device kind */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_device"));
|
|
gtk_label_set_label (GTK_LABEL (widget),
|
|
panel_device_to_localized_string (nm_device));
|
|
|
|
|
|
/* set device state */
|
|
state = nm_device_get_state (nm_device);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_status"));
|
|
str = panel_device_state_to_localized_string (type, state);
|
|
gtk_label_set_label (GTK_LABEL (widget), str);
|
|
|
|
/* set up the options button */
|
|
switch (type) {
|
|
case NM_DEVICE_TYPE_ETHERNET:
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"button_wired_options"));
|
|
gtk_widget_set_sensitive (widget, state == NM_DEVICE_STATE_ACTIVATED);
|
|
break;
|
|
case NM_DEVICE_TYPE_WIFI:
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"button_wireless_options"));
|
|
gtk_widget_set_sensitive (widget, state == NM_DEVICE_STATE_ACTIVATED);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* set up the device on/off switch */
|
|
sw = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"device_off_switch"));
|
|
/* keep this in sync with the signal handler setup in cc_network_panel_init */
|
|
switch (type) {
|
|
case NM_DEVICE_TYPE_ETHERNET:
|
|
gtk_widget_set_visible (sw, state != NM_DEVICE_STATE_UNAVAILABLE &&
|
|
state != NM_DEVICE_STATE_UNMANAGED);
|
|
update_off_switch_from_device_state (GTK_SWITCH (sw), state, panel);
|
|
break;
|
|
case NM_DEVICE_TYPE_WIFI:
|
|
gtk_widget_show (sw);
|
|
wireless_enabled_toggled (priv->client, NULL, panel);
|
|
break;
|
|
case NM_DEVICE_TYPE_WIMAX:
|
|
gtk_widget_show (sw);
|
|
wimax_enabled_toggled (priv->client, NULL, panel);
|
|
break;
|
|
default:
|
|
gtk_widget_hide (sw);
|
|
break;
|
|
}
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"notebook_types"));
|
|
if (type == NM_DEVICE_TYPE_ETHERNET) {
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
|
|
sub_pane = "wired";
|
|
} else if (type == NM_DEVICE_TYPE_WIFI) {
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1);
|
|
sub_pane = "wireless";
|
|
} else if (type == NM_DEVICE_TYPE_MODEM) {
|
|
NMDeviceModemCapabilities caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (nm_device));
|
|
if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) ||
|
|
(caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) {
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 4);
|
|
sub_pane = "mobilebb";
|
|
}
|
|
}
|
|
if (sub_pane == NULL)
|
|
goto out;
|
|
|
|
#if 0
|
|
/* FIXME? should we need to do something with this? */
|
|
if (state == NM_DEVICE_STATE_ACTIVATED)
|
|
panel_show_ip4_config (nm_device_get_ip4_config (nm_device));
|
|
#endif
|
|
|
|
if (type == NM_DEVICE_TYPE_ETHERNET) {
|
|
|
|
/* speed */
|
|
speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (nm_device));
|
|
if (state == NM_DEVICE_STATE_UNAVAILABLE)
|
|
str_tmp = NULL;
|
|
else if (speed > 0)
|
|
/* Translators: network device speed */
|
|
str_tmp = g_strdup_printf (_("%d Mb/s"), speed);
|
|
else
|
|
str_tmp = g_strdup ("");
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"speed",
|
|
str_tmp);
|
|
g_free (str_tmp);
|
|
|
|
/* device MAC */
|
|
str = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (nm_device));
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"mac",
|
|
str);
|
|
|
|
} else if (type == NM_DEVICE_TYPE_WIFI) {
|
|
const GPtrArray *aps;
|
|
GPtrArray *aps_unique = NULL;
|
|
|
|
/* speed */
|
|
speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (nm_device));
|
|
if (state == NM_DEVICE_STATE_UNAVAILABLE)
|
|
str_tmp = NULL;
|
|
else if (speed > 0)
|
|
str_tmp = g_strdup_printf (_("%d Mb/s"),
|
|
speed / 1000);
|
|
else
|
|
str_tmp = g_strdup ("");
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"speed",
|
|
str_tmp);
|
|
g_free (str_tmp);
|
|
|
|
/* device MAC */
|
|
str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device));
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"mac",
|
|
str);
|
|
/* security */
|
|
active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device));
|
|
if (state == NM_DEVICE_STATE_UNAVAILABLE)
|
|
str_tmp = NULL;
|
|
else if (active_ap != NULL)
|
|
str_tmp = get_ap_security_string (active_ap);
|
|
else
|
|
str_tmp = g_strdup ("");
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"security",
|
|
str_tmp);
|
|
g_free (str_tmp);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"hbox_wireless_ssid"));
|
|
/* populate access point dropdown */
|
|
if (state == NM_DEVICE_STATE_UNAVAILABLE)
|
|
gtk_widget_hide (widget);
|
|
else {
|
|
gtk_widget_show (widget);
|
|
liststore_wireless_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder,
|
|
"liststore_wireless_network"));
|
|
priv->updating_device = TRUE;
|
|
gtk_list_store_clear (liststore_wireless_network);
|
|
aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device));
|
|
aps_unique = panel_get_strongest_unique_aps (aps);
|
|
|
|
for (i = 0; i < aps_unique->len; i++) {
|
|
ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i));
|
|
add_access_point (panel, ap, active_ap);
|
|
}
|
|
priv->updating_device = FALSE;
|
|
|
|
g_ptr_array_unref (aps_unique);
|
|
}
|
|
|
|
} else if (type == NM_DEVICE_TYPE_MODEM) {
|
|
NMDeviceModemCapabilities caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (nm_device));
|
|
|
|
if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) ||
|
|
(caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) {
|
|
/* IMEI */
|
|
str = g_object_get_data (G_OBJECT (nm_device),
|
|
"ControlCenter::EquipmentIdentifier");
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"imei",
|
|
str);
|
|
|
|
/* operator name */
|
|
str = g_object_get_data (G_OBJECT (nm_device),
|
|
"ControlCenter::OperatorName");
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"provider",
|
|
str);
|
|
|
|
/* device speed */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"speed",
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
/* get IP4 parameters */
|
|
config_dhcp4 = nm_device_get_dhcp4_config (nm_device);
|
|
if (config_dhcp4 != NULL) {
|
|
g_object_get (G_OBJECT (config_dhcp4),
|
|
NM_DHCP4_CONFIG_OPTIONS, &options,
|
|
NULL);
|
|
|
|
/* IPv4 address */
|
|
str = nm_dhcp4_config_get_one_option (config_dhcp4,
|
|
"ip_address");
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"ip4",
|
|
str);
|
|
has_ip4 = str != NULL;
|
|
|
|
/* IPv4 DNS */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"dns",
|
|
nm_dhcp4_config_get_one_option (config_dhcp4,
|
|
"domain_name_servers"));
|
|
|
|
/* IPv4 route */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"route",
|
|
nm_dhcp4_config_get_one_option (config_dhcp4,
|
|
"routers"));
|
|
|
|
/* IPv4 netmask */
|
|
if (type == NM_DEVICE_TYPE_ETHERNET) {
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"subnet",
|
|
nm_dhcp4_config_get_one_option (config_dhcp4,
|
|
"subnet_mask"));
|
|
}
|
|
} else {
|
|
/* IPv4 address */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"ip4",
|
|
NULL);
|
|
has_ip4 = FALSE;
|
|
|
|
/* IPv4 DNS */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"dns",
|
|
NULL);
|
|
|
|
/* IPv4 route */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"route",
|
|
NULL);
|
|
|
|
/* IPv4 netmask */
|
|
if (type == NM_DEVICE_TYPE_ETHERNET) {
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"subnet",
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
/* get IP6 parameters */
|
|
ip6_config = nm_device_get_ip6_config (nm_device);
|
|
if (ip6_config != NULL) {
|
|
|
|
/* IPv6 address */
|
|
str_tmp = get_ipv6_config_address_as_string (ip6_config);
|
|
panel_set_widget_data (panel, sub_pane, "ip6", str_tmp);
|
|
has_ip6 = str_tmp != NULL;
|
|
g_free (str_tmp);
|
|
} else {
|
|
panel_set_widget_data (panel, sub_pane, "ip6", NULL);
|
|
has_ip6 = FALSE;
|
|
}
|
|
|
|
if (has_ip4 && has_ip6) {
|
|
panel_set_widget_heading (panel, sub_pane, "ip4", _("IPv4 Address"));
|
|
panel_set_widget_heading (panel, sub_pane, "ip6", _("IPv6 Address"));
|
|
}
|
|
else if (has_ip4) {
|
|
panel_set_widget_heading (panel, sub_pane, "ip4", _("IP Address"));
|
|
}
|
|
else if (has_ip6) {
|
|
panel_set_widget_heading (panel, sub_pane, "ip6", _("IP Address"));
|
|
}
|
|
out: ;
|
|
}
|
|
|
|
static void
|
|
nm_device_refresh_vpn_ui (CcNetworkPanel *panel, NetVpn *vpn)
|
|
{
|
|
GtkWidget *widget;
|
|
GtkWidget *sw;
|
|
const gchar *sub_pane = "vpn";
|
|
const gchar *status;
|
|
CcNetworkPanelPrivate *priv = panel->priv;
|
|
const GPtrArray *acs;
|
|
NMActiveConnection *a;
|
|
gint i;
|
|
const gchar *path;
|
|
const gchar *apath;
|
|
NMVPNConnectionState state;
|
|
|
|
sw = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"device_off_switch"));
|
|
gtk_widget_set_visible (sw, TRUE);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"button_vpn_options"));
|
|
gtk_widget_set_visible (widget, TRUE);
|
|
gtk_widget_set_sensitive (widget, TRUE);
|
|
|
|
/* use proxy note page */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"notebook_types"));
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 3);
|
|
|
|
/* set VPN icon */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"image_device"));
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (widget),
|
|
"network-vpn",
|
|
GTK_ICON_SIZE_DIALOG);
|
|
|
|
/* use title */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_device"));
|
|
gtk_label_set_label (GTK_LABEL (widget), net_object_get_title (NET_OBJECT (vpn)));
|
|
|
|
/* use status */
|
|
state = net_vpn_get_state (vpn);
|
|
|
|
acs = nm_client_get_active_connections (priv->client);
|
|
path = nm_connection_get_path (net_vpn_get_connection (vpn));
|
|
for (i = 0; i < acs->len; i++) {
|
|
a = (NMActiveConnection*)acs->pdata[i];
|
|
|
|
apath = nm_active_connection_get_connection (a);
|
|
if (NM_IS_VPN_CONNECTION (a) && strcmp (apath, path) == 0) {
|
|
state = nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (a));
|
|
break;
|
|
}
|
|
}
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_status"));
|
|
status = panel_vpn_state_to_localized_string (state);
|
|
gtk_label_set_label (GTK_LABEL (widget), status);
|
|
priv->updating_device = TRUE;
|
|
gtk_switch_set_active (GTK_SWITCH (sw),
|
|
state != NM_VPN_CONNECTION_STATE_FAILED &&
|
|
state != NM_VPN_CONNECTION_STATE_DISCONNECTED);
|
|
priv->updating_device = FALSE;
|
|
|
|
/* gateway */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"gateway",
|
|
net_vpn_get_gateway (vpn));
|
|
|
|
/* groupname */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"groupname",
|
|
net_vpn_get_id (vpn));
|
|
|
|
/* username */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"username",
|
|
net_vpn_get_username (vpn));
|
|
|
|
/* password */
|
|
panel_set_widget_data (panel,
|
|
sub_pane,
|
|
"group_password",
|
|
net_vpn_get_password (vpn));
|
|
}
|
|
|
|
static void
|
|
refresh_ui (CcNetworkPanel *panel)
|
|
{
|
|
GtkTreeSelection *selection;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkWidget *widget;
|
|
NetObject *object = NULL;
|
|
CcNetworkPanelPrivate *priv = panel->priv;
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"treeview_devices"));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
|
|
/* will only work in single or browse selection mode! */
|
|
if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
|
|
g_debug ("no row selected");
|
|
goto out;
|
|
}
|
|
|
|
object = get_selected_object (panel);
|
|
|
|
/* this is the proxy settings device */
|
|
if (object == NULL) {
|
|
|
|
/* set header to something sane */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"image_device"));
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (widget),
|
|
"preferences-system-network",
|
|
GTK_ICON_SIZE_DIALOG);
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_device"));
|
|
gtk_label_set_label (GTK_LABEL (widget),
|
|
_("Proxy"));
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"label_status"));
|
|
gtk_label_set_label (GTK_LABEL (widget), "");
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"notebook_types"));
|
|
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2);
|
|
|
|
/* hide the slider until we get some more detail in the mockup */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"device_off_switch"));
|
|
gtk_widget_hide (widget);
|
|
|
|
/* we shoulnd't be able to delete the proxy device */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"remove_toolbutton"));
|
|
gtk_widget_set_sensitive (widget, FALSE);
|
|
goto out;
|
|
}
|
|
|
|
/* VPN */
|
|
if (NET_IS_VPN (object)) {
|
|
nm_device_refresh_vpn_ui (panel, NET_VPN (object));
|
|
|
|
/* we're able to remove the VPN connection */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"remove_toolbutton"));
|
|
gtk_widget_set_sensitive (widget, TRUE);
|
|
goto out;
|
|
}
|
|
|
|
/* device */
|
|
if (NET_IS_DEVICE (object)) {
|
|
|
|
/* we're not yet able to remove the connection */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
|
|
"remove_toolbutton"));
|
|
gtk_widget_set_sensitive (widget, FALSE);
|
|
|
|
/* refresh device */
|
|
nm_device_refresh_device_ui (panel, NET_DEVICE (object));
|
|
}
|
|
out:
|
|
return;
|
|
}
|
|
|
|
static void
|
|
nm_devices_treeview_clicked_cb (GtkTreeSelection *selection, CcNetworkPanel *panel)
|
|
{
|
|
refresh_ui (panel);
|
|
}
|
|
|
|
static void
|
|
panel_add_proxy_device (CcNetworkPanel *panel)
|
|
{
|
|
gchar *title;
|
|
GtkListStore *liststore_devices;
|
|
GtkTreeIter iter;
|
|
|
|
liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
|
|
"liststore_devices"));
|
|
title = g_strdup_printf ("<span size=\"large\">%s</span>",
|
|
_("Network proxy"));
|
|
|
|
gtk_list_store_append (liststore_devices, &iter);
|
|
gtk_list_store_set (liststore_devices,
|
|
&iter,
|
|
PANEL_DEVICES_COLUMN_ICON, "preferences-system-network",
|
|
PANEL_DEVICES_COLUMN_TITLE, title,
|
|
PANEL_DEVICES_COLUMN_SORT, "9",
|
|
PANEL_DEVICES_COLUMN_OBJECT, NULL,
|
|
-1);
|
|
g_free (title);
|
|
}
|
|
|
|
static void
|
|
cc_network_panel_notify_enable_active_cb (GtkSwitch *sw,
|
|
GParamSpec *pspec,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
gboolean enable;
|
|
|
|
/* set enabled state */
|
|
enable = !gtk_switch_get_active (sw);
|
|
nm_client_wireless_set_enabled (panel->priv->client, enable);
|
|
}
|
|
|
|
static void
|
|
connection_state_changed (NMActiveConnection *c, GParamSpec *pspec, CcNetworkPanel *panel)
|
|
{
|
|
refresh_ui (panel);
|
|
}
|
|
|
|
static void
|
|
active_connections_changed (NMClient *client, GParamSpec *pspec, gpointer user_data)
|
|
{
|
|
CcNetworkPanel *panel = user_data;
|
|
const GPtrArray *connections;
|
|
int i, j;
|
|
|
|
g_debug ("Active connections changed:");
|
|
connections = nm_client_get_active_connections (client);
|
|
for (i = 0; connections && (i < connections->len); i++) {
|
|
NMActiveConnection *connection;
|
|
const GPtrArray *devices;
|
|
|
|
connection = g_ptr_array_index (connections, i);
|
|
g_debug (" %s", nm_object_get_path (NM_OBJECT (connection)));
|
|
devices = nm_active_connection_get_devices (connection);
|
|
for (j = 0; devices && j < devices->len; j++)
|
|
g_debug (" %s", nm_device_get_udi (g_ptr_array_index (devices, j)));
|
|
if (NM_IS_VPN_CONNECTION (connection))
|
|
g_debug (" VPN base connection: %s", nm_active_connection_get_specific_object (connection));
|
|
|
|
if (g_object_get_data (G_OBJECT (connection), "has-state-changed-handler") == NULL) {
|
|
g_signal_connect_object (connection, "notify::state",
|
|
G_CALLBACK (connection_state_changed), panel, 0);
|
|
g_object_set_data (G_OBJECT (connection), "has-state-changed-handler", GINT_TO_POINTER (TRUE));
|
|
}
|
|
}
|
|
|
|
refresh_ui (panel);
|
|
}
|
|
|
|
static void
|
|
device_added_cb (NMClient *client, NMDevice *device, CcNetworkPanel *panel)
|
|
{
|
|
g_debug ("New device added");
|
|
panel_add_device (panel, device);
|
|
}
|
|
|
|
static void
|
|
device_removed_cb (NMClient *client, NMDevice *device, CcNetworkPanel *panel)
|
|
{
|
|
g_debug ("Device removed");
|
|
panel_remove_device (panel, device);
|
|
}
|
|
|
|
static void
|
|
manager_running (NMClient *client, GParamSpec *pspec, gpointer user_data)
|
|
{
|
|
const GPtrArray *devices;
|
|
int i;
|
|
NMDevice *device_tmp;
|
|
CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
|
|
|
|
/* TODO: clear all devices we added */
|
|
if (!nm_client_get_manager_running (client)) {
|
|
g_debug ("NM disappeared");
|
|
return;
|
|
}
|
|
|
|
g_debug ("coldplugging devices");
|
|
devices = nm_client_get_devices (client);
|
|
if (devices == NULL) {
|
|
g_debug ("No devices to add");
|
|
return;
|
|
}
|
|
for (i = 0; i < devices->len; i++) {
|
|
device_tmp = g_ptr_array_index (devices, i);
|
|
panel_add_device (panel, device_tmp);
|
|
}
|
|
|
|
/* select the first device */
|
|
select_first_device (panel);
|
|
}
|
|
|
|
static NetObject *
|
|
find_in_model_by_id (CcNetworkPanel *panel, const gchar *id)
|
|
{
|
|
gboolean ret;
|
|
NetObject *object_tmp;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
NetObject *object = NULL;
|
|
|
|
/* find in model */
|
|
model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder,
|
|
"liststore_devices"));
|
|
ret = gtk_tree_model_get_iter_first (model, &iter);
|
|
if (!ret)
|
|
goto out;
|
|
|
|
/* get the other elements */
|
|
ret = FALSE;
|
|
do {
|
|
gtk_tree_model_get (model, &iter,
|
|
PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
|
|
-1);
|
|
if (object_tmp != NULL) {
|
|
g_debug ("got %s", net_object_get_id (object_tmp));
|
|
if (g_strcmp0 (net_object_get_id (object_tmp), id) == 0)
|
|
object = object_tmp;
|
|
g_object_unref (object_tmp);
|
|
}
|
|
} while (object == NULL && gtk_tree_model_iter_next (model, &iter));
|
|
out:
|
|
return object;
|
|
}
|
|
|
|
static void
|
|
panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
|
|
{
|
|
gchar *title;
|
|
gchar *title_markup;
|
|
GtkListStore *liststore_devices;
|
|
GtkTreeIter iter;
|
|
NetVpn *net_vpn;
|
|
const gchar *id;
|
|
|
|
/* does already exist */
|
|
id = nm_connection_get_path (connection);
|
|
if (find_in_model_by_id (panel, id) != NULL)
|
|
return;
|
|
|
|
/* add as a virtual object */
|
|
net_vpn = net_vpn_new ();
|
|
net_vpn_set_connection (net_vpn, connection);
|
|
net_object_set_id (NET_OBJECT (net_vpn), id);
|
|
register_object_interest (panel, NET_OBJECT (net_vpn));
|
|
|
|
liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
|
|
"liststore_devices"));
|
|
title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (connection));
|
|
title_markup = g_strdup_printf ("<span size=\"large\">%s</span>",
|
|
title);
|
|
|
|
net_object_set_title (NET_OBJECT (net_vpn), title);
|
|
gtk_list_store_append (liststore_devices, &iter);
|
|
gtk_list_store_set (liststore_devices,
|
|
&iter,
|
|
PANEL_DEVICES_COLUMN_ICON, "network-vpn",
|
|
PANEL_DEVICES_COLUMN_TITLE, title_markup,
|
|
PANEL_DEVICES_COLUMN_SORT, "5",
|
|
PANEL_DEVICES_COLUMN_OBJECT, net_vpn,
|
|
-1);
|
|
g_free (title);
|
|
g_free (title_markup);
|
|
}
|
|
|
|
static void
|
|
add_connection (CcNetworkPanel *panel,
|
|
NMConnection *connection)
|
|
{
|
|
NMSettingConnection *s_con;
|
|
const gchar *type;
|
|
|
|
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection,
|
|
NM_TYPE_SETTING_CONNECTION));
|
|
type = nm_setting_connection_get_connection_type (s_con);
|
|
if (g_strcmp0 (type, "vpn") != 0)
|
|
return;
|
|
g_debug ("add %s/%s remote connection: %s",
|
|
type, g_type_name_from_instance ((GTypeInstance*)connection),
|
|
nm_connection_get_path (connection));
|
|
panel_add_vpn_device (panel, connection);
|
|
}
|
|
|
|
static void
|
|
notify_new_connection_cb (NMRemoteSettings *settings,
|
|
NMRemoteConnection *connection,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
add_connection (panel, NM_CONNECTION (connection));
|
|
}
|
|
|
|
static void
|
|
notify_connections_read_cb (NMRemoteSettings *settings,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
GSList *list, *iter;
|
|
NMConnection *connection;
|
|
|
|
list = nm_remote_settings_list_connections (settings);
|
|
g_debug ("%p has %i remote connections",
|
|
panel, g_slist_length (list));
|
|
for (iter = list; iter; iter = g_slist_next (iter)) {
|
|
connection = NM_CONNECTION (iter->data);
|
|
add_connection (panel, connection);
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
display_version_warning_idle (CcNetworkPanel *panel)
|
|
{
|
|
GtkWidget *dialog;
|
|
GtkWidget *image;
|
|
GtkWindow *window;
|
|
const char *message;
|
|
|
|
/* TRANSLATORS: the user is running a NM that is not API compatible */
|
|
message = _("The system network services are not compatible with this version.");
|
|
|
|
window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
|
|
dialog = gtk_message_dialog_new (window,
|
|
GTK_DIALOG_MODAL,
|
|
GTK_MESSAGE_ERROR,
|
|
GTK_BUTTONS_CLOSE,
|
|
"%s",
|
|
message);
|
|
image = gtk_image_new_from_icon_name ("computer-fail", GTK_ICON_SIZE_DIALOG);
|
|
gtk_widget_show (image);
|
|
gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
|
|
|
|
gtk_dialog_run (GTK_DIALOG (dialog));
|
|
gtk_widget_destroy (dialog);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
panel_check_network_manager_version (CcNetworkPanel *panel)
|
|
{
|
|
const gchar *version;
|
|
gchar **split = NULL;
|
|
guint major = 0;
|
|
guint micro = 0;
|
|
guint minor = 0;
|
|
gboolean ret = TRUE;
|
|
|
|
/* parse running version */
|
|
version = nm_client_get_version (panel->priv->client);
|
|
if (version != NULL) {
|
|
split = g_strsplit (version, ".", -1);
|
|
major = atoi (split[0]);
|
|
minor = atoi (split[1]);
|
|
micro = atoi (split[2]);
|
|
}
|
|
|
|
/* is it too new or old */
|
|
if (major > 0 || major > 9 || (minor <= 8 && micro < 992)) {
|
|
ret = FALSE;
|
|
|
|
/* do modal dialog in idle so we don't block startup */
|
|
g_idle_add ((GSourceFunc)display_version_warning_idle, panel);
|
|
}
|
|
|
|
g_strfreev (split);
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
edit_connection (GtkButton *button, CcNetworkPanel *panel)
|
|
{
|
|
NMConnection *c;
|
|
const gchar *uuid;
|
|
gchar *cmdline;
|
|
GError *error;
|
|
NetObject *object;
|
|
NMDevice *device;
|
|
|
|
object = get_selected_object (panel);
|
|
if (object == NULL)
|
|
return;
|
|
else if (NET_IS_VPN (object)) {
|
|
c = net_vpn_get_connection (NET_VPN (object));
|
|
}
|
|
else {
|
|
device = net_device_get_nm_device (NET_DEVICE (object));
|
|
c = find_connection_for_device (panel, device);
|
|
}
|
|
|
|
uuid = nm_connection_get_uuid (c);
|
|
|
|
cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid);
|
|
g_debug ("Launching '%s'\n", cmdline);
|
|
|
|
error = NULL;
|
|
if (!g_spawn_command_line_async (cmdline, &error)) {
|
|
g_warning ("Failed to launch nm-connection-editor: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
|
|
g_free (cmdline);
|
|
}
|
|
|
|
static void
|
|
add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel)
|
|
{
|
|
GtkWidget *dialog;
|
|
gint response;
|
|
|
|
dialog = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"connection_type_dialog"));
|
|
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))));
|
|
|
|
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
|
|
gtk_widget_hide (dialog);
|
|
|
|
if (response == GTK_RESPONSE_OK) {
|
|
GtkComboBox *combo;
|
|
GtkTreeModel *model;
|
|
GtkTreeIter iter;
|
|
gchar *type;
|
|
gchar *cmdline;
|
|
GError *error;
|
|
|
|
combo = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder,
|
|
"connection_type_combo"));
|
|
model = gtk_combo_box_get_model (combo);
|
|
gtk_combo_box_get_active_iter (combo, &iter);
|
|
gtk_tree_model_get (model, &iter, 1, &type, -1);
|
|
|
|
cmdline = g_strdup_printf ("nm-connection-editor --create --type %s", type);
|
|
g_debug ("Launching '%s'\n", cmdline);
|
|
|
|
error = NULL;
|
|
if (!g_spawn_command_line_async (cmdline, &error)) {
|
|
g_warning ("Failed to launch nm-connection-editor: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
g_free (cmdline);
|
|
g_free (type);
|
|
}
|
|
}
|
|
|
|
static void
|
|
remove_connection (GtkToolButton *button, CcNetworkPanel *panel)
|
|
{
|
|
NetObject *object;
|
|
NMConnection *connection;
|
|
|
|
/* get current device */
|
|
object = get_selected_object (panel);
|
|
if (object == NULL)
|
|
return;
|
|
|
|
/* VPN */
|
|
if (NET_IS_VPN (object)) {
|
|
connection = net_vpn_get_connection (NET_VPN (object));
|
|
nm_remote_connection_delete (NM_REMOTE_CONNECTION (connection), NULL, panel);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_toplevel_map (GtkWidget *widget,
|
|
CcNetworkPanel *panel)
|
|
{
|
|
gboolean ret;
|
|
|
|
/* is the user compiling against a new version, but running an
|
|
* old daemon version? */
|
|
ret = panel_check_network_manager_version (panel);
|
|
if (ret) {
|
|
manager_running (panel->priv->client, NULL, panel);
|
|
} else {
|
|
/* just select the proxy settings */
|
|
select_first_device (panel);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
wireless_ap_changed_cb (GtkComboBox *combo_box, CcNetworkPanel *panel)
|
|
{
|
|
const GByteArray *ssid;
|
|
const gchar *ssid_tmp;
|
|
gboolean ret;
|
|
gchar *object_path = NULL;
|
|
gchar *ssid_target = NULL;
|
|
GSList *list, *l;
|
|
GSList *filtered;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
NetObject *object;
|
|
NMConnection *connection;
|
|
NMConnection *connection_activate = NULL;
|
|
NMDevice *device;
|
|
NMSettingWireless *setting_wireless;
|
|
|
|
if (panel->priv->updating_device)
|
|
goto out;
|
|
|
|
ret = gtk_combo_box_get_active_iter (combo_box, &iter);
|
|
if (!ret)
|
|
goto out;
|
|
|
|
object = get_selected_object (panel);
|
|
if (object == NULL)
|
|
goto out;
|
|
|
|
device = net_device_get_nm_device (NET_DEVICE (object));
|
|
if (device == NULL)
|
|
goto out;
|
|
|
|
/* get entry */
|
|
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
|
|
gtk_tree_model_get (model, &iter,
|
|
PANEL_WIRELESS_COLUMN_ID, &object_path,
|
|
PANEL_WIRELESS_COLUMN_TITLE, &ssid_target,
|
|
-1);
|
|
g_debug ("try to connect to WIFI network %s [%s]",
|
|
ssid_target, object_path);
|
|
|
|
/* look for an existing connection we can use */
|
|
list = nm_remote_settings_list_connections (panel->priv->remote_settings);
|
|
g_debug ("%i existing remote connections available",
|
|
g_slist_length (list));
|
|
filtered = nm_device_filter_connections (device, list);
|
|
g_debug ("%i suitable remote connections to check",
|
|
g_slist_length (filtered));
|
|
for (l = filtered; l; l = g_slist_next (l)) {
|
|
connection = NM_CONNECTION (l->data);
|
|
setting_wireless = nm_connection_get_setting_wireless (connection);
|
|
if (!NM_IS_SETTING_WIRELESS (setting_wireless))
|
|
continue;
|
|
ssid = nm_setting_wireless_get_ssid (setting_wireless);
|
|
if (ssid == NULL)
|
|
continue;
|
|
ssid_tmp = nm_utils_escape_ssid (ssid->data, ssid->len);
|
|
if (g_strcmp0 (ssid_target, ssid_tmp) == 0) {
|
|
g_debug ("we found an existing connection %s to activate!",
|
|
nm_connection_get_id (connection));
|
|
connection_activate = connection;
|
|
break;
|
|
}
|
|
}
|
|
|
|
g_slist_free (list);
|
|
g_slist_free (filtered);
|
|
|
|
/* activate the connection */
|
|
if (connection_activate != NULL) {
|
|
nm_client_activate_connection (panel->priv->client,
|
|
connection_activate, NULL, NULL,
|
|
NULL, NULL);
|
|
goto out;
|
|
}
|
|
|
|
/* create one, as it's missing */
|
|
g_debug ("no existing connection found for %s, creating",
|
|
ssid_target);
|
|
nm_client_add_and_activate_connection (panel->priv->client,
|
|
NULL,
|
|
device,
|
|
object_path,
|
|
NULL, NULL);
|
|
out:
|
|
g_free (ssid_target);
|
|
g_free (object_path);
|
|
}
|
|
|
|
static void
|
|
cc_network_panel_init (CcNetworkPanel *panel)
|
|
{
|
|
DBusGConnection *bus = NULL;
|
|
gboolean ret;
|
|
GError *error = NULL;
|
|
gint value;
|
|
GSettings *settings_tmp;
|
|
GtkAdjustment *adjustment;
|
|
GtkCellRenderer *renderer;
|
|
GtkComboBox *combobox;
|
|
GtkStyleContext *context;
|
|
GtkTreeSelection *selection;
|
|
GtkTreeSortable *sortable;
|
|
GtkWidget *widget;
|
|
GtkWidget *toplevel;
|
|
|
|
panel->priv = NETWORK_PANEL_PRIVATE (panel);
|
|
|
|
panel->priv->builder = gtk_builder_new ();
|
|
gtk_builder_add_from_file (panel->priv->builder,
|
|
GNOMECC_UI_DIR "/network.ui",
|
|
&error);
|
|
if (error != NULL) {
|
|
g_warning ("Could not load interface file: %s", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
panel->priv->cancellable = g_cancellable_new ();
|
|
|
|
panel->priv->proxy_settings = g_settings_new ("org.gnome.system.proxy");
|
|
g_signal_connect (panel->priv->proxy_settings,
|
|
"changed",
|
|
G_CALLBACK (panel_settings_changed),
|
|
panel);
|
|
|
|
/* actions */
|
|
value = g_settings_get_enum (panel->priv->proxy_settings, "mode");
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"combobox_proxy_mode"));
|
|
panel_set_value_for_combo (panel, GTK_COMBO_BOX (widget), value);
|
|
g_signal_connect (widget, "changed",
|
|
G_CALLBACK (panel_proxy_mode_combo_changed_cb),
|
|
panel);
|
|
|
|
/* bind the proxy values */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"entry_proxy_url"));
|
|
g_settings_bind (panel->priv->proxy_settings, "autoconfig-url",
|
|
widget, "text",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
|
|
/* bind the proxy values */
|
|
settings_tmp = g_settings_new ("org.gnome.system.proxy.http");
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"entry_proxy_http"));
|
|
g_settings_bind (settings_tmp, "host",
|
|
widget, "text",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder,
|
|
"adjustment_proxy_port_http"));
|
|
g_settings_bind (settings_tmp, "port",
|
|
adjustment, "value",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
g_object_unref (settings_tmp);
|
|
|
|
/* bind the proxy values */
|
|
settings_tmp = g_settings_new ("org.gnome.system.proxy.https");
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"entry_proxy_https"));
|
|
g_settings_bind (settings_tmp, "host",
|
|
widget, "text",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder,
|
|
"adjustment_proxy_port_https"));
|
|
g_settings_bind (settings_tmp, "port",
|
|
adjustment, "value",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
g_object_unref (settings_tmp);
|
|
|
|
/* bind the proxy values */
|
|
settings_tmp = g_settings_new ("org.gnome.system.proxy.ftp");
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"entry_proxy_ftp"));
|
|
g_settings_bind (settings_tmp, "host",
|
|
widget, "text",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder,
|
|
"adjustment_proxy_port_ftp"));
|
|
g_settings_bind (settings_tmp, "port",
|
|
adjustment, "value",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
g_object_unref (settings_tmp);
|
|
|
|
/* bind the proxy values */
|
|
settings_tmp = g_settings_new ("org.gnome.system.proxy.socks");
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"entry_proxy_socks"));
|
|
g_settings_bind (settings_tmp, "host",
|
|
widget, "text",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (panel->priv->builder,
|
|
"adjustment_proxy_port_socks"));
|
|
g_settings_bind (settings_tmp, "port",
|
|
adjustment, "value",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
g_object_unref (settings_tmp);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"treeview_devices"));
|
|
panel_add_devices_columns (panel, GTK_TREE_VIEW (widget));
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
|
|
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
|
|
g_signal_connect (selection, "changed",
|
|
G_CALLBACK (nm_devices_treeview_clicked_cb), panel);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"devices_scrolledwindow"));
|
|
context = gtk_widget_get_style_context (widget);
|
|
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"devices_toolbar"));
|
|
context = gtk_widget_get_style_context (widget);
|
|
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
|
|
|
|
/* add the virtual proxy device */
|
|
panel_add_proxy_device (panel);
|
|
|
|
/* setup wireless combobox model */
|
|
combobox = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder,
|
|
"combobox_network_name"));
|
|
g_signal_connect (combobox, "changed",
|
|
G_CALLBACK (wireless_ap_changed_cb),
|
|
panel);
|
|
|
|
renderer = panel_cell_renderer_mode_new ();
|
|
gtk_cell_renderer_set_padding (renderer, 4, 0);
|
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox),
|
|
renderer,
|
|
FALSE);
|
|
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
|
|
"mode", PANEL_WIRELESS_COLUMN_MODE,
|
|
NULL);
|
|
|
|
renderer = panel_cell_renderer_security_new ();
|
|
gtk_cell_renderer_set_padding (renderer, 4, 0);
|
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox),
|
|
renderer,
|
|
FALSE);
|
|
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
|
|
"security", PANEL_WIRELESS_COLUMN_SECURITY,
|
|
NULL);
|
|
|
|
/* sort networks in drop down */
|
|
sortable = GTK_TREE_SORTABLE (gtk_builder_get_object (panel->priv->builder,
|
|
"liststore_wireless_network"));
|
|
gtk_tree_sortable_set_sort_column_id (sortable,
|
|
PANEL_WIRELESS_COLUMN_SORT,
|
|
GTK_SORT_ASCENDING);
|
|
|
|
renderer = panel_cell_renderer_signal_new ();
|
|
gtk_cell_renderer_set_padding (renderer, 4, 0);
|
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox),
|
|
renderer,
|
|
FALSE);
|
|
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,
|
|
"signal", PANEL_WIRELESS_COLUMN_STRENGTH,
|
|
NULL);
|
|
|
|
/* use NetworkManager client */
|
|
panel->priv->client = nm_client_new ();
|
|
g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_MANAGER_RUNNING,
|
|
G_CALLBACK (manager_running), panel);
|
|
g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS,
|
|
G_CALLBACK (active_connections_changed), panel);
|
|
g_signal_connect (panel->priv->client, "device-added",
|
|
G_CALLBACK (device_added_cb), panel);
|
|
g_signal_connect (panel->priv->client, "device-removed",
|
|
G_CALLBACK (device_removed_cb), panel);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"device_off_switch"));
|
|
g_signal_connect (widget, "notify::active",
|
|
G_CALLBACK (device_off_toggled), panel);
|
|
g_signal_connect (panel->priv->client, "notify::wireless-enabled",
|
|
G_CALLBACK (wireless_enabled_toggled), panel);
|
|
g_signal_connect (panel->priv->client, "notify::wimax-enabled",
|
|
G_CALLBACK (wimax_enabled_toggled), panel);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"button_wired_options"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (edit_connection), panel);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"button_wireless_options"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (edit_connection), panel);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"button_vpn_options"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (edit_connection), panel);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"add_toolbutton"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (add_connection_cb), panel);
|
|
|
|
/* disable for now, until we actually show removable connections */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"remove_toolbutton"));
|
|
g_signal_connect (widget, "clicked",
|
|
G_CALLBACK (remove_connection), panel);
|
|
|
|
/* nothing to unlock yet */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"button_unlock"));
|
|
gtk_widget_set_sensitive (widget, FALSE);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"switch_flight_mode"));
|
|
ret = nm_client_wireless_get_enabled (panel->priv->client);
|
|
gtk_switch_set_active (GTK_SWITCH (widget), !ret);
|
|
g_signal_connect (GTK_SWITCH (widget), "notify::active",
|
|
G_CALLBACK (cc_network_panel_notify_enable_active_cb),
|
|
panel);
|
|
|
|
/* add remote settings such as VPN settings as virtual devices */
|
|
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
|
|
if (bus == NULL) {
|
|
g_warning ("Error connecting to system D-Bus: %s",
|
|
error->message);
|
|
g_error_free (error);
|
|
}
|
|
panel->priv->remote_settings = nm_remote_settings_new (bus);
|
|
g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ,
|
|
G_CALLBACK (notify_connections_read_cb), panel);
|
|
g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_NEW_CONNECTION,
|
|
G_CALLBACK (notify_new_connection_cb), panel);
|
|
|
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel));
|
|
g_signal_connect_after (toplevel, "map", G_CALLBACK (on_toplevel_map), panel);
|
|
|
|
/* hide implementation details */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"notebook_types"));
|
|
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
|
|
|
|
/* hide stuff that doesn't work yet */
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"button_unlock"));
|
|
gtk_widget_hide (widget);
|
|
|
|
widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
|
|
"vbox1"));
|
|
gtk_widget_reparent (widget, (GtkWidget *) panel);
|
|
}
|
|
|
|
void
|
|
cc_network_panel_register (GIOModule *module)
|
|
{
|
|
cc_network_panel_register_type (G_TYPE_MODULE (module));
|
|
g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
|
|
CC_TYPE_NETWORK_PANEL,
|
|
"network", 0);
|
|
}
|