diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) +include(ECMQMLModules) include(FeatureSummary) @@ -50,6 +51,8 @@ set_package_properties(KF5ModemManagerQt PROPERTIES TYPE OPTIONAL) +ecm_find_qmlmodule(org.kde.prison 1.0) + if (BUILD_MOBILE) find_package(KF5Kirigami2 ${KF5_MIN_VERSION} CONFIG) set_package_properties(KF5Kirigami2 PROPERTIES diff --git a/applet/contents/ui/ConnectionItem.qml b/applet/contents/ui/ConnectionItem.qml --- a/applet/contents/ui/ConnectionItem.qml +++ b/applet/contents/ui/ConnectionItem.qml @@ -166,6 +166,22 @@ icon: (ConnectionState == PlasmaNM.Enums.Deactivated) ? "network-connect" : "network-disconnect" onClicked: changeState() } + PlasmaComponents.MenuItem { + text: i18n("Show network's QR code") + icon: "view-barcode" + visible: Uuid && Type == PlasmaNM.Enums.Wireless && + (SecurityType == PlasmaNM.Enums.StaticWep || SecurityType == PlasmaNM.Enums.WpaPsk || SecurityType == PlasmaNM.Enums.Wpa2Psk) + onClicked: { + const data = handler.wifiCode(ConnectionPath, Ssid, SecurityType) + var obj = showQR.createObject(connectionItem, { content: data }); + obj.showMaximized() + } + + Component { + id: showQR + ShowQR {} + } + } PlasmaComponents.MenuItem { text: i18n("Configure...") icon: "settings-configure" diff --git a/applet/contents/ui/ShowQR.qml b/applet/contents/ui/ShowQR.qml new file mode 100644 --- /dev/null +++ b/applet/contents/ui/ShowQR.qml @@ -0,0 +1,53 @@ +/* + Copyright 2019 Aleix Pol Gonzalez + + 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 . +*/ + +import QtQuick 2.0 +import QtQuick.Window 2.0 +import QtQuick.Layouts 1.0 +import org.kde.kirigami 2.3 as Kirigami +import org.kde.prison 1.0 as Prison + +Window +{ + id: window + color: Qt.rgba(0, 0, 0, 0.3) + flags: Qt.FramelessWindowHint + + property alias content: dataInput.content + + MouseArea { + anchors.fill: parent + + onClicked: { + window.visible = false + window.destroy() + } + + Prison.Barcode { + anchors { + fill: parent + margins: Kirigami.Units.largeSpacing * 4 + } + + id: dataInput + barcodeType: "QRCode" + } + } +} diff --git a/libs/handler.h b/libs/handler.h --- a/libs/handler.h +++ b/libs/handler.h @@ -26,6 +26,7 @@ #include #include #include +#include #if WITH_MODEMMANAGER_SUPPORT #include #endif @@ -68,6 +69,18 @@ * it will open the connection editor for advanced configuration. * */ void addAndActivateConnection(const QString &device, const QString &specificParameter, const QString &password = QString()); + + /** + * Returns a code that includes the credentials to a said wifi connection + * Here's some information on how this information is created, it's generally used to put in QR codes to share. + * https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11 + * + * @param connectionPath the d-bus path to the connection we want to read + * @param ssid the name of the network being displayed + * @param securityType the authentication protocol used for this specific ssid + */ + QString wifiCode(const QString& connectionPath, const QString& ssid, /*NetworkManager::WirelessSecurityType*/ int securityType) const; + /** * Adds a new connection * @map - NMVariantMapMap with connection settings diff --git a/libs/handler.cpp b/libs/handler.cpp --- a/libs/handler.cpp +++ b/libs/handler.cpp @@ -165,6 +165,56 @@ connect(watcher, &QDBusPendingCallWatcher::finished, this, &Handler::replyFinished); } +QString Handler::wifiCode(const QString& connectionPath, const QString& ssid, int _securityType) const +{ + NetworkManager::WirelessSecurityType securityType = static_cast(_securityType); + + QString ret = QStringLiteral("WIFI:S:") + ssid + QLatin1Char(';'); + if (securityType != NetworkManager::NoneSecurity) { + switch (securityType) { + case NetworkManager::NoneSecurity: + break; + case NetworkManager::StaticWep: + ret += "T:WEP;"; + break; + case NetworkManager::WpaPsk: + case NetworkManager::Wpa2Psk: + ret += "T:WPA;"; + break; + default: + case NetworkManager::DynamicWep: + case NetworkManager::WpaEap: + case NetworkManager::Wpa2Eap: + case NetworkManager::Leap: + return {}; + } + } + + NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(connectionPath); + if(!connection) + return {}; + + const auto key = QStringLiteral("802-11-wireless-security"); + auto reply = connection->secrets(key); + + const auto secret = reply.argumentAt<0>()[key]; + QString pass; + switch (securityType) { + case NetworkManager::NoneSecurity: + break; + case NetworkManager::WpaPsk: + case NetworkManager::Wpa2Psk: + pass = secret["psk"].toString(); + break; + default: + return {}; + } + if (!pass.isEmpty()) + ret += QStringLiteral("P:") + pass + QLatin1Char(';'); + + return ret + QLatin1Char(';'); +} + void Handler::addAndActivateConnection(const QString& device, const QString& specificObject, const QString& password) { NetworkManager::AccessPoint::Ptr ap;