2018-12-13 18:02:12 +01:00
|
|
|
/*
|
|
|
|
* Copyright © 2018 Red Hat Inc.
|
|
|
|
*
|
|
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2018-12-15 17:35:44 +01:00
|
|
|
#include <glib/gi18n.h>
|
2018-12-13 18:02:12 +01:00
|
|
|
#include <config.h>
|
|
|
|
#include "cc-wifi-connection-row.h"
|
|
|
|
|
|
|
|
struct _CcWifiConnectionRow
|
|
|
|
{
|
|
|
|
GtkListBoxRow parent_instance;
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
gboolean constructed;
|
|
|
|
|
2018-12-13 18:02:12 +01:00
|
|
|
gboolean checkable;
|
|
|
|
gboolean checked;
|
|
|
|
|
|
|
|
NMDeviceWifi *device;
|
2018-12-15 17:47:25 +01:00
|
|
|
GPtrArray *aps;
|
2018-12-13 18:02:12 +01:00
|
|
|
NMConnection *connection;
|
|
|
|
|
|
|
|
GtkImage *active_icon;
|
|
|
|
GtkStack *button_stack;
|
|
|
|
GtkCheckButton *checkbutton;
|
|
|
|
GtkButton *configure_button;
|
|
|
|
GtkSpinner *connecting_spinner;
|
|
|
|
GtkImage *encrypted_icon;
|
|
|
|
GtkLabel *name_label;
|
|
|
|
GtkImage *strength_icon;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
|
|
|
PROP_CHECKABLE,
|
|
|
|
PROP_CHECKED,
|
|
|
|
PROP_DEVICE,
|
2018-12-15 17:47:25 +01:00
|
|
|
PROP_APS,
|
2018-12-13 18:02:12 +01:00
|
|
|
PROP_CONNECTION,
|
|
|
|
PROP_LAST
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
NM_AP_SEC_UNKNOWN,
|
|
|
|
NM_AP_SEC_NONE,
|
|
|
|
NM_AP_SEC_WEP,
|
|
|
|
NM_AP_SEC_WPA,
|
2019-12-21 19:21:03 +01:00
|
|
|
NM_AP_SEC_WPA2,
|
2020-07-17 03:41:44 +00:00
|
|
|
NM_AP_SEC_SAE,
|
|
|
|
NM_AP_SEC_OWE
|
2018-12-13 18:02:12 +01:00
|
|
|
} NMAccessPointSecurity;
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (CcWifiConnectionRow, cc_wifi_connection_row, GTK_TYPE_LIST_BOX_ROW)
|
|
|
|
|
|
|
|
static GParamSpec *props[PROP_LAST];
|
|
|
|
|
|
|
|
static NMAccessPointSecurity
|
|
|
|
get_access_point_security (NMAccessPoint *ap)
|
|
|
|
{
|
|
|
|
NM80211ApFlags flags;
|
|
|
|
NM80211ApSecurityFlags wpa_flags;
|
|
|
|
NM80211ApSecurityFlags rsn_flags;
|
|
|
|
NMAccessPointSecurity 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;
|
|
|
|
}
|
2019-12-21 19:21:03 +01:00
|
|
|
#if NM_CHECK_VERSION(1,20,6)
|
|
|
|
else if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)
|
|
|
|
{
|
|
|
|
type = NM_AP_SEC_SAE;
|
|
|
|
}
|
2020-07-17 03:41:44 +00:00
|
|
|
#endif
|
|
|
|
#if NM_CHECK_VERSION(1,24,0)
|
|
|
|
else if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_OWE)
|
|
|
|
{
|
|
|
|
type = NM_AP_SEC_OWE;
|
|
|
|
}
|
2019-12-21 19:21:03 +01:00
|
|
|
#endif
|
2018-12-13 18:02:12 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
type = NM_AP_SEC_WPA2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2018-12-15 17:35:44 +01:00
|
|
|
static NMAccessPointSecurity
|
|
|
|
get_connection_security (NMConnection *con)
|
|
|
|
{
|
|
|
|
NMSettingWirelessSecurity *sws;
|
|
|
|
const gchar *key_mgmt;
|
|
|
|
|
|
|
|
sws = nm_connection_get_setting_wireless_security (con);
|
|
|
|
g_debug ("getting security from %p", sws);
|
|
|
|
if (!sws)
|
|
|
|
return NM_AP_SEC_NONE;
|
|
|
|
|
|
|
|
key_mgmt = nm_setting_wireless_security_get_key_mgmt (sws);
|
|
|
|
g_debug ("key management is %s", key_mgmt);
|
|
|
|
|
|
|
|
if (!key_mgmt)
|
|
|
|
return NM_AP_SEC_NONE;
|
|
|
|
else if (g_str_equal (key_mgmt, "none"))
|
|
|
|
return NM_AP_SEC_WEP;
|
|
|
|
else if (g_str_equal (key_mgmt, "ieee8021x"))
|
|
|
|
return NM_AP_SEC_WEP;
|
|
|
|
else if (g_str_equal (key_mgmt, "wpa-eap"))
|
|
|
|
return NM_AP_SEC_WPA2;
|
|
|
|
else if (strncmp (key_mgmt, "wpa-", 4) == 0)
|
|
|
|
return NM_AP_SEC_WPA;
|
2019-12-21 19:21:03 +01:00
|
|
|
else if (g_str_equal (key_mgmt, "sae"))
|
|
|
|
return NM_AP_SEC_SAE;
|
2020-07-17 03:41:44 +00:00
|
|
|
else if (g_str_equal (key_mgmt, "owe"))
|
|
|
|
return NM_AP_SEC_OWE;
|
2018-12-15 17:35:44 +01:00
|
|
|
else
|
|
|
|
return NM_AP_SEC_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2018-12-13 18:02:12 +01:00
|
|
|
static void
|
|
|
|
update_ui (CcWifiConnectionRow *self)
|
|
|
|
{
|
|
|
|
GBytes *ssid;
|
|
|
|
g_autofree gchar *title = NULL;
|
2018-12-15 17:47:25 +01:00
|
|
|
NMActiveConnection *active_connection = NULL;
|
2018-12-13 18:02:12 +01:00
|
|
|
gboolean active;
|
|
|
|
gboolean connecting;
|
2018-12-15 17:35:44 +01:00
|
|
|
NMAccessPointSecurity security = NM_AP_SEC_UNKNOWN;
|
2018-12-15 17:47:25 +01:00
|
|
|
NMAccessPoint *best_ap;
|
2018-12-15 17:35:44 +01:00
|
|
|
guint8 strength = 0;
|
2018-12-15 17:47:25 +01:00
|
|
|
NMActiveConnectionState state;
|
2018-12-13 18:02:12 +01:00
|
|
|
|
|
|
|
g_assert (self->device);
|
2018-12-15 17:47:25 +01:00
|
|
|
g_assert (self->connection || self->aps->len > 0);
|
|
|
|
|
|
|
|
best_ap = cc_wifi_connection_row_best_access_point (self);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
if (self->connection)
|
|
|
|
{
|
|
|
|
active_connection = nm_device_get_active_connection (NM_DEVICE (self->device));
|
|
|
|
if (active_connection &&
|
|
|
|
NM_CONNECTION (nm_active_connection_get_connection (active_connection)) != self->connection)
|
|
|
|
active_connection = NULL;
|
|
|
|
}
|
2018-12-13 18:02:12 +01:00
|
|
|
|
|
|
|
if (self->connection)
|
|
|
|
{
|
2018-12-15 17:35:44 +01:00
|
|
|
NMSettingWireless *sw;
|
|
|
|
const gchar *name = NULL;
|
|
|
|
g_autofree gchar *ssid_str = NULL;
|
|
|
|
gchar *ssid_pos;
|
|
|
|
|
|
|
|
sw = nm_connection_get_setting_wireless (self->connection);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
|
|
|
ssid = nm_setting_wireless_get_ssid (sw);
|
2018-12-15 17:35:44 +01:00
|
|
|
ssid_str = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid));
|
|
|
|
name = nm_connection_get_id (NM_CONNECTION (self->connection));
|
|
|
|
|
|
|
|
ssid_pos = strstr (name, ssid_str);
|
|
|
|
if (ssid_pos == name && strlen (name) == strlen (ssid_str))
|
|
|
|
{
|
2019-03-29 11:11:52 +01:00
|
|
|
title = g_markup_escape_text (name, -1);
|
2018-12-15 17:35:44 +01:00
|
|
|
}
|
|
|
|
else if (ssid_pos)
|
|
|
|
{
|
|
|
|
g_autofree gchar *before = g_strndup (name, ssid_pos - name);
|
|
|
|
g_autofree gchar *after = g_strndup (ssid_pos + strlen (ssid_str), strlen(ssid_pos) - strlen(ssid_str));
|
|
|
|
title = g_markup_printf_escaped ("<i>%s</i>%s<i>%s</i>",
|
|
|
|
before, ssid_str, after);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* TRANSLATORS: This happens when the connection name does not contain the SSID. */
|
|
|
|
title = g_markup_printf_escaped (C_("Wi-Fi Connection", "%s (SSID: %s)"),
|
|
|
|
name, ssid_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_label_set_markup (self->name_label, title);
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-12-15 17:47:25 +01:00
|
|
|
ssid = nm_access_point_get_ssid (best_ap);
|
2018-12-15 17:35:44 +01:00
|
|
|
title = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid));
|
|
|
|
gtk_label_set_text (self->name_label, title);
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
if (active_connection)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2018-12-15 17:47:25 +01:00
|
|
|
state = nm_active_connection_get_state (active_connection);
|
|
|
|
|
|
|
|
active = state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
|
|
|
|
connecting = state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
active = FALSE;
|
|
|
|
connecting = FALSE;
|
|
|
|
}
|
|
|
|
|
2018-12-15 17:35:44 +01:00
|
|
|
if (self->connection)
|
|
|
|
security = get_connection_security (self->connection);
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
if (best_ap != NULL)
|
2018-12-15 17:35:44 +01:00
|
|
|
{
|
|
|
|
security = get_access_point_security (best_ap);
|
|
|
|
strength = nm_access_point_get_strength (best_ap);
|
|
|
|
}
|
2018-12-13 18:02:12 +01:00
|
|
|
|
|
|
|
if (connecting)
|
|
|
|
{
|
|
|
|
gtk_stack_set_visible_child_name (self->button_stack, "connecting");
|
|
|
|
gtk_spinner_start (self->connecting_spinner);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_spinner_stop (self->connecting_spinner);
|
|
|
|
|
|
|
|
if (self->connection)
|
|
|
|
gtk_stack_set_visible_child_name (self->button_stack, "configure");
|
|
|
|
else
|
|
|
|
gtk_stack_set_visible_child_name (self->button_stack, "empty");
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->active_icon), active);
|
|
|
|
|
2020-07-17 03:41:44 +00:00
|
|
|
if (security != NM_AP_SEC_UNKNOWN && security != NM_AP_SEC_NONE && security != NM_AP_SEC_OWE)
|
2019-01-03 16:51:02 +01:00
|
|
|
{
|
|
|
|
gchar *icon_name;
|
|
|
|
|
|
|
|
gtk_widget_set_child_visible (GTK_WIDGET (self->encrypted_icon), TRUE);
|
|
|
|
if (security == NM_AP_SEC_WEP)
|
2019-09-11 03:20:55 +00:00
|
|
|
{
|
|
|
|
icon_name = "channel-insecure-symbolic";
|
|
|
|
gtk_widget_set_tooltip_text (GTK_WIDGET (self->encrypted_icon), _("Insecure network (WEP)"));
|
|
|
|
}
|
|
|
|
else if (security == NM_AP_SEC_WPA)
|
|
|
|
{
|
|
|
|
icon_name = "network-wireless-encrypted-symbolic";
|
|
|
|
gtk_widget_set_tooltip_text (GTK_WIDGET (self->encrypted_icon), _("Secure network (WPA)"));
|
|
|
|
}
|
|
|
|
else if (security == NM_AP_SEC_WPA2)
|
|
|
|
{
|
|
|
|
icon_name = "network-wireless-encrypted-symbolic";
|
|
|
|
gtk_widget_set_tooltip_text (GTK_WIDGET (self->encrypted_icon), _("Secure network (WPA2)"));
|
|
|
|
}
|
2019-12-21 19:21:03 +01:00
|
|
|
else if (security == NM_AP_SEC_SAE)
|
|
|
|
{
|
|
|
|
icon_name = "network-wireless-encrypted-symbolic";
|
|
|
|
gtk_widget_set_tooltip_text (GTK_WIDGET (self->encrypted_icon), _("Secure network (WPA3)"));
|
|
|
|
}
|
2019-01-03 16:51:02 +01:00
|
|
|
else
|
2019-09-11 03:20:55 +00:00
|
|
|
{
|
|
|
|
icon_name = "network-wireless-encrypted-symbolic";
|
|
|
|
gtk_widget_set_tooltip_text (GTK_WIDGET (self->encrypted_icon), _("Secure network"));
|
|
|
|
}
|
2019-01-03 16:51:02 +01:00
|
|
|
|
|
|
|
g_object_set (self->encrypted_icon, "icon-name", icon_name, NULL);
|
|
|
|
}
|
2018-12-13 18:02:12 +01:00
|
|
|
else
|
2019-01-03 16:51:02 +01:00
|
|
|
{
|
|
|
|
gtk_widget_set_child_visible (GTK_WIDGET (self->encrypted_icon), FALSE);
|
|
|
|
}
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
if (best_ap)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
|
|
|
gchar *icon_name;
|
|
|
|
|
|
|
|
if (strength < 20)
|
|
|
|
icon_name = "network-wireless-signal-none-symbolic";
|
|
|
|
else if (strength < 40)
|
|
|
|
icon_name = "network-wireless-signal-weak-symbolic";
|
|
|
|
else if (strength < 50)
|
|
|
|
icon_name = "network-wireless-signal-ok-symbolic";
|
|
|
|
else if (strength < 80)
|
|
|
|
icon_name = "network-wireless-signal-good-symbolic";
|
|
|
|
else
|
|
|
|
icon_name = "network-wireless-signal-excellent-symbolic";
|
|
|
|
|
|
|
|
g_object_set (self->strength_icon, "icon-name", icon_name, NULL);
|
|
|
|
gtk_widget_set_child_visible (GTK_WIDGET (self->strength_icon), TRUE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_set_child_visible (GTK_WIDGET (self->strength_icon), FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cc_wifi_connection_row_constructed (GObject *object)
|
|
|
|
{
|
|
|
|
CcWifiConnectionRow *self = CC_WIFI_CONNECTION_ROW (object);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (cc_wifi_connection_row_parent_class)->constructed (object);
|
|
|
|
|
|
|
|
/* Reparent the label into the checkbox */
|
|
|
|
if (self->checkable)
|
|
|
|
{
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->checkbutton), TRUE);
|
|
|
|
g_object_ref (self->name_label);
|
|
|
|
gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (GTK_WIDGET (self->name_label))),
|
|
|
|
GTK_WIDGET (self->name_label));
|
|
|
|
gtk_container_add (GTK_CONTAINER (self->checkbutton), GTK_WIDGET (self->name_label));
|
|
|
|
gtk_widget_show (GTK_WIDGET (self->name_label));
|
|
|
|
g_object_unref (self->name_label);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->checkbutton), FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
update_ui (CC_WIFI_CONNECTION_ROW (object));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cc_wifi_connection_row_get_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
CcWifiConnectionRow *self = CC_WIFI_CONNECTION_ROW (object);
|
2018-12-15 17:47:25 +01:00
|
|
|
GPtrArray *ptr_array;
|
|
|
|
gint i;
|
2018-12-13 18:02:12 +01:00
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_CHECKABLE:
|
|
|
|
g_value_set_boolean (value, self->checkable);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_CHECKED:
|
|
|
|
g_value_set_boolean (value, self->checked);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_DEVICE:
|
|
|
|
g_value_set_object (value, self->device);
|
|
|
|
break;
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
case PROP_APS:
|
|
|
|
ptr_array = g_ptr_array_new_full (self->aps->len, NULL);
|
|
|
|
for (i = 0; i < self->aps->len; i++)
|
|
|
|
g_ptr_array_add (ptr_array, g_ptr_array_index (self->aps, i));
|
|
|
|
|
|
|
|
g_value_take_boxed (value, ptr_array);
|
2018-12-13 18:02:12 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_CONNECTION:
|
|
|
|
g_value_set_object (value, self->connection);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cc_wifi_connection_row_set_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
CcWifiConnectionRow *self = CC_WIFI_CONNECTION_ROW (object);
|
2018-12-15 17:47:25 +01:00
|
|
|
GPtrArray *ptr_array;
|
|
|
|
gint i;
|
2018-12-13 18:02:12 +01:00
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_CHECKABLE:
|
|
|
|
self->checkable = g_value_get_boolean (value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_CHECKED:
|
|
|
|
self->checked = g_value_get_boolean (value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_DEVICE:
|
|
|
|
self->device = g_value_dup_object (value);
|
|
|
|
break;
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
case PROP_APS:
|
|
|
|
ptr_array = g_value_get_boxed (value);
|
|
|
|
g_ptr_array_set_size (self->aps, 0);
|
|
|
|
|
|
|
|
if (ptr_array)
|
|
|
|
{
|
|
|
|
for (i = 0; i < ptr_array->len; i++)
|
|
|
|
g_ptr_array_add (self->aps, g_object_ref (g_ptr_array_index (ptr_array, i)));
|
|
|
|
}
|
|
|
|
if (self->constructed)
|
|
|
|
update_ui (self);
|
2018-12-13 18:02:12 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_CONNECTION:
|
|
|
|
self->connection = g_value_dup_object (value);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cc_wifi_connection_row_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
CcWifiConnectionRow *self = CC_WIFI_CONNECTION_ROW (object);
|
|
|
|
|
|
|
|
g_clear_object (&self->device);
|
2018-12-15 17:47:25 +01:00
|
|
|
g_clear_pointer (&self->aps, g_ptr_array_unref);
|
2018-12-13 18:02:12 +01:00
|
|
|
g_clear_object (&self->connection);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (cc_wifi_connection_row_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
cc_wifi_connection_row_class_init (CcWifiConnectionRowClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->constructed = cc_wifi_connection_row_constructed;
|
|
|
|
object_class->get_property = cc_wifi_connection_row_get_property;
|
|
|
|
object_class->set_property = cc_wifi_connection_row_set_property;
|
|
|
|
object_class->finalize = cc_wifi_connection_row_finalize;
|
|
|
|
|
|
|
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/network/cc-wifi-connection-row.ui");
|
|
|
|
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, active_icon);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, button_stack);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, checkbutton);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, configure_button);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, connecting_spinner);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, encrypted_icon);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, name_label);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, CcWifiConnectionRow, strength_icon);
|
|
|
|
|
|
|
|
props[PROP_CHECKABLE] = g_param_spec_boolean ("checkable", "checkable",
|
|
|
|
"Whether to show a checkbox to select the row",
|
|
|
|
FALSE,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
props[PROP_CHECKED] = g_param_spec_boolean ("checked", "Checked",
|
|
|
|
"Whether the row is selected by checking it",
|
|
|
|
FALSE,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
props[PROP_DEVICE] = g_param_spec_object ("device", "WiFi Device",
|
|
|
|
"The WiFi Device for this connection/ap",
|
|
|
|
NM_TYPE_DEVICE_WIFI,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
props[PROP_APS] = g_param_spec_boxed ("aps", "Access Points",
|
|
|
|
"The access points for this connection (may be empty if a connection is given)",
|
|
|
|
G_TYPE_PTR_ARRAY,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
|
|
|
props[PROP_CONNECTION] = g_param_spec_object ("connection", "Connection",
|
|
|
|
"The NMConnection (may be NULL if there is an AP)",
|
|
|
|
NM_TYPE_CONNECTION,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
|
|
|
|
|
|
|
g_object_class_install_properties (object_class,
|
|
|
|
PROP_LAST,
|
|
|
|
props);
|
|
|
|
|
|
|
|
g_signal_new ("configure",
|
|
|
|
CC_TYPE_WIFI_CONNECTION_ROW,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0, NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
configure_clicked_cb (CcWifiConnectionRow *self)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_signal_emit_by_name (self, "configure");
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_init (CcWifiConnectionRow *self)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
gtk_widget_init_template (GTK_WIDGET (self));
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2019-11-22 16:21:43 +13:00
|
|
|
g_signal_connect_object (self->configure_button, "clicked", G_CALLBACK (configure_clicked_cb), self, G_CONNECT_SWAPPED);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
self->aps = g_ptr_array_new_with_free_func (g_object_unref);
|
2018-12-15 17:47:25 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
g_object_bind_property (self, "checked",
|
|
|
|
self->checkbutton, "active",
|
2018-12-13 18:02:12 +01:00
|
|
|
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
|
|
|
}
|
|
|
|
|
|
|
|
CcWifiConnectionRow *
|
2018-12-15 17:47:25 +01:00
|
|
|
cc_wifi_connection_row_new (NMDeviceWifi *device,
|
2018-12-13 18:02:12 +01:00
|
|
|
NMConnection *connection,
|
2018-12-15 17:47:25 +01:00
|
|
|
GPtrArray *aps,
|
2018-12-13 18:02:12 +01:00
|
|
|
gboolean checkable)
|
|
|
|
{
|
|
|
|
return g_object_new (CC_TYPE_WIFI_CONNECTION_ROW,
|
|
|
|
"device", device,
|
|
|
|
"connection", connection,
|
2018-12-15 17:47:25 +01:00
|
|
|
"aps", aps,
|
2018-12-13 18:02:12 +01:00
|
|
|
"checkable", checkable,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_get_checkable (CcWifiConnectionRow *self)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), FALSE);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
return self->checkable;
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_get_checked (CcWifiConnectionRow *self)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), FALSE);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
return self->checked;
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
NMDeviceWifi*
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_get_device (CcWifiConnectionRow *self)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), NULL);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
return self->device;
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
const GPtrArray*
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_get_access_points (CcWifiConnectionRow *self)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), NULL);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
return self->aps;
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
NMConnection*
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_get_connection (CcWifiConnectionRow *self)
|
2018-12-13 18:02:12 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), NULL);
|
2018-12-13 18:02:12 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
return self->connection;
|
2018-12-13 18:02:12 +01:00
|
|
|
}
|
|
|
|
|
2018-12-15 17:50:24 +01:00
|
|
|
void
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_set_checked (CcWifiConnectionRow *self,
|
|
|
|
gboolean value)
|
2018-12-15 17:50:24 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_if_fail (CC_WIFI_CONNECTION_ROW (self));
|
2018-12-15 17:50:24 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
self->checked = value;
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CHECKED]);
|
2018-12-15 17:50:24 +01:00
|
|
|
}
|
|
|
|
|
2018-12-15 17:47:25 +01:00
|
|
|
NMAccessPoint*
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_best_access_point (CcWifiConnectionRow *self)
|
2018-12-15 17:47:25 +01:00
|
|
|
{
|
|
|
|
NMAccessPoint *best_ap = NULL;
|
|
|
|
NMAccessPoint *active_ap = NULL;
|
|
|
|
guint8 strength = 0;
|
|
|
|
gint i;
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), NULL);
|
2018-12-15 17:47:25 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->aps->len == 0)
|
2018-12-15 17:47:25 +01:00
|
|
|
return NULL;
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
active_ap = nm_device_wifi_get_active_access_point (self->device);
|
2018-12-15 17:47:25 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
for (i = 0; i < self->aps->len; i++)
|
2018-12-15 17:47:25 +01:00
|
|
|
{
|
|
|
|
NMAccessPoint *cur;
|
|
|
|
guint8 cur_strength;
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
cur = g_ptr_array_index (self->aps, i);
|
2018-12-15 17:47:25 +01:00
|
|
|
|
|
|
|
/* Prefer the active AP in all cases */
|
|
|
|
if (cur == active_ap)
|
|
|
|
return cur;
|
|
|
|
|
|
|
|
cur_strength = nm_access_point_get_strength (cur);
|
|
|
|
/* Use if we don't have an AP, this is the current AP, or it is better */
|
|
|
|
if (!best_ap || cur_strength > strength)
|
|
|
|
{
|
|
|
|
best_ap = cur;
|
|
|
|
strength = cur_strength;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return best_ap;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_add_access_point (CcWifiConnectionRow *self,
|
|
|
|
NMAccessPoint *ap)
|
2018-12-15 17:47:25 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_if_fail (CC_WIFI_CONNECTION_ROW (self));
|
2018-12-15 17:47:25 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
g_ptr_array_add (self->aps, g_object_ref (ap));
|
|
|
|
update_ui (self);
|
2018-12-15 17:47:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_remove_access_point (CcWifiConnectionRow *self,
|
|
|
|
NMAccessPoint *ap)
|
2018-12-15 17:47:25 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), FALSE);
|
2018-12-15 17:47:25 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
if (!g_ptr_array_remove (self->aps, g_object_ref (ap)))
|
2018-12-15 17:47:25 +01:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Object might be invalid; this is alright if it is deleted right away */
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->aps->len > 0 || self->connection)
|
2018-12-15 17:47:25 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_APS]);
|
|
|
|
update_ui (self);
|
2018-12-15 17:47:25 +01:00
|
|
|
}
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
return self->aps->len == 0;
|
2018-12-15 17:47:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_has_access_point (CcWifiConnectionRow *self,
|
|
|
|
NMAccessPoint *ap)
|
2018-12-15 17:47:25 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
g_return_val_if_fail (CC_WIFI_CONNECTION_ROW (self), FALSE);
|
2018-12-15 17:47:25 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
return g_ptr_array_find (self->aps, ap, NULL);
|
2018-12-15 17:47:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-10-18 11:47:17 +13:00
|
|
|
cc_wifi_connection_row_update (CcWifiConnectionRow *self)
|
2018-12-15 17:47:25 +01:00
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
update_ui (self);
|
2018-12-15 17:47:25 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
gtk_list_box_row_changed (GTK_LIST_BOX_ROW (self));
|
2018-12-15 17:47:25 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|