File indexing completed on 2024-04-28 05:34:04

0001 /*
0002     SPDX-FileCopyrightText: 2013 Jan Grulich <jgrulich@redhat.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "connectionicon.h"
0008 #include "configuration.h"
0009 #include "uiutils.h"
0010 
0011 #include <NetworkManagerQt/BluetoothDevice>
0012 #include <NetworkManagerQt/Connection>
0013 #include <NetworkManagerQt/ConnectionSettings>
0014 #include <NetworkManagerQt/Device>
0015 #include <NetworkManagerQt/ModemDevice>
0016 #include <NetworkManagerQt/WiredDevice>
0017 #include <NetworkManagerQt/WirelessDevice>
0018 #include <NetworkManagerQt/WirelessSetting>
0019 
0020 #include <ModemManagerQt/Manager>
0021 
0022 #include <QDBusReply>
0023 
0024 #include <QCoroDBus>
0025 
0026 ConnectionIcon::ConnectionIcon(QObject *parent)
0027     : QObject(parent)
0028     , m_wirelessNetwork(nullptr)
0029     , m_modemNetwork(nullptr)
0030 {
0031     connect(NetworkManager::notifier(), &NetworkManager::Notifier::primaryConnectionChanged, this, &ConnectionIcon::primaryConnectionChanged);
0032     connect(NetworkManager::notifier(), &NetworkManager::Notifier::activatingConnectionChanged, this, &ConnectionIcon::activatingConnectionChanged);
0033     connect(NetworkManager::notifier(), &NetworkManager::Notifier::activeConnectionAdded, this, &ConnectionIcon::activeConnectionAdded);
0034     connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceAdded, this, &ConnectionIcon::deviceAdded);
0035     connect(NetworkManager::notifier(), &NetworkManager::Notifier::deviceRemoved, this, &ConnectionIcon::deviceRemoved);
0036     connect(NetworkManager::notifier(), &NetworkManager::Notifier::networkingEnabledChanged, this, &ConnectionIcon::networkingEnabledChanged);
0037     connect(NetworkManager::notifier(), &NetworkManager::Notifier::statusChanged, this, &ConnectionIcon::statusChanged);
0038     connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessEnabledChanged, this, &ConnectionIcon::wirelessEnabledChanged);
0039     connect(NetworkManager::notifier(), &NetworkManager::Notifier::wirelessHardwareEnabledChanged, this, &ConnectionIcon::wirelessEnabledChanged);
0040     connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanEnabledChanged, this, &ConnectionIcon::wwanEnabledChanged);
0041     connect(NetworkManager::notifier(), &NetworkManager::Notifier::wwanHardwareEnabledChanged, this, &ConnectionIcon::wwanEnabledChanged);
0042 
0043     for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) {
0044         if (device->type() == NetworkManager::Device::Ethernet) {
0045             NetworkManager::WiredDevice::Ptr wiredDevice = device.staticCast<NetworkManager::WiredDevice>();
0046             if (wiredDevice) {
0047                 connect(wiredDevice.data(), &NetworkManager::WiredDevice::carrierChanged, this, &ConnectionIcon::carrierChanged);
0048             }
0049         } else if (device->type() == NetworkManager::Device::Wifi) {
0050             NetworkManager::WirelessDevice::Ptr wifiDevice = device.staticCast<NetworkManager::WirelessDevice>();
0051             if (wifiDevice) {
0052                 connect(wifiDevice.data(), &NetworkManager::WirelessDevice::availableConnectionAppeared, this, &ConnectionIcon::wirelessNetworkAppeared);
0053                 connect(wifiDevice.data(), &NetworkManager::WirelessDevice::networkAppeared, this, &ConnectionIcon::wirelessNetworkAppeared);
0054             }
0055         }
0056     }
0057 
0058     for (const NetworkManager::ActiveConnection::Ptr &activeConnection : NetworkManager::activeConnections()) {
0059         addActiveConnection(activeConnection->path());
0060     }
0061     setStates();
0062 
0063     setIcons();
0064 }
0065 
0066 ConnectionIcon::~ConnectionIcon() = default;
0067 
0068 bool ConnectionIcon::connecting() const
0069 {
0070     return m_connecting;
0071 }
0072 
0073 QString ConnectionIcon::connectionIcon() const
0074 {
0075     if (m_vpn && !m_connectionIcon.contains(QLatin1String("available"))) {
0076         return m_connectionIcon + QStringLiteral("-locked");
0077     }
0078 
0079     if (m_limited && !m_connectionIcon.contains(QLatin1String("available"))) {
0080         return m_connectionIcon + QStringLiteral("-limited");
0081     }
0082 
0083     return m_connectionIcon;
0084 }
0085 
0086 QString ConnectionIcon::connectionTooltipIcon() const
0087 {
0088     return m_connectionTooltipIcon;
0089 }
0090 
0091 NetworkManager::Connectivity ConnectionIcon::connectivity() const
0092 {
0093     return m_connectivity;
0094 }
0095 
0096 void ConnectionIcon::setConnectivity(NetworkManager::Connectivity connectivity)
0097 {
0098     if (m_connectivity == connectivity) {
0099         return;
0100     }
0101 
0102     m_connectivity = connectivity;
0103     Q_EMIT connectivityChanged(connectivity);
0104 
0105     const bool limited = (connectivity == NetworkManager::Portal || connectivity == NetworkManager::Limited);
0106     if (m_limited != limited) {
0107         m_limited = limited;
0108         Q_EMIT connectionIconChanged(connectionIcon());
0109     }
0110 }
0111 
0112 void ConnectionIcon::activatingConnectionChanged(const QString &connection)
0113 {
0114     Q_UNUSED(connection);
0115     setIcons();
0116 }
0117 
0118 void ConnectionIcon::addActiveConnection(const QString &activeConnection)
0119 {
0120     NetworkManager::ActiveConnection::Ptr active = NetworkManager::findActiveConnection(activeConnection);
0121 
0122     if (active) {
0123         NetworkManager::VpnConnection::Ptr vpnConnection;
0124         connect(active.data(), &NetworkManager::ActiveConnection::destroyed, this, &ConnectionIcon::activeConnectionDestroyed);
0125         if (active->vpn()) {
0126             vpnConnection = active.objectCast<NetworkManager::VpnConnection>();
0127             connect(vpnConnection.data(), &NetworkManager::VpnConnection::stateChanged, this, &ConnectionIcon::vpnConnectionStateChanged);
0128         } else {
0129             connect(active.data(), &NetworkManager::ActiveConnection::stateChanged, this, &ConnectionIcon::activeConnectionStateChanged, Qt::UniqueConnection);
0130         }
0131     }
0132 }
0133 
0134 void ConnectionIcon::activeConnectionAdded(const QString &activeConnection)
0135 {
0136     addActiveConnection(activeConnection);
0137     setStates();
0138 }
0139 
0140 void ConnectionIcon::activeConnectionStateChanged(NetworkManager::ActiveConnection::State state)
0141 {
0142     Q_UNUSED(state);
0143     setStates();
0144 }
0145 
0146 void ConnectionIcon::activeConnectionDestroyed()
0147 {
0148     setStates();
0149 }
0150 
0151 void ConnectionIcon::carrierChanged(bool carrier)
0152 {
0153     Q_UNUSED(carrier);
0154     setIcons();
0155 }
0156 
0157 void ConnectionIcon::deviceAdded(const QString &device)
0158 {
0159     NetworkManager::Device::Ptr dev = NetworkManager::findNetworkInterface(device);
0160 
0161     if (!dev) {
0162         return;
0163     }
0164 
0165     if (dev->type() == NetworkManager::Device::Ethernet) {
0166         NetworkManager::WiredDevice::Ptr wiredDev = dev.objectCast<NetworkManager::WiredDevice>();
0167         connect(wiredDev.data(), &NetworkManager::WiredDevice::carrierChanged, this, &ConnectionIcon::carrierChanged);
0168     }
0169 }
0170 
0171 void ConnectionIcon::deviceRemoved(const QString &device)
0172 {
0173     Q_UNUSED(device);
0174 
0175     if (NetworkManager::status() == NetworkManager::Disconnected) {
0176         setDisconnectedIcon();
0177     }
0178 }
0179 
0180 void ConnectionIcon::modemNetworkRemoved()
0181 {
0182     m_modemNetwork.clear();
0183 }
0184 
0185 void ConnectionIcon::modemSignalChanged(ModemManager::SignalQualityPair signalQuality)
0186 {
0187     int diff = m_signal - signalQuality.signal;
0188 
0189     if (diff >= 10 || diff <= -10) {
0190         m_signal = signalQuality.signal;
0191 
0192         setIconForModem();
0193     }
0194 }
0195 
0196 void ConnectionIcon::networkingEnabledChanged(bool enabled)
0197 {
0198     if (!enabled) {
0199         setConnectionIcon(QStringLiteral("network-unavailable"));
0200     }
0201 }
0202 
0203 void ConnectionIcon::primaryConnectionChanged(const QString &connection)
0204 {
0205     if (!connection.isEmpty()) {
0206         setIcons();
0207     }
0208 }
0209 
0210 void ConnectionIcon::statusChanged(NetworkManager::Status status)
0211 {
0212     if (status == NetworkManager::Disconnected) {
0213         setDisconnectedIcon();
0214     }
0215 }
0216 
0217 void ConnectionIcon::vpnConnectionStateChanged(NetworkManager::VpnConnection::State state, NetworkManager::VpnConnection::StateChangeReason reason)
0218 {
0219     Q_UNUSED(state);
0220     Q_UNUSED(reason);
0221     setStates();
0222     setIcons();
0223 }
0224 
0225 void ConnectionIcon::wirelessEnabledChanged(bool enabled)
0226 {
0227     Q_UNUSED(enabled);
0228     setIcons();
0229 }
0230 
0231 void ConnectionIcon::wwanEnabledChanged(bool enabled)
0232 {
0233     Q_UNUSED(enabled);
0234     setIcons();
0235 }
0236 
0237 void ConnectionIcon::wirelessNetworkAppeared(const QString &network)
0238 {
0239     Q_UNUSED(network);
0240     setIcons();
0241 }
0242 
0243 void ConnectionIcon::setStates()
0244 {
0245     bool connecting = false;
0246     bool vpn = false;
0247     for (const NetworkManager::ActiveConnection::Ptr &activeConnection : NetworkManager::activeConnections()) {
0248         NetworkManager::VpnConnection::Ptr vpnConnection;
0249         if (activeConnection->vpn()) {
0250             vpnConnection = activeConnection.objectCast<NetworkManager::VpnConnection>();
0251         }
0252 
0253         if (!vpnConnection) {
0254             if (activeConnection->state() == NetworkManager::ActiveConnection::Activating && UiUtils::isConnectionTypeSupported(activeConnection->type())) {
0255                 connecting = true;
0256             }
0257             if (activeConnection->type() == NetworkManager::ConnectionSettings::ConnectionType::WireGuard) {
0258                 vpn = true;
0259             }
0260         } else {
0261             if (vpnConnection->state() == NetworkManager::VpnConnection::Activated) {
0262                 vpn = true;
0263             } else if (vpnConnection->state() == NetworkManager::VpnConnection::Prepare //
0264                        || vpnConnection->state() == NetworkManager::VpnConnection::NeedAuth //
0265                        || vpnConnection->state() == NetworkManager::VpnConnection::Connecting //
0266                        || vpnConnection->state() == NetworkManager::VpnConnection::GettingIpConfig) {
0267                 connecting = true;
0268             }
0269         }
0270     }
0271 
0272     setVpn(vpn);
0273     setConnecting(connecting);
0274 }
0275 
0276 void ConnectionIcon::setIcons()
0277 {
0278     m_signal = 0;
0279     if (m_modemNetwork) {
0280         disconnect(m_modemNetwork.data(), nullptr, this, nullptr);
0281         m_modemNetwork.clear();
0282     }
0283     if (m_wirelessNetwork) {
0284         disconnect(m_wirelessNetwork.data(), nullptr, this, nullptr);
0285         m_wirelessNetwork.clear();
0286     }
0287 
0288     NetworkManager::ActiveConnection::Ptr connection = NetworkManager::activatingConnection();
0289 
0290     // Set icon based on the current primary connection if the activating connection is virtual
0291     // since we're not setting icons for virtual connections
0292     if (!connection || (connection && UiUtils::isConnectionTypeVirtual(connection->type()))
0293         || connection->type() == NetworkManager::ConnectionSettings::WireGuard) {
0294         connection = NetworkManager::primaryConnection();
0295     }
0296 
0297     /* Fallback: If we still don't have an active connection with default route or the default route goes through a connection
0298                  of generic type (some type of VPNs) we need to go through all other active connections and pick the one with
0299                  highest probability of being the main one (order is: vpn, wired, wireless, gsm, cdma, bluetooth) */
0300     if ((!connection && !NetworkManager::activeConnections().isEmpty()) || (connection && connection->type() == NetworkManager::ConnectionSettings::Generic)
0301         || (connection && connection->type() == NetworkManager::ConnectionSettings::Tun)) {
0302         for (const NetworkManager::ActiveConnection::Ptr &activeConnection : NetworkManager::activeConnections()) {
0303             const NetworkManager::ConnectionSettings::ConnectionType type = activeConnection->type();
0304             if (type == NetworkManager::ConnectionSettings::Bluetooth) {
0305                 if (connection && connection->type() <= NetworkManager::ConnectionSettings::Bluetooth) {
0306                     connection = activeConnection;
0307                 }
0308             } else if (type == NetworkManager::ConnectionSettings::Cdma) {
0309                 if (connection && connection->type() <= NetworkManager::ConnectionSettings::Cdma) {
0310                     connection = activeConnection;
0311                 }
0312             } else if (type == NetworkManager::ConnectionSettings::Gsm) {
0313                 if (connection && connection->type() <= NetworkManager::ConnectionSettings::Gsm) {
0314                     connection = activeConnection;
0315                 }
0316             } else if (type == NetworkManager::ConnectionSettings::Vpn) {
0317                 connection = activeConnection;
0318             } else if (type == NetworkManager::ConnectionSettings::WireGuard) {
0319                 connection = activeConnection;
0320             } else if (type == NetworkManager::ConnectionSettings::Wired) {
0321                 if (connection
0322                     && (connection->type() != NetworkManager::ConnectionSettings::Vpn //
0323                         || connection->type() != NetworkManager::ConnectionSettings::WireGuard)) {
0324                     connection = activeConnection;
0325                 }
0326             } else if (type == NetworkManager::ConnectionSettings::Wireless) {
0327                 if (connection
0328                     && (connection->type() != NetworkManager::ConnectionSettings::Vpn //
0329                         && (connection->type() != NetworkManager::ConnectionSettings::Wired))) {
0330                     connection = activeConnection;
0331                 }
0332             }
0333         }
0334     }
0335 
0336     if (connection && !connection->devices().isEmpty()) {
0337         NetworkManager::Device::Ptr device = NetworkManager::findNetworkInterface(connection->devices().first());
0338 
0339         if (device) {
0340             NetworkManager::Device::Type type = device->type();
0341             if (type == NetworkManager::Device::Wifi) {
0342                 NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>();
0343                 if (wifiDevice->mode() == NetworkManager::WirelessDevice::Adhoc) {
0344                     setWirelessIconForSignalStrength(100);
0345                 } else {
0346                     NetworkManager::AccessPoint::Ptr ap = wifiDevice->activeAccessPoint();
0347                     if (ap) {
0348                         setWirelessIcon(device, ap->ssid());
0349                     }
0350                 }
0351             } else if (type == NetworkManager::Device::Ethernet) {
0352                 setConnectionIcon(QStringLiteral("network-wired-activated"));
0353                 setConnectionTooltipIcon(QStringLiteral("network-wired-activated"));
0354             } else if (type == NetworkManager::Device::Modem) {
0355                 setModemIcon(device);
0356             } else if (type == NetworkManager::Device::Bluetooth) {
0357                 NetworkManager::BluetoothDevice::Ptr btDevice = device.objectCast<NetworkManager::BluetoothDevice>();
0358                 if (btDevice) {
0359                     if (btDevice->bluetoothCapabilities().testFlag(NetworkManager::BluetoothDevice::Dun)) {
0360                         setModemIcon(device);
0361                     } else {
0362                         setConnectionIcon(QStringLiteral("network-wireless-bluetooth-symbolic"));
0363                         setConnectionTooltipIcon(QStringLiteral("network-wireless-bluetooth"));
0364                     }
0365                 }
0366             } else if (type == 29) { // TODO change to WireGuard enum value once it is added
0367                 // WireGuard is a VPN but is not implemented
0368                 // in NetworkManager as a VPN, so we don't want to
0369                 // do anything just because it has a device
0370                 // associated with it.
0371             } else {
0372                 // Ignore other devices (bond/bridge/team etc.)
0373                 setDisconnectedIcon();
0374             }
0375         }
0376     } else {
0377         setDisconnectedIcon();
0378     }
0379 }
0380 
0381 void ConnectionIcon::setDisconnectedIcon()
0382 {
0383     if (Configuration::self().airplaneModeEnabled()) {
0384         setConnectionIcon(QStringLiteral("network-flightmode-on"));
0385         return;
0386     }
0387 
0388     if (NetworkManager::status() == NetworkManager::Unknown //
0389         || NetworkManager::status() == NetworkManager::Asleep) {
0390         setConnectionIcon(QStringLiteral("network-unavailable"));
0391         return;
0392     }
0393 
0394     bool wired = false;
0395     bool wireless = false;
0396     bool modem = false;
0397 
0398     m_limited = false;
0399     m_vpn = false;
0400 
0401     for (const NetworkManager::Device::Ptr &device : NetworkManager::networkInterfaces()) {
0402         if (device->type() == NetworkManager::Device::Ethernet) {
0403             NetworkManager::WiredDevice::Ptr wiredDev = device.objectCast<NetworkManager::WiredDevice>();
0404             if (wiredDev->carrier()) {
0405                 wired = true;
0406             }
0407         } else if (device->type() == NetworkManager::Device::Wifi //
0408                    && NetworkManager::isWirelessEnabled() //
0409                    && NetworkManager::isWirelessHardwareEnabled()) {
0410             NetworkManager::WirelessDevice::Ptr wifiDevice = device.objectCast<NetworkManager::WirelessDevice>();
0411             if (!wifiDevice->accessPoints().isEmpty() || !wifiDevice->availableConnections().isEmpty()) {
0412                 wireless = true;
0413             }
0414         } else if (device->type() == NetworkManager::Device::Modem //
0415                    && NetworkManager::isWwanEnabled() //
0416                    && NetworkManager::isWwanHardwareEnabled()) {
0417             modem = true;
0418         }
0419     }
0420 
0421     if (wired) {
0422         setConnectionIcon(QStringLiteral("network-wired-available"));
0423         setConnectionTooltipIcon(QStringLiteral("network-wired"));
0424         return;
0425     } else if (wireless) {
0426         setConnectionIcon(QStringLiteral("network-wireless-available"));
0427         setConnectionTooltipIcon(QStringLiteral("network-wireless-connected-00"));
0428         return;
0429     } else if (modem) {
0430         setConnectionIcon(QStringLiteral("network-mobile-available"));
0431         setConnectionTooltipIcon(QStringLiteral("phone"));
0432         return;
0433     } else {
0434         setConnectionIcon(QStringLiteral("network-unavailable"));
0435         setConnectionTooltipIcon(QStringLiteral("network-wired"));
0436     }
0437 }
0438 
0439 void ConnectionIcon::setModemIcon(const NetworkManager::Device::Ptr &device)
0440 {
0441     NetworkManager::ModemDevice::Ptr modemDevice = device.objectCast<NetworkManager::ModemDevice>();
0442 
0443     if (!modemDevice) {
0444         setConnectionIcon(QStringLiteral("network-mobile-100"));
0445 
0446         return;
0447     }
0448 
0449     ModemManager::ModemDevice::Ptr modem = ModemManager::findModemDevice(device->udi());
0450     if (modem) {
0451         if (modem->hasInterface(ModemManager::ModemDevice::ModemInterface)) {
0452             m_modemNetwork = modem->interface(ModemManager::ModemDevice::ModemInterface).objectCast<ModemManager::Modem>();
0453         }
0454     }
0455 
0456     if (m_modemNetwork) {
0457         connect(m_modemNetwork.data(), &ModemManager::Modem::signalQualityChanged, this, &ConnectionIcon::modemSignalChanged, Qt::UniqueConnection);
0458         connect(m_modemNetwork.data(), &ModemManager::Modem::accessTechnologiesChanged, this, &ConnectionIcon::setIconForModem, Qt::UniqueConnection);
0459         connect(m_modemNetwork.data(), &ModemManager::Modem::destroyed, this, &ConnectionIcon::modemNetworkRemoved);
0460 
0461         m_signal = m_modemNetwork->signalQuality().signal;
0462         setIconForModem();
0463     } else {
0464         setConnectionIcon(QStringLiteral("network-mobile-0"));
0465         setConnectionTooltipIcon(QStringLiteral("phone"));
0466         return;
0467     }
0468 }
0469 
0470 void ConnectionIcon::setIconForModem()
0471 {
0472     if (!m_signal) {
0473         m_signal = m_modemNetwork->signalQuality().signal;
0474     }
0475     QString strength = QStringLiteral("00");
0476 
0477     if (m_signal == 0) {
0478         strength = QLatin1Char('0');
0479     } else if (m_signal < 20) {
0480         strength = QStringLiteral("20");
0481     } else if (m_signal < 40) {
0482         strength = QStringLiteral("40");
0483     } else if (m_signal < 60) {
0484         strength = QStringLiteral("60");
0485     } else if (m_signal < 80) {
0486         strength = QStringLiteral("80");
0487     } else {
0488         strength = QStringLiteral("100");
0489     }
0490 
0491     QString result;
0492 
0493     switch (m_modemNetwork->accessTechnologies()) {
0494     case MM_MODEM_ACCESS_TECHNOLOGY_GSM:
0495     case MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT:
0496         result = QStringLiteral("network-mobile-%1");
0497         break;
0498     case MM_MODEM_ACCESS_TECHNOLOGY_GPRS:
0499         result = QStringLiteral("network-mobile-%1-gprs");
0500         break;
0501     case MM_MODEM_ACCESS_TECHNOLOGY_EDGE:
0502         result = QStringLiteral("network-mobile-%1-edge");
0503         break;
0504     case MM_MODEM_ACCESS_TECHNOLOGY_UMTS:
0505         result = QStringLiteral("network-mobile-%1-umts");
0506         break;
0507     case MM_MODEM_ACCESS_TECHNOLOGY_HSDPA:
0508         result = QStringLiteral("network-mobile-%1-hsdpa");
0509         break;
0510     case MM_MODEM_ACCESS_TECHNOLOGY_HSUPA:
0511         result = QStringLiteral("network-mobile-%1-hsupa");
0512         break;
0513     case MM_MODEM_ACCESS_TECHNOLOGY_HSPA:
0514     case MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS:
0515         result = QStringLiteral("network-mobile-%1-hspa");
0516         break;
0517     case MM_MODEM_ACCESS_TECHNOLOGY_LTE:
0518         result = QStringLiteral("network-mobile-%1-lte");
0519         break;
0520 #if MM_CHECK_VERSION(1, 14, 0)
0521     case MM_MODEM_ACCESS_TECHNOLOGY_5GNR:
0522         result = QStringLiteral("network-mobile-%1-5g");
0523         break;
0524 #endif
0525     default:
0526         result = QStringLiteral("network-mobile-%1");
0527         break;
0528     }
0529 
0530     setConnectionIcon(QString(result).arg(strength));
0531     setConnectionTooltipIcon(QStringLiteral("phone"));
0532 }
0533 
0534 void ConnectionIcon::setWirelessIcon(const NetworkManager::Device::Ptr &device, const QString &ssid)
0535 {
0536     NetworkManager::WirelessDevice::Ptr wirelessDevice = device.objectCast<NetworkManager::WirelessDevice>();
0537     if (device) {
0538         m_wirelessNetwork = wirelessDevice->findNetwork(ssid);
0539     } else {
0540         m_wirelessNetwork.clear();
0541     }
0542 
0543     if (m_wirelessNetwork) {
0544         connect(m_wirelessNetwork.data(),
0545                 &NetworkManager::WirelessNetwork::signalStrengthChanged,
0546                 this,
0547                 &ConnectionIcon::setWirelessIconForSignalStrength,
0548                 Qt::UniqueConnection);
0549 
0550         setWirelessIconForSignalStrength(m_wirelessNetwork->signalStrength());
0551     } else {
0552         setDisconnectedIcon();
0553     }
0554 }
0555 
0556 void ConnectionIcon::setWirelessIconForSignalStrength(int strength)
0557 {
0558     int iconStrength = 100;
0559     if (strength == 0) {
0560         iconStrength = 0;
0561         setConnectionTooltipIcon(QStringLiteral("network-wireless-connected-00"));
0562     } else if (strength < 20) {
0563         iconStrength = 20;
0564         setConnectionTooltipIcon(QStringLiteral("network-wireless-connected-20"));
0565     } else if (strength < 40) {
0566         iconStrength = 40;
0567         setConnectionTooltipIcon(QStringLiteral("network-wireless-connected-40"));
0568     } else if (strength < 60) {
0569         iconStrength = 60;
0570         setConnectionTooltipIcon(QStringLiteral("network-wireless-connected-60"));
0571     } else if (strength < 80) {
0572         iconStrength = 80;
0573         setConnectionTooltipIcon(QStringLiteral("network-wireless-connected-80"));
0574     } else if (strength < 100) {
0575         setConnectionTooltipIcon(QStringLiteral("network-wireless-connected-100"));
0576     }
0577 
0578     const QString icon = QStringLiteral("network-wireless-%1").arg(iconStrength);
0579 
0580     setConnectionIcon(icon);
0581 }
0582 
0583 void ConnectionIcon::setConnecting(bool connecting)
0584 {
0585     if (connecting != m_connecting) {
0586         m_connecting = connecting;
0587         Q_EMIT connectingChanged(m_connecting);
0588     }
0589 }
0590 
0591 void ConnectionIcon::setConnectionIcon(const QString &icon)
0592 {
0593     if (icon != m_connectionIcon) {
0594         m_connectionIcon = icon;
0595         Q_EMIT connectionIconChanged(connectionIcon());
0596     }
0597 }
0598 
0599 void ConnectionIcon::setConnectionTooltipIcon(const QString &icon)
0600 {
0601     if (icon != m_connectionTooltipIcon) {
0602         m_connectionTooltipIcon = icon;
0603         Q_EMIT connectionTooltipIconChanged(m_connectionTooltipIcon);
0604     }
0605 }
0606 
0607 void ConnectionIcon::setVpn(bool vpn)
0608 {
0609     if (m_vpn != vpn) {
0610         m_vpn = vpn;
0611         Q_EMIT connectionIconChanged(connectionIcon());
0612     }
0613 }
0614 
0615 #include "moc_connectionicon.cpp"