diff --git a/kded/passworddialog.ui b/kded/passworddialog.ui index c2322a75..7008cbb3 100644 --- a/kded/passworddialog.ui +++ b/kded/passworddialog.ui @@ -1,139 +1,139 @@ PasswordDialog 0 0 480 147 0 0 640 16777215 Password dialog 1 IconLabel 8 -1 font-weight: bold TextLabel - + 0 0 16777215 16777215 TextLabel true Password: 64 true Qt::Vertical QSizePolicy::Preferred 20 40 QDialogButtonBox::Cancel|QDialogButtonBox::Ok PasswordField QLineEdit
passwordfield.h
diff --git a/libs/declarative/connectionicon.cpp b/libs/declarative/connectionicon.cpp index 1d1c0a9e..a3f0caee 100644 --- a/libs/declarative/connectionicon.cpp +++ b/libs/declarative/connectionicon.cpp @@ -1,681 +1,681 @@ /* Copyright 2013 Jan Grulich This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "connectionicon.h" #include "uiutils.h" #include #include #include #include #include #include #include #include #include #if WITH_MODEMMANAGER_SUPPORT #include #include #endif ConnectionIcon::ConnectionIcon(QObject* parent) : QObject(parent) , m_signal(0) , m_wirelessNetwork(nullptr) , m_connecting(false) , m_limited(false) , m_vpn(false) , m_airplaneMode(false) #if WITH_MODEMMANAGER_SUPPORT , m_modemNetwork(nullptr) #endif { connect(NetworkManager::notifier(), &NetworkManager::Notifier::primaryConnectionChanged, this, &ConnectionIcon::primaryConnectionChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::activatingConnectionChanged, this, &ConnectionIcon::activatingConnectionChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &ConnectionIcon::activeConnectionAdded); connect(NetworkManager::notifier(), &NetworkManager::Notifier::connectivityChanged, this, &ConnectionIcon::connectivityChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &ConnectionIcon::deviceAdded); connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &ConnectionIcon::deviceRemoved); connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &ConnectionIcon::networkingEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &ConnectionIcon::statusChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &ConnectionIcon::wirelessEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessHardwareEnabledChanged, this, &ConnectionIcon::wirelessEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanEnabledChanged, this, &ConnectionIcon::wwanEnabledChanged); connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanHardwareEnabledChanged, this, &ConnectionIcon::wwanEnabledChanged); Q_FOREACH (NetworkManager::Device::Ptr device, NetworkManager::networkInterfaces()) { if (device->type() == NetworkManager::Device::Ethernet) { NetworkManager::WiredDevice::Ptr wiredDevice = device.staticCast(); if (wiredDevice) { connect(wiredDevice.data(), &NetworkManager::WiredDevice::carrierChanged, this, &ConnectionIcon::carrierChanged); } } else if (device->type() == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.staticCast(); if (wifiDevice) { connect(wifiDevice.data(), &NetworkManager::WirelessDevice::availableConnectionAppeared, this, &ConnectionIcon::wirelessNetworkAppeared); connect(wifiDevice.data(), &NetworkManager::WirelessDevice::networkAppeared, this, &ConnectionIcon::wirelessNetworkAppeared); } } } Q_FOREACH (NetworkManager::ActiveConnection::Ptr activeConnection, NetworkManager::activeConnections()) { addActiveConnection(activeConnection->path()); } setStates(); connectivityChanged(); + setIcons(); } ConnectionIcon::~ConnectionIcon() { } bool ConnectionIcon::connecting() const { return m_connecting; } QString ConnectionIcon::connectionIcon() const { if (m_vpn && !m_connectionIcon.contains("available")) { return m_connectionIcon + "-locked"; } if (m_limited && !m_connectionIcon.contains("available")) { return m_connectionIcon + "-limited"; } return m_connectionIcon; } QString ConnectionIcon::connectionTooltipIcon() const { return m_connectionTooltipIcon; } bool ConnectionIcon::airplaneMode() const { return m_airplaneMode; } void ConnectionIcon::setAirplaneMode(bool airplaneMode) { if (m_airplaneMode != airplaneMode) { m_airplaneMode = airplaneMode; Q_EMIT airplaneModeChanged(airplaneMode); setIcons(); } } void ConnectionIcon::activatingConnectionChanged(const QString& connection) { Q_UNUSED(connection); setIcons(); } void ConnectionIcon::addActiveConnection(const QString &activeConnection) { NetworkManager::ActiveConnection::Ptr active = NetworkManager::findActiveConnection(activeConnection); if (active) { NetworkManager::VpnConnection::Ptr vpnConnection; connect(active.data(), &NetworkManager::ActiveConnection::destroyed, this, &ConnectionIcon::activeConnectionDestroyed); if (active->vpn()) { vpnConnection = active.objectCast(); connect(vpnConnection.data(), &NetworkManager::VpnConnection::stateChanged, this, &ConnectionIcon::vpnConnectionStateChanged); } else { connect(active.data(), &NetworkManager::ActiveConnection::stateChanged, this, &ConnectionIcon::activeConnectionStateChanged, Qt::UniqueConnection); } } } void ConnectionIcon::activeConnectionAdded(const QString &activeConnection) { addActiveConnection(activeConnection); setStates(); } void ConnectionIcon::activeConnectionStateChanged(NetworkManager::ActiveConnection::State state) { Q_UNUSED(state); setStates(); } void ConnectionIcon::activeConnectionDestroyed() { setStates(); } void ConnectionIcon::carrierChanged(bool carrier) { Q_UNUSED(carrier); setIcons(); } void ConnectionIcon::connectivityChanged() { NetworkManager::Connectivity conn = NetworkManager::connectivity(); - m_limited = (conn == NetworkManager::Portal || conn == NetworkManager::Limited); - setIcons(); + setLimited(conn == NetworkManager::Portal || conn == NetworkManager::Limited); } void ConnectionIcon::deviceAdded(const QString& device) { NetworkManager::Device::Ptr dev = NetworkManager::findNetworkInterface(device); if (!dev) { return; } if (dev->type() == NetworkManager::Device::Ethernet) { NetworkManager::WiredDevice::Ptr wiredDev = dev.objectCast(); connect(wiredDev.data(), &NetworkManager::WiredDevice::carrierChanged, this, &ConnectionIcon::carrierChanged); } } void ConnectionIcon::deviceRemoved(const QString& device) { Q_UNUSED(device); if (NetworkManager::status() == NetworkManager::Disconnected) { setDisconnectedIcon(); } } #if WITH_MODEMMANAGER_SUPPORT void ConnectionIcon::modemNetworkRemoved() { m_modemNetwork.clear(); } void ConnectionIcon::modemSignalChanged(const ModemManager::SignalQualityPair &signalQuality) { int diff = m_signal - signalQuality.signal; if (diff >= 10 || diff <= -10) { m_signal = signalQuality.signal; setIconForModem(); } } #endif void ConnectionIcon::networkingEnabledChanged(bool enabled) { if (!enabled) { setConnectionIcon("network-unavailable"); } } void ConnectionIcon::primaryConnectionChanged(const QString& connection) { if (!connection.isEmpty()) { setIcons(); } } void ConnectionIcon::statusChanged(NetworkManager::Status status) { if (status == NetworkManager::Disconnected) { setDisconnectedIcon(); } } void ConnectionIcon::vpnConnectionStateChanged(NetworkManager::VpnConnection::State state, NetworkManager::VpnConnection::StateChangeReason reason) { Q_UNUSED(state); Q_UNUSED(reason); setStates(); setIcons(); } void ConnectionIcon::wirelessEnabledChanged(bool enabled) { Q_UNUSED(enabled); setIcons(); } void ConnectionIcon::wwanEnabledChanged(bool enabled) { Q_UNUSED(enabled); setIcons(); } void ConnectionIcon::wirelessNetworkAppeared(const QString& network) { Q_UNUSED(network); setIcons(); } void ConnectionIcon::setStates() { bool connecting = false; bool vpn = false; Q_FOREACH (NetworkManager::ActiveConnection::Ptr activeConnection, NetworkManager::activeConnections()) { NetworkManager::VpnConnection::Ptr vpnConnection; if (activeConnection->vpn()) { vpnConnection = activeConnection.objectCast(); } if (!vpnConnection) { if (activeConnection->state() == NetworkManager::ActiveConnection::Activating && UiUtils::isConnectionTypeSupported(activeConnection->type())) { connecting = true; } } else { if (vpnConnection->state() == NetworkManager::VpnConnection::Activated) { vpn = true; } else if (vpnConnection->state() == NetworkManager::VpnConnection::Prepare || vpnConnection->state() == NetworkManager::VpnConnection::NeedAuth || vpnConnection->state() == NetworkManager::VpnConnection::Connecting || vpnConnection->state() == NetworkManager::VpnConnection::GettingIpConfig) { connecting = true; } } } setVpn(vpn); setConnecting(connecting); } void ConnectionIcon::setIcons() { m_signal = 0; #if WITH_MODEMMANAGER_SUPPORT if (m_modemNetwork) { disconnect(m_modemNetwork.data(), nullptr, this, nullptr); m_modemNetwork.clear(); } #endif if (m_wirelessNetwork) { disconnect(m_wirelessNetwork.data(), nullptr, this, nullptr); m_wirelessNetwork.clear(); } NetworkManager::ActiveConnection::Ptr connection = NetworkManager::activatingConnection(); if (!connection) { connection = NetworkManager::primaryConnection(); } // Workaround, because PrimaryConnection is kinda broken in NM 0.9.8.x and // doesn't work correctly with some VPN connections. This shouldn't be necessary // for NM 0.9.9.0 or the upcoming bugfix release NM 0.9.8.10 #if !NM_CHECK_VERSION(0, 9, 10) if (!connection) { bool defaultRoute = false; NetworkManager::ActiveConnection::Ptr mainActiveConnection; Q_FOREACH (const NetworkManager::ActiveConnection::Ptr & activeConnection, NetworkManager::activeConnections()) { if ((activeConnection->default4() || activeConnection->default6()) && activeConnection->vpn()) { defaultRoute = true; mainActiveConnection = activeConnection; break; } } if (!defaultRoute) { Q_FOREACH (const NetworkManager::ActiveConnection::Ptr & activeConnection, NetworkManager::activeConnections()) { if (activeConnection->vpn()) { mainActiveConnection = activeConnection; break; } } } if (mainActiveConnection) { NetworkManager::ActiveConnection::Ptr baseActiveConnection; baseActiveConnection = NetworkManager::findActiveConnection(mainActiveConnection->specificObject()); if (baseActiveConnection) { connection = baseActiveConnection; } } } #endif /* Fallback: If we still don't have an active connection with default route or the default route goes through a connection of generic type (some type of VPNs) we need to go through all other active connections and pick the one with hightest probability of being the main one (order is: vpn, wired, wireless, gsm, cdma, bluetooth) */ #if NM_CHECK_VERSION(1, 2, 0) if ((!connection && !NetworkManager::activeConnections().isEmpty()) || (connection && connection->type() == NetworkManager::ConnectionSettings::Generic) || (connection && connection->type() == NetworkManager::ConnectionSettings::Tun)) { #elif NM_CHECK_VERSION(0, 9, 10) if ((!connection && !NetworkManager::activeConnections().isEmpty()) || (connection && connection->type() == NetworkManager::ConnectionSettings::Generic)) { #else if (!connection && !NetworkManager::activeConnections().isEmpty()) { #endif #if NM_CHECK_VERSION(0, 9, 10) Q_FOREACH (const NetworkManager::ActiveConnection::Ptr &activeConnection, NetworkManager::activeConnections()) { const NetworkManager::ConnectionSettings::ConnectionType type = activeConnection->type(); if (type == NetworkManager::ConnectionSettings::Bluetooth) { if (connection && connection->type() <= NetworkManager::ConnectionSettings::Bluetooth) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Cdma) { if (connection && connection->type() <= NetworkManager::ConnectionSettings::Cdma) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Gsm) { if (connection && connection->type() <= NetworkManager::ConnectionSettings::Gsm) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Vpn) { connection = activeConnection; } else if (type == NetworkManager::ConnectionSettings::Wired) { if (connection && connection->type() != NetworkManager::ConnectionSettings::Vpn) { connection = activeConnection; } } else if (type == NetworkManager::ConnectionSettings::Wireless) { if (connection && (connection->type() != NetworkManager::ConnectionSettings::Vpn && (connection->type() != NetworkManager::ConnectionSettings::Wired))) { connection = activeConnection; } } } #else connection = NetworkManager::activeConnections().first(); #endif } if (connection && !connection->devices().isEmpty()) { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(connection->devices().first()); if (device) { NetworkManager::Device::Type type = device->type(); if (type == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast(); if (wifiDevice->mode() == NetworkManager::WirelessDevice::Adhoc) { setWirelessIconForSignalStrength(100); } else { NetworkManager::AccessPoint::Ptr ap = wifiDevice->activeAccessPoint(); if (ap) { setWirelessIcon(device, ap->ssid()); } } } else if (type == NetworkManager::Device::Ethernet) { setConnectionIcon("network-wired-activated"); setConnectionTooltipIcon("network-wired-activated"); } else if (type == NetworkManager::Device::Modem) { #if WITH_MODEMMANAGER_SUPPORT setModemIcon(device); #else setConnectionIcon("network-mobile-0"); setConnectionTooltipIcon("phone"); #endif } else if (type == NetworkManager::Device::Bluetooth) { NetworkManager::BluetoothDevice::Ptr btDevice = device.objectCast(); if (btDevice) { if (btDevice->bluetoothCapabilities().testFlag(NetworkManager::BluetoothDevice::Dun)) { #if WITH_MODEMMANAGER_SUPPORT setModemIcon(device); #else setConnectionIcon("network-mobile-0"); setConnectionTooltipIcon("phone"); #endif } else { setConnectionIcon("network-bluetooth-activated"); setConnectionTooltipIcon("preferences-system-bluetooth"); } } } else { // Ignore other devices (bond/bridge/team etc.) setDisconnectedIcon(); } } } else { setDisconnectedIcon(); } } void ConnectionIcon::setDisconnectedIcon() { if (m_airplaneMode) { setConnectionIcon(QStringLiteral("network-flightmode-on")); return; } if (NetworkManager::status() == NetworkManager::Unknown || NetworkManager::status() == NetworkManager::Asleep) { setConnectionIcon("network-unavailable"); return; } bool wired = false; bool wireless = false; bool modem = false; m_limited = false; m_vpn = false; Q_FOREACH (const NetworkManager::Device::Ptr &device, NetworkManager::networkInterfaces()) { if (device->type() == NetworkManager::Device::Ethernet) { NetworkManager::WiredDevice::Ptr wiredDev = device.objectCast(); if (wiredDev->carrier()) { wired = true; } } else if (device->type() == NetworkManager::Device::Wifi && NetworkManager::isWirelessEnabled() && NetworkManager::isWirelessHardwareEnabled()) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast(); if (!wifiDevice->accessPoints().isEmpty() || !wifiDevice->availableConnections().isEmpty()) { wireless = true; } } else if (device->type() == NetworkManager::Device::Modem && NetworkManager::isWwanEnabled() && NetworkManager::isWwanHardwareEnabled()) { modem = true; } } if (wired) { setConnectionIcon("network-wired-available"); setConnectionTooltipIcon("network-wired"); return; } else if (wireless) { setConnectionIcon("network-wireless-available"); setConnectionTooltipIcon("network-wireless-connected-00"); return; } else if (modem) { setConnectionIcon("network-mobile-available"); setConnectionTooltipIcon("phone"); return; } else { setConnectionIcon("network-unavailable"); setConnectionTooltipIcon("network-wired"); } } #if WITH_MODEMMANAGER_SUPPORT void ConnectionIcon::setModemIcon(const NetworkManager::Device::Ptr & device) { NetworkManager::ModemDevice::Ptr modemDevice = device.objectCast(); if (!modemDevice) { setConnectionIcon("network-mobile-100"); return; } ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(device->udi()); if (modem) { if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { m_modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); } } if (m_modemNetwork) { connect(m_modemNetwork.data(), &ModemManager::Modem::signalQualityChanged, this, &ConnectionIcon::modemSignalChanged, Qt::UniqueConnection); connect(m_modemNetwork.data(), &ModemManager::Modem::accessTechnologiesChanged, this, &ConnectionIcon::setIconForModem, Qt::UniqueConnection); connect(m_modemNetwork.data(), &ModemManager::Modem::destroyed, this, &ConnectionIcon::modemNetworkRemoved); m_signal = m_modemNetwork->signalQuality().signal; setIconForModem(); } else { setConnectionIcon("network-mobile-0"); setConnectionTooltipIcon("phone"); return; } } void ConnectionIcon::setIconForModem() { if (!m_signal) { m_signal = m_modemNetwork->signalQuality().signal; } QString strength = "00"; if (m_signal == 0) { strength = '0'; } else if (m_signal < 20) { strength = "20"; } else if (m_signal < 40) { strength = "40"; } else if (m_signal < 60) { strength = "60"; } else if (m_signal < 80) { strength = "80"; } else { strength = "100"; } QString result; switch(m_modemNetwork->accessTechnologies()) { case MM_MODEM_ACCESS_TECHNOLOGY_GSM: case MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT: result = "network-mobile-%1"; break; case MM_MODEM_ACCESS_TECHNOLOGY_GPRS: result = "network-mobile-%1-gprs"; break; case MM_MODEM_ACCESS_TECHNOLOGY_EDGE: result = "network-mobile-%1-edge"; break; case MM_MODEM_ACCESS_TECHNOLOGY_UMTS: result = "network-mobile-%1-umts"; break; case MM_MODEM_ACCESS_TECHNOLOGY_HSDPA: result = "network-mobile-%1-hsdpa"; break; case MM_MODEM_ACCESS_TECHNOLOGY_HSUPA: result = "network-mobile-%1-hsupa"; break; case MM_MODEM_ACCESS_TECHNOLOGY_HSPA: case MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS: result = "network-mobile-%1-hspa"; break; case MM_MODEM_ACCESS_TECHNOLOGY_LTE: result = "network-mobile-%1-lte"; break; default: result = "network-mobile-%1"; break; } setConnectionIcon(QString(result).arg(strength)); setConnectionTooltipIcon("phone"); } #endif void ConnectionIcon::setWirelessIcon(const NetworkManager::Device::Ptr &device, const QString& ssid) { NetworkManager::WirelessDevice::Ptr wirelessDevice = device.objectCast(); if (device) { m_wirelessNetwork = wirelessDevice->findNetwork(ssid); } else { m_wirelessNetwork.clear(); } if (m_wirelessNetwork) { connect(m_wirelessNetwork.data(), &NetworkManager::WirelessNetwork::signalStrengthChanged, this, &ConnectionIcon::setWirelessIconForSignalStrength, Qt::UniqueConnection); setWirelessIconForSignalStrength(m_wirelessNetwork->signalStrength()); } else { setDisconnectedIcon(); } } void ConnectionIcon::setWirelessIconForSignalStrength(int strength) { int iconStrength = 100; if (strength == 0) { iconStrength = 0; setConnectionTooltipIcon("network-wireless-connected-00"); } else if (strength < 20) { iconStrength = 20; setConnectionTooltipIcon("network-wireless-connected-20"); } else if (strength < 40) { iconStrength = 40; setConnectionTooltipIcon("network-wireless-connected-40"); } else if (strength < 60) { iconStrength = 60; setConnectionTooltipIcon("network-wireless-connected-60"); } else if (strength < 80) { iconStrength = 80; setConnectionTooltipIcon("network-wireless-connected-80"); } else if (strength < 100) { setConnectionTooltipIcon("network-wireless-connected-100"); } QString icon = QString("network-wireless-%1").arg(iconStrength); setConnectionIcon(icon); } void ConnectionIcon::setConnecting(bool connecting) { if (connecting != m_connecting) { m_connecting = connecting; Q_EMIT connectingChanged(m_connecting); } } void ConnectionIcon::setConnectionIcon(const QString & icon) { if (icon != m_connectionIcon) { m_connectionIcon = icon; Q_EMIT connectionIconChanged(connectionIcon()); } } void ConnectionIcon::setConnectionTooltipIcon(const QString & icon) { if (icon != m_connectionTooltipIcon) { m_connectionTooltipIcon = icon; Q_EMIT connectionTooltipIconChanged(m_connectionTooltipIcon); } } void ConnectionIcon::setVpn(bool vpn) { if (m_vpn != vpn) { m_vpn = vpn; Q_EMIT connectionIconChanged(connectionIcon()); } } void ConnectionIcon::setLimited(bool limited) { if (m_limited != limited) { m_limited = limited; Q_EMIT connectionIconChanged(connectionIcon()); } } diff --git a/libs/models/networkmodel.cpp b/libs/models/networkmodel.cpp index cce77fa7..e4b0f73e 100644 --- a/libs/models/networkmodel.cpp +++ b/libs/models/networkmodel.cpp @@ -1,1038 +1,1043 @@ /* Copyright 2013-2018 Jan Grulich This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "networkmodel.h" #include "networkmodelitem.h" #include "debug.h" #include "uiutils.h" #if WITH_MODEMMANAGER_SUPPORT #include #include #endif #include #include NetworkModel::NetworkModel(QObject *parent) : QAbstractListModel(parent) { QLoggingCategory::setFilterRules(QStringLiteral("plasma-nm.debug = false")); initialize(); } NetworkModel::~NetworkModel() { } QVariant NetworkModel::data(const QModelIndex &index, int role) const { const int row = index.row(); if (row >= 0 && row < m_list.count()) { NetworkModelItem *item = m_list.itemAt(row); switch (role) { case ConnectionDetailsRole: return item->details(); case ConnectionIconRole: return item->icon(); case ConnectionPathRole: return item->connectionPath(); case ConnectionStateRole: return item->connectionState(); case DeviceName: return item->deviceName(); case DevicePathRole: return item->devicePath(); case DeviceStateRole: return item->deviceState(); case DuplicateRole: return item->duplicate(); case ItemUniqueNameRole: if (m_list.returnItems(NetworkItemsList::Name, item->name()).count() > 1) { return item->originalName(); } else { return item->name(); } case ItemTypeRole: return item->itemType(); case LastUsedRole: return UiUtils::formatLastUsedDateRelative(item->timestamp()); case LastUsedDateOnlyRole: return UiUtils::formatDateRelative(item->timestamp()); case NameRole: return item->name(); case SectionRole: return item->sectionType(); case SignalRole: return item->signal(); case SlaveRole: return item->slave(); case SsidRole: return item->ssid(); case SpecificPathRole: return item->specificPath(); case SecurityTypeRole: return item->securityType(); case SecurityTypeStringRole: return UiUtils::labelFromWirelessSecurity(item->securityType()); case TimeStampRole: return item->timestamp(); case TypeRole: return item->type(); case UniRole: return item->uni(); case UuidRole: return item->uuid(); case VpnState: return item->vpnState(); case VpnType: return item->vpnType(); case RxBytesRole: return item->rxBytes(); case TxBytesRole: return item->txBytes(); default: break; } } return QVariant(); } int NetworkModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return parent.isValid() ? 0 : m_list.count(); } QHash NetworkModel::roleNames() const { QHash roles = QAbstractListModel::roleNames(); roles[ConnectionDetailsRole] = "ConnectionDetails"; roles[ConnectionIconRole] = "ConnectionIcon"; roles[ConnectionPathRole] = "ConnectionPath"; roles[ConnectionStateRole] = "ConnectionState"; roles[DeviceName] = "DeviceName"; roles[DevicePathRole] = "DevicePath"; roles[DeviceStateRole] = "DeviceState"; roles[DuplicateRole] = "Duplicate"; roles[ItemUniqueNameRole] = "ItemUniqueName"; roles[ItemTypeRole] = "ItemType"; roles[LastUsedRole] = "LastUsed"; roles[LastUsedDateOnlyRole] = "LastUsedDateOnly"; roles[NameRole] = "Name"; roles[SectionRole] = "Section"; roles[SignalRole] = "Signal"; roles[SlaveRole] = "Slave"; roles[SsidRole] = "Ssid"; roles[SpecificPathRole] = "SpecificPath"; roles[SecurityTypeRole] = "SecurityType"; roles[SecurityTypeStringRole] = "SecurityTypeString"; roles[TimeStampRole] = "TimeStamp"; roles[TypeRole] = "Type"; roles[UniRole] = "Uni"; roles[UuidRole] = "Uuid"; roles[VpnState] = "VpnState"; roles[VpnType] = "VpnType"; roles[RxBytesRole] = "RxBytes"; roles[TxBytesRole] = "TxBytes"; return roles; } void NetworkModel::initialize() { // Initialize existing connections for (const NetworkManager::Connection::Ptr &connection : NetworkManager::listConnections()) { addConnection(connection); } // Initialize existing devices for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { addDevice(dev); } // Initialize existing active connections for (const NetworkManager::ActiveConnection::Ptr &active : NetworkManager::activeConnections()) { addActiveConnection(active); } initializeSignals(); } void NetworkModel::initializeSignals() { connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &NetworkModel::activeConnectionAdded, Qt::UniqueConnection); connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionRemoved, this, &NetworkModel::activeConnectionRemoved, Qt::UniqueConnection); connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionAdded, this, &NetworkModel::connectionAdded, Qt::UniqueConnection); connect(NetworkManager::settingsNotifier(), &NetworkManager::SettingsNotifier::connectionRemoved, this, &NetworkModel::connectionRemoved, Qt::UniqueConnection); connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &NetworkModel::deviceAdded, Qt::UniqueConnection); connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &NetworkModel::deviceRemoved, Qt::UniqueConnection); connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &NetworkModel::statusChanged, Qt::UniqueConnection); } void NetworkModel::initializeSignals(const NetworkManager::ActiveConnection::Ptr &activeConnection) { if (activeConnection->vpn()) { NetworkManager::VpnConnection::Ptr vpnConnection = activeConnection.objectCast(); if (vpnConnection) { connect(vpnConnection.data(), &NetworkManager::VpnConnection::stateChanged, this, &NetworkModel::activeVpnConnectionStateChanged, Qt::UniqueConnection); } } else { connect(activeConnection.data(), &NetworkManager::ActiveConnection::stateChanged, this, &NetworkModel::activeConnectionStateChanged, Qt::UniqueConnection); } } void NetworkModel::initializeSignals(const NetworkManager::Connection::Ptr &connection) { connect(connection.data(), &NetworkManager::Connection::updated, this, &NetworkModel::connectionUpdated, Qt::UniqueConnection); } void NetworkModel::initializeSignals(const NetworkManager::Device::Ptr &device) { connect(device.data(), &NetworkManager::Device::availableConnectionAppeared, this, &NetworkModel::availableConnectionAppeared, Qt::UniqueConnection); connect(device.data(), &NetworkManager::Device::availableConnectionDisappeared, this, &NetworkModel::availableConnectionDisappeared, Qt::UniqueConnection); connect(device.data(), &NetworkManager::Device::ipV4ConfigChanged, this, &NetworkModel::ipConfigChanged, Qt::UniqueConnection); connect(device.data(), &NetworkManager::Device::ipV6ConfigChanged, this, &NetworkModel::ipConfigChanged, Qt::UniqueConnection); connect(device.data(), &NetworkManager::Device::ipInterfaceChanged, this, &NetworkModel::ipInterfaceChanged); connect(device.data(), &NetworkManager::Device::stateChanged, this, &NetworkModel::deviceStateChanged, Qt::UniqueConnection); auto deviceStatistics = device->deviceStatistics(); connect(deviceStatistics.data(), &NetworkManager::DeviceStatistics::rxBytesChanged, this, [this, device](qulonglong rxBytes) { for (auto *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { item->setRxBytes(rxBytes); updateItem(item); } }); connect(deviceStatistics.data(), &NetworkManager::DeviceStatistics::txBytesChanged, this, [this, device](qulonglong txBytes) { for (auto *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { item->setTxBytes(txBytes); updateItem(item); } }); if (device->type() == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDev = device.objectCast(); connect(wifiDev.data(), &NetworkManager::WirelessDevice::networkAppeared, this, &NetworkModel::wirelessNetworkAppeared, Qt::UniqueConnection); connect(wifiDev.data(), &NetworkManager::WirelessDevice::networkDisappeared, this, &NetworkModel::wirelessNetworkDisappeared, Qt::UniqueConnection); } #if WITH_MODEMMANAGER_SUPPORT else if (device->type() == NetworkManager::Device::Modem) { ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(device->udi()); if (modem) { if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); if (modemNetwork) { connect(modemNetwork.data(), &ModemManager::Modem::signalQualityChanged, this, &NetworkModel::gsmNetworkSignalQualityChanged, Qt::UniqueConnection); connect(modemNetwork.data(), &ModemManager::Modem::accessTechnologiesChanged, this, &NetworkModel::gsmNetworkAccessTechnologiesChanged, Qt::UniqueConnection); connect(modemNetwork.data(), &ModemManager::Modem::currentModesChanged, this, &NetworkModel::gsmNetworkCurrentModesChanged, Qt::UniqueConnection); } } } } #endif } void NetworkModel::initializeSignals(const NetworkManager::WirelessNetwork::Ptr &network) { connect(network.data(), &NetworkManager::WirelessNetwork::signalStrengthChanged, this, &NetworkModel::wirelessNetworkSignalChanged, Qt::UniqueConnection); connect(network.data(), &NetworkManager::WirelessNetwork::referenceAccessPointChanged, this, &NetworkModel::wirelessNetworkReferenceApChanged, Qt::UniqueConnection); } void NetworkModel::addActiveConnection(const NetworkManager::ActiveConnection::Ptr &activeConnection) { initializeSignals(activeConnection); NetworkManager::Device::Ptr device; NetworkManager::Connection::Ptr connection = activeConnection->connection(); // Not necessary to have device for VPN connections if (activeConnection && !activeConnection->vpn() && !activeConnection->devices().isEmpty()) { device = NetworkManager::findNetworkInterface(activeConnection->devices().first()); } // Check whether we have a base connection if (!m_list.contains(NetworkItemsList::Uuid, connection->uuid())) { // Active connection appeared before a base connection, so we have to add its base connection first addConnection(connection); } beginResetModel(); for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::NetworkItemsList::Uuid, connection->uuid())) { if (((device && device->uni() == item->devicePath()) || item->devicePath().isEmpty()) || item->type() == NetworkManager::ConnectionSettings::Vpn) { item->setActiveConnectionPath(activeConnection->path()); item->setConnectionState(activeConnection->state()); if (activeConnection->vpn()) { NetworkManager::VpnConnection::Ptr vpnConnection = activeConnection.objectCast(); NetworkManager::VpnConnection::State state = vpnConnection->state(); if (state == NetworkManager::VpnConnection::Prepare || state == NetworkManager::VpnConnection::NeedAuth || state == NetworkManager::VpnConnection::Connecting || state == NetworkManager::VpnConnection::GettingIpConfig) { item->setConnectionState(NetworkManager::ActiveConnection::Activating); } else if (state == NetworkManager::VpnConnection::Activated) { item->setConnectionState(NetworkManager::ActiveConnection::Activated); } else { item->setConnectionState(NetworkManager::ActiveConnection::Deactivated); } item->setVpnState(state); } item->invalidateDetails(); qCDebug(PLASMA_NM) << "Item " << item->name() << ": active connection state changed to " << item->connectionState(); } } endResetModel(); } void NetworkModel::addAvailableConnection(const QString &connection, const NetworkManager::Device::Ptr &device) { - checkAndCreateDuplicate(connection, device); + if (!device) { + return; + } + + checkAndCreateDuplicate(connection, device->uni()); for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { // The item is already associated with another device - if (!item->devicePath().isEmpty()) { + if (!device || !item->devicePath().isEmpty()) { continue; } if (device->ipInterfaceName().isEmpty()) { item->setDeviceName(device->interfaceName()); } else { item->setDeviceName(device->ipInterfaceName()); } + item->setDevicePath(device->uni()); item->setDeviceState(device->state()); qCDebug(PLASMA_NM) << "Item " << item->name() << ": device changed to " << item->devicePath(); #if WITH_MODEMMANAGER_SUPPORT if (device->type() == NetworkManager::Device::Modem) { ModemManager::ModemDevice::Ptr modemDevice = ModemManager::findModemDevice(device->udi()); if (modemDevice) { ModemManager::Modem::Ptr modemInterface = modemDevice->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); if (modemInterface) { item->setSignal(modemInterface->signalQuality().signal); qCDebug(PLASMA_NM) << "Item " << item->name() << ": signal changed to " << item->signal(); } } } #endif if (item->type() == NetworkManager::ConnectionSettings::Wireless && item->mode() == NetworkManager::WirelessSetting::Infrastructure) { // Find an accesspoint which could be removed, because it will be merged with a connection for (NetworkModelItem *secondItem : m_list.returnItems(NetworkItemsList::Ssid, item->ssid())) { if (secondItem->itemType() == NetworkModelItem::AvailableAccessPoint && secondItem->devicePath() == item->devicePath()) { const int row = m_list.indexOf(secondItem); qCDebug(PLASMA_NM) << "Access point " << secondItem->name() << ": merged to " << item->name() << " connection"; if (row >= 0) { beginRemoveRows(QModelIndex(), row, row); m_list.removeItem(secondItem); secondItem->deleteLater(); endRemoveRows(); } break; } } NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast(); if (wifiDevice) { NetworkManager::WirelessNetwork::Ptr wifiNetwork = wifiDevice->findNetwork(item->ssid()); if (wifiNetwork) { updateFromWirelessNetwork(item, wifiNetwork, wifiDevice); } } } updateItem(item); break; } } void NetworkModel::addConnection(const NetworkManager::Connection::Ptr &connection) { // Can't add a connection without name or uuid if (connection->name().isEmpty() || connection->uuid().isEmpty()) { return; } initializeSignals(connection); NetworkManager::ConnectionSettings::Ptr settings = connection->settings(); NetworkManager::VpnSetting::Ptr vpnSetting; NetworkManager::WirelessSetting::Ptr wirelessSetting; if (settings->connectionType() == NetworkManager::ConnectionSettings::Vpn) { vpnSetting = settings->setting(NetworkManager::Setting::Vpn).dynamicCast(); } else if (settings->connectionType() == NetworkManager::ConnectionSettings::Wireless) { wirelessSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); } // Check whether the connection is already in the model to avoid duplicates, but this shouldn't happen if (!m_list.contains(NetworkItemsList::Connection, connection->path())) { NetworkModelItem *item = new NetworkModelItem(); item->setConnectionPath(connection->path()); item->setName(settings->id()); item->setTimestamp(settings->timestamp()); item->setType(settings->connectionType()); item->setUuid(settings->uuid()); item->setSlave(settings->isSlave()); if (item->type() == NetworkManager::ConnectionSettings::Vpn) { item->setVpnType(vpnSetting->serviceType().section('.', -1)); } else if (item->type() == NetworkManager::ConnectionSettings::Wireless) { item->setMode(wirelessSetting->mode()); item->setSecurityType(NetworkManager::securityTypeFromConnectionSetting(settings)); item->setSsid(QString::fromUtf8(wirelessSetting->ssid())); } item->invalidateDetails(); const int index = m_list.count(); beginInsertRows(QModelIndex(), index, index); m_list.insertItem(item); endInsertRows(); qCDebug(PLASMA_NM) << "New connection " << item->name() << " added"; } } void NetworkModel::addDevice(const NetworkManager::Device::Ptr &device) { initializeSignals(device); if (device->type() == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDev = device.objectCast(); for (const NetworkManager::WirelessNetwork::Ptr &wifiNetwork : wifiDev->networks()) { addWirelessNetwork(wifiNetwork, wifiDev); } } for (const NetworkManager::Connection::Ptr &connection : device->availableConnections()) { addAvailableConnection(connection->path(), device); } } void NetworkModel::addWirelessNetwork(const NetworkManager::WirelessNetwork::Ptr &network, const NetworkManager::WirelessDevice::Ptr &device) { initializeSignals(network); // BUG: 386342 // When creating a new hidden wireless network and attempting to connect to it, NM then later reports that AccessPoint appeared, but // it doesn't know its SSID from some reason, this also makes Wireless device to advertise a new available connection, which we later // attempt to merge with an AP, based on its SSID, but it doesn't find any, because we have AP with empty SSID. After this we get another // AccessPoint appeared signal, this time we know SSID, but we don't attempt any merging, because it's usually the other way around, thus // we need to attempt to merge it here with a connection we guess it's related to this new AP for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Type, NetworkManager::ConnectionSettings::Wireless)) { if (item->itemType() == NetworkModelItem::AvailableConnection) { NetworkManager::ConnectionSettings::Ptr connectionSettings = NetworkManager::findConnection(item->connectionPath())->settings(); if (connectionSettings && connectionSettings->connectionType() == NetworkManager::ConnectionSettings::Wireless) { NetworkManager::WirelessSetting::Ptr wirelessSetting = connectionSettings->setting(NetworkManager::Setting::Wireless).dynamicCast(); if (QString::fromUtf8(wirelessSetting->ssid()) == network->ssid()) { const QString bssid = NetworkManager::macAddressAsString(wirelessSetting->bssid()); const QString restrictedHw = NetworkManager::macAddressAsString(wirelessSetting->macAddress()); if ((bssid.isEmpty() || bssid == network->referenceAccessPoint()->hardwareAddress()) && (restrictedHw.isEmpty() || restrictedHw == device->hardwareAddress())) { updateFromWirelessNetwork(item, network, device); return; } } } } } NetworkManager::WirelessSetting::NetworkMode mode = NetworkManager::WirelessSetting::Infrastructure; NetworkManager::WirelessSecurityType securityType = NetworkManager::UnknownSecurity; NetworkManager::AccessPoint::Ptr ap = network->referenceAccessPoint(); if (ap && ap->capabilities().testFlag(NetworkManager::AccessPoint::Privacy)) { securityType = NetworkManager::findBestWirelessSecurity(device->wirelessCapabilities(), true, (device->mode() == NetworkManager::WirelessDevice::Adhoc), ap->capabilities(), ap->wpaFlags(), ap->rsnFlags()); if (network->referenceAccessPoint()->mode() == NetworkManager::AccessPoint::Infra) { mode = NetworkManager::WirelessSetting::Infrastructure; } else if (network->referenceAccessPoint()->mode() == NetworkManager::AccessPoint::Adhoc) { mode = NetworkManager::WirelessSetting::Adhoc; } else if (network->referenceAccessPoint()->mode() == NetworkManager::AccessPoint::ApMode) { mode = NetworkManager::WirelessSetting::Ap; } } NetworkModelItem *item = new NetworkModelItem(); if (device->ipInterfaceName().isEmpty()) { item->setDeviceName(device->interfaceName()); } else { item->setDeviceName(device->ipInterfaceName()); } item->setDevicePath(device->uni()); item->setMode(mode); item->setName(network->ssid()); item->setSignal(network->signalStrength()); item->setSpecificPath(network->referenceAccessPoint()->uni()); item->setSsid(network->ssid()); item->setType(NetworkManager::ConnectionSettings::Wireless); item->setSecurityType(securityType); item->invalidateDetails(); const int index = m_list.count(); beginInsertRows(QModelIndex(), index, index); m_list.insertItem(item); endInsertRows(); qCDebug(PLASMA_NM) << "New wireless network " << item->name() << " added"; } -void NetworkModel::checkAndCreateDuplicate(const QString &connection, const NetworkManager::Device::Ptr &device) +void NetworkModel::checkAndCreateDuplicate(const QString &connection, const QString &deviceUni) { bool createDuplicate = false; NetworkModelItem *originalItem = nullptr; for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { if (!item->duplicate()) { originalItem = item; } - if (!item->duplicate() && item->itemType() == NetworkModelItem::AvailableConnection && (item->devicePath() != device->uni() && !item->devicePath().isEmpty())) { + if (!item->duplicate() && item->itemType() == NetworkModelItem::AvailableConnection && (item->devicePath() != deviceUni && !item->devicePath().isEmpty())) { createDuplicate = true; } } if (createDuplicate) { NetworkModelItem *duplicatedItem = new NetworkModelItem(originalItem); duplicatedItem->invalidateDetails(); const int index = m_list.count(); beginInsertRows(QModelIndex(), index, index); m_list.insertItem(duplicatedItem); endInsertRows(); } } void NetworkModel::onItemUpdated() { NetworkModelItem *item = static_cast(sender()); if (item) { updateItem(item); } } void NetworkModel::setDeviceStatisticsRefreshRateMs(const QString &devicePath, uint refreshRate) { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(devicePath); if (device) { device->deviceStatistics()->setRefreshRateMs(refreshRate); } } void NetworkModel::updateItem(NetworkModelItem*item) { const int row = m_list.indexOf(item); if (row >= 0) { item->invalidateDetails(); QModelIndex index = createIndex(row, 0); Q_EMIT dataChanged(index, index); } } void NetworkModel::accessPointSignalStrengthChanged(int signal) { NetworkManager::AccessPoint *apPtr = qobject_cast(sender()); if (apPtr) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, apPtr->ssid())) { if (item->specificPath() == apPtr->uni()) { item->setSignal(signal); updateItem(item); qCDebug(PLASMA_NM) << "AccessPoint " << item->name() << ": signal changed to " << item->signal(); } } } } void NetworkModel::activeConnectionAdded(const QString &activeConnection) { NetworkManager::ActiveConnection::Ptr activeCon = NetworkManager::findActiveConnection(activeConnection); if (activeCon) { addActiveConnection(activeCon); } } void NetworkModel::activeConnectionRemoved(const QString &activeConnection) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::ActiveConnection, activeConnection)) { item->setActiveConnectionPath(QString()); item->setConnectionState(NetworkManager::ActiveConnection::Deactivated); item->setVpnState(NetworkManager::VpnConnection::Disconnected); updateItem(item); qCDebug(PLASMA_NM) << "Item " << item->name() << ": active connection removed"; } } void NetworkModel::activeConnectionStateChanged(NetworkManager::ActiveConnection::State state) { NetworkManager::ActiveConnection *activePtr = qobject_cast(sender()); if (activePtr) { beginResetModel(); for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::ActiveConnection, activePtr->path())) { item->setConnectionState(state); item->invalidateDetails(); qCDebug(PLASMA_NM) << "Item " << item->name() << ": active connection changed to " << item->connectionState(); } endResetModel(); } } void NetworkModel::activeVpnConnectionStateChanged(NetworkManager::VpnConnection::State state, NetworkManager::VpnConnection::StateChangeReason reason) { Q_UNUSED(reason) NetworkManager::ActiveConnection *activePtr = qobject_cast(sender()); if (activePtr) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::ActiveConnection, activePtr->path())) { if (state == NetworkManager::VpnConnection::Prepare || state == NetworkManager::VpnConnection::NeedAuth || state == NetworkManager::VpnConnection::Connecting || state == NetworkManager::VpnConnection::GettingIpConfig) { item->setConnectionState(NetworkManager::ActiveConnection::Activating); } else if (state == NetworkManager::VpnConnection::Activated) { item->setConnectionState(NetworkManager::ActiveConnection::Activated); } else { item->setConnectionState(NetworkManager::ActiveConnection::Deactivated); } item->setVpnState(state); updateItem(item); qCDebug(PLASMA_NM) << "Item " << item->name() << ": active connection changed to " << item->connectionState(); } } } void NetworkModel::availableConnectionAppeared(const QString &connection) { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast(sender())->uni()); if (device) { addAvailableConnection(connection, device); } } void NetworkModel::availableConnectionDisappeared(const QString &connection) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { bool available = false; const QString devicePath = item->devicePath(); const QString specificPath = item->specificPath(); // We have to check whether the connection is still available, because it might be // presented in the model for more devices and we don't want to remove it for all of them. // Check whether the device is still available NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(devicePath); if (device) { // Check whether the connection is still listed as available for (const NetworkManager::Connection::Ptr &connection : device->availableConnections()) { if (connection->path() == item->connectionPath()) { available = true; break; } } } if (!available) { item->setDeviceName(QString()); item->setDevicePath(QString()); item->setDeviceState(NetworkManager::Device::UnknownState); item->setSignal(0); item->setSpecificPath(QString()); qCDebug(PLASMA_NM) << "Item " << item->name() << " removed as available connection"; // Check whether the connection is still available as an access point, this happens // when we change its properties, like ssid, bssid, security etc. if (item->type() == NetworkManager::ConnectionSettings::Wireless && !specificPath.isEmpty()) { if (device && device->type() == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast(); if (wifiDevice) { NetworkManager::AccessPoint::Ptr ap = wifiDevice->findAccessPoint(specificPath); if (ap) { NetworkManager::WirelessNetwork::Ptr network = wifiDevice->findNetwork(ap->ssid()); if (network) { addWirelessNetwork(network, wifiDevice); } } } } } if (item->duplicate()) { const int row = m_list.indexOf(item); if (row >= 0) { qCDebug(PLASMA_NM) << "Duplicate item " << item->name() << " removed completely"; beginRemoveRows(QModelIndex(), row, row); m_list.removeItem(item); item->deleteLater(); endRemoveRows(); } } else { updateItem(item); } } available = false; } } void NetworkModel::connectionAdded(const QString &connection) { NetworkManager::Connection::Ptr newConnection = NetworkManager::findConnection(connection); if (newConnection) { addConnection(newConnection); } } void NetworkModel::connectionRemoved(const QString &connection) { bool remove = false; for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connection)) { // When the item type is wireless, we can remove only the connection and leave it as an available access point if (item->type() == NetworkManager::ConnectionSettings::Wireless && !item->devicePath().isEmpty()) { for (NetworkModelItem *secondItem : m_list.items()) { // Remove it entirely when there is another connection with the same configuration and for the same device // or it's a shared connection if ((item->mode() != NetworkManager::WirelessSetting::Infrastructure) || (item->connectionPath() != secondItem->connectionPath() && item->devicePath() == secondItem->devicePath() && item->mode() == secondItem->mode() && item->securityType() == secondItem->securityType() && item->ssid() == secondItem->ssid())) { remove = true; break; } } if (!remove) { item->setConnectionPath(QString()); item->setName(item->ssid()); item->setSlave(false); item->setTimestamp(QDateTime()); item->setUuid(QString()); updateItem(item); qCDebug(PLASMA_NM) << "Item " << item->name() << ": connection removed"; } } else { remove = true; } if (remove) { const int row = m_list.indexOf(item); if (row >= 0) { qCDebug(PLASMA_NM) << "Item " << item->name() << " removed completely"; beginRemoveRows(QModelIndex(), row, row); m_list.removeItem(item); item->deleteLater(); endRemoveRows(); } } remove = false; } } void NetworkModel::connectionUpdated() { NetworkManager::Connection *connectionPtr = qobject_cast(sender()); if (connectionPtr) { NetworkManager::ConnectionSettings::Ptr settings = connectionPtr->settings(); for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Connection, connectionPtr->path())) { item->setConnectionPath(connectionPtr->path()); item->setName(settings->id()); item->setTimestamp(settings->timestamp()); item->setType(settings->connectionType()); item->setUuid(settings->uuid()); if (item->type() == NetworkManager::ConnectionSettings::Wireless) { NetworkManager::WirelessSetting::Ptr wirelessSetting; wirelessSetting = settings->setting(NetworkManager::Setting::Wireless).dynamicCast(); item->setMode(wirelessSetting->mode()); item->setSecurityType(NetworkManager::securityTypeFromConnectionSetting(settings)); item->setSsid(QString::fromUtf8(wirelessSetting->ssid())); // TODO check whether BSSID has changed and update the wireless info } updateItem(item); qCDebug(PLASMA_NM) << "Item " << item->name() << ": connection updated"; } } } void NetworkModel::deviceAdded(const QString &device) { NetworkManager::Device::Ptr dev = NetworkManager::findNetworkInterface(device); if (dev) { addDevice(dev); } } void NetworkModel::deviceRemoved(const QString &device) { // Make all items unavailable for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device)) { availableConnectionDisappeared(item->connectionPath()); } } void NetworkModel::deviceStateChanged(NetworkManager::Device::State state, NetworkManager::Device::State oldState, NetworkManager::Device::StateChangeReason reason) { Q_UNUSED(oldState); Q_UNUSED(reason); NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast(sender())->uni()); if (device) { beginResetModel(); for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { item->setDeviceState(state); item->invalidateDetails(); // qCDebug(PLASMA_NM) << "Item " << item->name() << ": device state changed to " << item->deviceState(); } endResetModel(); } } #if WITH_MODEMMANAGER_SUPPORT void NetworkModel::gsmNetworkAccessTechnologiesChanged(QFlags accessTechnologies) { Q_UNUSED(accessTechnologies); ModemManager::Modem *gsmNetwork = qobject_cast(sender()); if (gsmNetwork) { for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { if (dev->type() == NetworkManager::Device::Modem) { ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(dev->udi()); if (modem) { if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); if (modemNetwork && modemNetwork->device() == gsmNetwork->device()) { // TODO store access technology internally? for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, dev->uni())) { updateItem(item); } } } } } } } } void NetworkModel::gsmNetworkCurrentModesChanged() { ModemManager::Modem *gsmNetwork = qobject_cast(sender()); if (gsmNetwork) { for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { if (dev->type() == NetworkManager::Device::Modem) { ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(dev->udi()); if (modem) { if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); if (modemNetwork && modemNetwork->device() == gsmNetwork->device()) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, dev->uni())) { updateItem(item); } } } } } } } } void NetworkModel::gsmNetworkSignalQualityChanged(const ModemManager::SignalQualityPair &signalQuality) { ModemManager::Modem *gsmNetwork = qobject_cast(sender()); if (gsmNetwork) { for (const NetworkManager::Device::Ptr &dev : NetworkManager::networkInterfaces()) { if (dev->type() == NetworkManager::Device::Modem) { ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(dev->udi()); if (modem) { if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) { ModemManager::Modem::Ptr modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast(); if (modemNetwork && modemNetwork->device() == gsmNetwork->device()) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, dev->uni())) { item->setSignal(signalQuality.signal); updateItem(item); } } } } } } } } #endif void NetworkModel::ipConfigChanged() { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast(sender())->uni()); if (device) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { updateItem(item); // qCDebug(PLASMA_NM) << "Item " << item->name() << ": device ipconfig changed"; } } } void NetworkModel::ipInterfaceChanged() { NetworkManager::Device *device = qobject_cast(sender()); if (device) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Device, device->uni())) { if (device->ipInterfaceName().isEmpty()) { item->setDeviceName(device->interfaceName()); } else { item->setDeviceName(device->ipInterfaceName()); } } } } void NetworkModel::statusChanged(NetworkManager::Status status) { Q_UNUSED(status); qCDebug(PLASMA_NM) << "NetworkManager state changed to " << status; // This has probably effect only for VPN connections for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Type, NetworkManager::ConnectionSettings::Vpn)) { updateItem(item); } } void NetworkModel::wirelessNetworkAppeared(const QString &ssid) { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast(sender())->uni()); if (device && device->type() == NetworkManager::Device::Wifi) { NetworkManager::WirelessDevice::Ptr wirelessDevice = device.objectCast(); NetworkManager::WirelessNetwork::Ptr network = wirelessDevice->findNetwork(ssid); addWirelessNetwork(network, wirelessDevice); } } void NetworkModel::wirelessNetworkDisappeared(const QString &ssid) { NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(qobject_cast(sender())->uni()); if (device) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, ssid, device->uni())) { // Remove the entire item, because it's only AP or it's a duplicated available connection if (item->itemType() == NetworkModelItem::AvailableAccessPoint || item->duplicate()) { const int row = m_list.indexOf(item); if (row >= 0) { qCDebug(PLASMA_NM) << "Wireless network " << item->name() << " removed completely"; beginRemoveRows(QModelIndex(), row, row); m_list.removeItem(item); item->deleteLater(); endRemoveRows(); } // Remove only AP and device from the item and leave it as an unavailable connection } else { if (item->mode() == NetworkManager::WirelessSetting::Infrastructure) { item->setDeviceName(QString()); item->setDevicePath(QString()); item->setSpecificPath(QString()); } item->setSignal(0); updateItem(item); qCDebug(PLASMA_NM) << "Item " << item->name() << ": wireless network removed"; } } } } void NetworkModel::wirelessNetworkReferenceApChanged(const QString &accessPoint) { NetworkManager::WirelessNetwork *networkPtr = qobject_cast(sender()); if (networkPtr) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, networkPtr->ssid(), networkPtr->device())) { NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(item->connectionPath()); if (connection) { NetworkManager::WirelessSetting::Ptr wirelessSetting = connection->settings()->setting(NetworkManager::Setting::Wireless).staticCast(); if (wirelessSetting) { if (wirelessSetting->bssid().isEmpty()) { item->setSpecificPath(accessPoint); updateItem(item); } } } } } } void NetworkModel::wirelessNetworkSignalChanged(int signal) { NetworkManager::WirelessNetwork *networkPtr = qobject_cast(sender()); if (networkPtr) { for (NetworkModelItem *item : m_list.returnItems(NetworkItemsList::Ssid, networkPtr->ssid(), networkPtr->device())) { if (item->specificPath() == networkPtr->referenceAccessPoint()->uni()) { item->setSignal(signal); updateItem(item); // qCDebug(PLASMA_NM) << "Wireless network " << item->name() << ": signal changed to " << item->signal(); } } } } NetworkManager::WirelessSecurityType NetworkModel::alternativeWirelessSecurity(const NetworkManager::WirelessSecurityType type) { if (type == NetworkManager::WpaPsk) { return NetworkManager::Wpa2Psk; } else if (type == NetworkManager::WpaEap) { return NetworkManager::Wpa2Eap; } else if (type == NetworkManager::Wpa2Psk) { return NetworkManager::WpaPsk; } else if (type == NetworkManager::Wpa2Eap) { return NetworkManager::WpaEap; } return type; } void NetworkModel::updateFromWirelessNetwork(NetworkModelItem *item, const NetworkManager::WirelessNetwork::Ptr &network, const NetworkManager::WirelessDevice::Ptr &device) { NetworkManager::WirelessSecurityType securityType = NetworkManager::UnknownSecurity; NetworkManager::AccessPoint::Ptr ap = network->referenceAccessPoint(); if (ap && ap->capabilities().testFlag(NetworkManager::AccessPoint::Privacy)) { securityType = NetworkManager::findBestWirelessSecurity(device->wirelessCapabilities(), true, (device->mode() == NetworkManager::WirelessDevice::Adhoc), ap->capabilities(), ap->wpaFlags(), ap->rsnFlags()); } // Check whether the connection is associated with some concrete AP NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(item->connectionPath()); if (connection) { NetworkManager::WirelessSetting::Ptr wirelessSetting = connection->settings()->setting(NetworkManager::Setting::Wireless).staticCast(); if (wirelessSetting) { if (!wirelessSetting->bssid().isEmpty()) { for (const NetworkManager::AccessPoint::Ptr ap : network->accessPoints()) { if (ap->hardwareAddress() == NetworkManager::macAddressAsString(wirelessSetting->bssid())) { item->setSignal(ap->signalStrength()); item->setSpecificPath(ap->uni()); // We need to watch this AP for signal changes connect(ap.data(), &NetworkManager::AccessPoint::signalStrengthChanged, this, &NetworkModel::accessPointSignalStrengthChanged, Qt::UniqueConnection); } } } else { item->setSignal(network->signalStrength()); item->setSpecificPath(network->referenceAccessPoint()->uni()); } } } item->setSecurityType(securityType); updateItem(item); } diff --git a/libs/models/networkmodel.h b/libs/models/networkmodel.h index 110f2cf3..b8598547 100644 --- a/libs/models/networkmodel.h +++ b/libs/models/networkmodel.h @@ -1,131 +1,131 @@ /* Copyright 2013-2018 Jan Grulich This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef PLASMA_NM_NETWORK_MODEL_H #define PLASMA_NM_NETWORK_MODEL_H #include #include "networkitemslist.h" #include #include #include #include #if WITH_MODEMMANAGER_SUPPORT #include #endif class Q_DECL_EXPORT NetworkModel : public QAbstractListModel { Q_OBJECT public: explicit NetworkModel(QObject *parent = nullptr); ~NetworkModel() override; enum ItemRole { ConnectionDetailsRole = Qt::UserRole + 1, ConnectionIconRole, ConnectionPathRole, ConnectionStateRole, DeviceName, DevicePathRole, DeviceStateRole, DuplicateRole, ItemUniqueNameRole, ItemTypeRole, LastUsedRole, LastUsedDateOnlyRole, NameRole, SecurityTypeRole, SecurityTypeStringRole, SectionRole, SignalRole, SlaveRole, SsidRole, SpecificPathRole, TimeStampRole, TypeRole, UniRole, UuidRole, VpnState, VpnType, RxBytesRole, TxBytesRole }; int rowCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; QHash roleNames() const override; public Q_SLOTS: void onItemUpdated(); void setDeviceStatisticsRefreshRateMs(const QString &devicePath, uint refreshRate); private Q_SLOTS: void accessPointSignalStrengthChanged(int signal); void activeConnectionAdded(const QString &activeConnection); void activeConnectionRemoved(const QString &activeConnection); void activeConnectionStateChanged(NetworkManager::ActiveConnection::State state); void activeVpnConnectionStateChanged(NetworkManager::VpnConnection::State state,NetworkManager::VpnConnection::StateChangeReason reason); void availableConnectionAppeared(const QString &connection); void availableConnectionDisappeared(const QString &connection); void connectionAdded(const QString &connection); void connectionRemoved(const QString &connection); void connectionUpdated(); void deviceAdded(const QString &device); void deviceRemoved(const QString &device); void deviceStateChanged(NetworkManager::Device::State state, NetworkManager::Device::State oldState, NetworkManager::Device::StateChangeReason reason); #if WITH_MODEMMANAGER_SUPPORT void gsmNetworkAccessTechnologiesChanged(QFlags accessTechnologies); void gsmNetworkCurrentModesChanged(); void gsmNetworkSignalQualityChanged(const ModemManager::SignalQualityPair &signalQuality); #endif void ipConfigChanged(); void ipInterfaceChanged(); void statusChanged(NetworkManager::Status status); void wirelessNetworkAppeared(const QString &ssid); void wirelessNetworkDisappeared(const QString &ssid); void wirelessNetworkSignalChanged(int signal); void wirelessNetworkReferenceApChanged(const QString &accessPoint); void initialize(); private: NetworkItemsList m_list; void addActiveConnection(const NetworkManager::ActiveConnection::Ptr &activeConnection); void addAvailableConnection(const QString &connection, const NetworkManager::Device::Ptr &device); void addConnection(const NetworkManager::Connection::Ptr &connection); void addDevice(const NetworkManager::Device::Ptr &device); void addWirelessNetwork(const NetworkManager::WirelessNetwork::Ptr &network, const NetworkManager::WirelessDevice::Ptr &device); - void checkAndCreateDuplicate(const QString &connection, const NetworkManager::Device::Ptr &device); + void checkAndCreateDuplicate(const QString &connection, const QString &deviceUni); void initializeSignals(); void initializeSignals(const NetworkManager::ActiveConnection::Ptr &activeConnection); void initializeSignals(const NetworkManager::Connection::Ptr &connection); void initializeSignals(const NetworkManager::Device::Ptr &device); void initializeSignals(const NetworkManager::WirelessNetwork::Ptr &network); void updateItem(NetworkModelItem *item); void updateFromWirelessNetwork(NetworkModelItem *item, const NetworkManager::WirelessNetwork::Ptr &network, const NetworkManager::WirelessDevice::Ptr &device); NetworkManager::WirelessSecurityType alternativeWirelessSecurity(const NetworkManager::WirelessSecurityType type); }; #endif // PLASMA_NM_NETWORK_MODEL_H