diff --git a/libs/models/mobileproxymodel.cpp b/libs/models/mobileproxymodel.cpp index f8802c14..9d012655 100644 --- a/libs/models/mobileproxymodel.cpp +++ b/libs/models/mobileproxymodel.cpp @@ -1,133 +1,131 @@ /* * Mobile proxy model - model for displaying netwoks in mobile kcm * Copyright 2017 Martin Kacej * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) 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 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "mobileproxymodel.h" #include "networkmodel.h" #include "networkmodelitem.h" #include "uiutils.h" MobileProxyModel::MobileProxyModel(QObject* parent) : QSortFilterProxyModel(parent) { setDynamicSortFilter(true); sort(0, Qt::DescendingOrder); } MobileProxyModel::~MobileProxyModel() { } void MobileProxyModel::setShowSavedMode(bool mode){ m_showSavedMode = mode; emit showSavedModeChanged(mode); invalidate(); } bool MobileProxyModel::showSavedMode() const{ return m_showSavedMode; } bool MobileProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { const QModelIndex index = sourceModel()->index(source_row, 0, source_parent); // slaves are always filtered-out const bool isSlave = sourceModel()->data(index, NetworkModel::SlaveRole).toBool(); if (isSlave) { return false; } const NetworkManager::ConnectionSettings::ConnectionType type = (NetworkManager::ConnectionSettings::ConnectionType) sourceModel()->data(index, NetworkModel::TypeRole).toUInt(); if (type == NetworkManager::ConnectionSettings::Wireless) { NetworkModelItem::ItemType itemType = (NetworkModelItem::ItemType)sourceModel()->data(index, NetworkModel::ItemTypeRole).toUInt(); if (showSavedMode()) { return itemType == NetworkModelItem::UnavailableConnection; } else { - if (sourceModel()->data(index,NetworkModel::SignalRole).toUInt() == 0) - return false; // if signal is 0 yet we still have connection, it means local access point -> we don't want to show that return itemType >= NetworkModelItem::AvailableConnection; } } return false; } bool MobileProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { const bool leftAvailable = (NetworkModelItem::ItemType)sourceModel()->data(left, NetworkModel::ItemTypeRole).toUInt() != NetworkModelItem::UnavailableConnection; const bool leftConnected = sourceModel()->data(left, NetworkModel::ConnectionStateRole).toUInt() == NetworkManager::ActiveConnection::Activated; const int leftConnectionState = sourceModel()->data(left, NetworkModel::ConnectionStateRole).toUInt(); const QString leftName = sourceModel()->data(left, NetworkModel::NameRole).toString(); const QString leftUuid = sourceModel()->data(left, NetworkModel::UuidRole).toString(); const int leftSignal = sourceModel()->data(left, NetworkModel::SignalRole).toInt(); const QDateTime leftDate = sourceModel()->data(left, NetworkModel::TimeStampRole).toDateTime(); const bool rightAvailable = (NetworkModelItem::ItemType)sourceModel()->data(right, NetworkModel::ItemTypeRole).toUInt() != NetworkModelItem::UnavailableConnection; const bool rightConnected = sourceModel()->data(right, NetworkModel::ConnectionStateRole).toUInt() == NetworkManager::ActiveConnection::Activated; const int rightConnectionState = sourceModel()->data(right, NetworkModel::ConnectionStateRole).toUInt(); const QString rightName = sourceModel()->data(right, NetworkModel::NameRole).toString(); const QString rightUuid = sourceModel()->data(right, NetworkModel::UuidRole).toString(); const int rightSignal = sourceModel()->data(right, NetworkModel::SignalRole).toInt(); const QDateTime rightDate = sourceModel()->data(right, NetworkModel::TimeStampRole).toDateTime(); if (leftAvailable < rightAvailable) { return true; } else if (leftAvailable > rightAvailable) { return false; } if (leftConnected < rightConnected) { return true; } else if (leftConnected > rightConnected) { return false; } if (leftConnectionState > rightConnectionState) { return true; } else if (leftConnectionState < rightConnectionState) { return false; } if (leftUuid.isEmpty() && !rightUuid.isEmpty()) { return true; } else if (!leftUuid.isEmpty() && rightUuid.isEmpty()) { return false; } if (leftDate > rightDate) { return false; } else if (leftDate < rightDate) { return true; } if (leftSignal < rightSignal) { return true; } else if (leftSignal > rightSignal) { return false; } if (QString::localeAwareCompare(leftName, rightName) > 0) { return true; } else { return false; } } diff --git a/mobile/wifi/package/contents/ui/ConnectionEditor.qml b/mobile/wifi/package/contents/ui/ConnectionEditor.qml deleted file mode 100644 index 3ac1a6da..00000000 --- a/mobile/wifi/package/contents/ui/ConnectionEditor.qml +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2017 Martin Kacej - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -import QtQuick 2.6 -import QtQuick.Controls 2.2 as Controls -import QtQuick.Layouts 1.2 -import org.kde.kirigami 2.2 as Kirigami - -Kirigami.ScrollablePage { - property var details - property var str: 0 - property var connection : ({}) - property var enabledSaving: (editorIpSection.enabledSave && editorSecuritySection.enabledSave && ssidField.text) - - title: i18n("Connection Editor") - width: parent.width - - ColumnLayout { - Controls.Label { - text: i18n("SSID") - font.weight: Font.Bold - //anchors.horizontalCenter: parent.horizontalCenter - } - - Controls.TextField { - id: ssidField - //anchors.horizontalCenter: parent.horizontalCenter - placeholderText: i18n("None") - } - - IPAddressSetting { - id: editorIpSection - width: parent.width - //anchors.horizontalCenter: parent.horizontalCenter - } - - WirelessSecuritySetting { - id: editorSecuritySection - anchors.topMargin: units.gridUnit - //anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - } - } - - footer: Item { - height: Kirigami.Units.gridUnit * 4 - RowLayout { - anchors.horizontalCenter: parent.horizontalCenter - spacing: Kirigami.Units.gridUnit - Controls.Button { - enabled: enabledSaving - text: i18n("Save") - icon.name: "document-save" - onPressed: { - save() - kcm.pop() - } - } - Controls.Button { - icon.name: "dialog-cancel" - text: i18n("Cancel") - onPressed: { - kcm.pop() - } - } - } - } - - function save() { - connection = editorIpSection.ipmap - connection["id"] = ssidField.text - connection["mode"] = "infrastructure" - connection["802-11-wireless-security"] = editorSecuritySection.securityMap - console.info(connection) - kcm.addConnectionFromQML(connection) - console.info('Connection saved '+ connection["id"]) - } -} diff --git a/mobile/wifi/package/contents/ui/ConnectionItemDelegate.qml b/mobile/wifi/package/contents/ui/ConnectionItemDelegate.qml index 7dae7230..749a2a13 100644 --- a/mobile/wifi/package/contents/ui/ConnectionItemDelegate.qml +++ b/mobile/wifi/package/contents/ui/ConnectionItemDelegate.qml @@ -1,149 +1,147 @@ /* * Copyright 2017 Martin Kacej * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.6 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.2 as Controls import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.networkmanagement 0.2 as PlasmaNM import org.kde.kirigami 2.2 as Kirigami Kirigami.SwipeListItem { enabled: true property var map : [] property bool predictableWirelessPassword: !Uuid && Type == PlasmaNM.Enums.Wireless && (SecurityType == PlasmaNM.Enums.StaticWep || SecurityType == PlasmaNM.Enums.WpaPsk || SecurityType == PlasmaNM.Enums.Wpa2Psk) RowLayout { anchors.leftMargin: Kirigami.Units.largeSpacing * 5 spacing: Kirigami.Units.largeSpacing Kirigami.Separator {} Item { Layout.preferredWidth: Kirigami.Units.gridUnit Layout.preferredHeight: Kirigami.Units.gridUnit PlasmaCore.SvgItem { id: connectionSvgIcon elementId: mobileProxyModel.showSavedMode ? "network-wireless-connected-100" : ConnectionIcon svg: PlasmaCore.Svg { multipleImages: true imagePath: "icons/network" colorGroup: PlasmaCore.ColorScope.colorGroup } } Controls.BusyIndicator { id: connectingIndicator anchors { horizontalCenter: connectionSvgIcon.horizontalCenter verticalCenter: connectionSvgIcon.verticalCenter } running: ConnectionState == PlasmaNM.Enums.Activating visible: running } } Controls.Label { id: connectionNameLabel Layout.fillWidth: true visible: !connectionPasswordField.visible elide: Text.ElideRight text: ItemUniqueName textFormat: Text.PlainText } PasswordField { id: connectionPasswordField Layout.fillWidth: true implicitWidth: Kirigami.Units.gridUnit *16 securityType: SecurityType visible: false onVisibleChanged: { if (visible) forceActiveFocus() connectionPasswordField.text = "" } onAccepted: { if (acceptableInput) handler.addAndActivateConnection(DevicePath, SpecificPath, connectionPasswordField.text); } } } actions: [ Kirigami.Action { iconName: "network-connect" - visible: ConnectionState != PlasmaNM.Enums.Activated && Signal > 0 + visible: ConnectionState != PlasmaNM.Enums.Activated onTriggered: changeState() }, Kirigami.Action { iconName: "network-disconnect" visible: ConnectionState == PlasmaNM.Enums.Activated onTriggered: handler.deactivateConnection(ConnectionPath, DevicePath) }, Kirigami.Action { iconName: "configure" visible: (Uuid != "")? true : false onTriggered: { kcm.push("NetworkSettings.qml", {path: ConnectionPath}) } }, Kirigami.Action { iconName: "entry-delete" visible: (Uuid != "")? true : false onTriggered: handler.removeConnection(ConnectionPath) } ] onClicked: { changeState() } function changeState() { - if (Signal === 0) - return if (Uuid || !predictableWirelessPassword || connectionPasswordField.visible) { if (ConnectionState == PlasmaNM.Enums.Deactivated) { if (!predictableWirelessPassword && !Uuid) { handler.addAndActivateConnection(DevicePath, SpecificPath); } else if (connectionPasswordField.visible) { if (connectionPasswordField.text != "") { handler.addAndActivateConnection(DevicePath, SpecificPath, connectionPasswordFieldField.text); connectionPasswordField.visible = false; } else { connectionPasswordField.visible = false; } } else { handler.activateConnection(ConnectionPath, DevicePath, SpecificPath); } } else{ //show popup } } else if (predictableWirelessPassword) { connectionPasswordField.visible = true; } } } diff --git a/mobile/wifi/package/contents/ui/NetworkSettings.qml b/mobile/wifi/package/contents/ui/NetworkSettings.qml index 9d5ad69d..f9e1074b 100644 --- a/mobile/wifi/package/contents/ui/NetworkSettings.qml +++ b/mobile/wifi/package/contents/ui/NetworkSettings.qml @@ -1,259 +1,236 @@ /* * Copyright 2017 Martin Kacej * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - import QtQuick 2.6 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.2 as Controls import org.kde.kirigami 2.3 as Kirigami import org.kde.plasma.networkmanagement 0.2 as PlasmaNM import org.kde.kcm 1.1 SimpleKCM { property var path - property var settings: ({}) - property var securityMap: ({}) - property var activeMap: ({}) - property alias password: wepWpaPasswordField.text - property var ipmap: ({}) - property alias address: manualIPaddress.text - property alias gateway: manualIPgateway.text - property alias prefix: manualIPprefix.text - property alias dns: manualIPdns.text - property var ipRegex: /^(([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))\.){3}([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))$/ - property bool manualIp + property var wirelessSettings: ({}) + property var securitySettings: ({}) + property var ipSettings: ({}) + property var secrets: ({}) + + property var ipRegex: /^(([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))\.){3}([01]?[0-9]?[0-9]|2([0-4][0-9]|5[0-5]))$/ - property bool enabledSave: (ipMethodComb.currentIndex == 0 || ( - ipMethodComb.currentIndex == 1 && manualIPaddress.acceptableInput - && manualIPgateway.acceptableInput && manualIPprefix.acceptableInput - && manualIPdns.acceptableInput )) + property bool enabledSave: (ipMethodCombobox.currentIndex == 0 + || (ipMethodCombobox.currentIndex == 1 + && manualIPaddress.acceptableInput + && manualIPgateway.acceptableInput + && manualIPprefix.acceptableInput + && manualIPdns.acceptableInput)) actions.main: Kirigami.Action { icon.name: "dialog-ok" text: i18n("Save") + enabled: enabledSave onTriggered: { save() kcm.pop() } } header: Kirigami.Heading { id: detailsName - text: i18n("Connection Name") + text: i18n("Add new Connection") level: 2 leftPadding: Kirigami.Units.smallSpacing } Kirigami.FormLayout { - Item { + Kirigami.FormData.label: i18n("General") + Kirigami.FormData.isSection: true + } + Controls.TextField { + id: ssidField + Kirigami.FormData.label: i18n("SSID:") + text: wirelessSettings["ssid"] ? wirelessSettings["ssid"] : "" + enabled: true + onTextChanged: { + ipSettings["id"] = text + } + } + Controls.CheckBox { + id: hidden + Kirigami.FormData.label: i18n("Hidden Network:") + checked: wirelessSettings["hidden"] ? wirelessSettings["hidden"] : false + onToggled: ipSettings["hidden"] = checked + } + + Kirigami.Separator { Kirigami.FormData.label: i18n("Security") Kirigami.FormData.isSection: true } Controls.ComboBox { id: securityCombobox Kirigami.FormData.label: i18n("Security type:") model: ListModel { id: securityTypesModel // FIXME just placeholder element to set "text" property as default ListElement { text: "placeholder" } - Component.onCompleted: { + function load() { clear() append({ "text": i18n("None"), "type": PlasmaNM.Enums.NoneSecurity }) append({ "text": i18n("WEP Key"), "type": PlasmaNM.Enums.StaticWep }) append({ "text": i18n("Dynamic WEP"), "type": PlasmaNM.Enums.DynamicWep }) append({ "text": i18n("WPA/WPA2 Personal"), "type": PlasmaNM.Enums.Wpa2Psk }) append({ "text": i18n("WPA/WPA2 Enterprise"), "type": PlasmaNM.Enums.Wpa2Eap }) - securityCombobox.currentIndex = 0 + switch (securitySettings["key-mgmt"]) { + case "none": + securityCombobox.currentIndex = 0 + break + case "ieee8021x": + securityCombobox.currentIndex = 1 + break + case "wpa-psk": + securityCombobox.currentIndex = 3 + break + case "wpa-eap": + securityCombobox.currentIndex = 4 + break + default: + securityCombobox.currentIndex = 0 + break + } } } - onCurrentIndexChanged: { - state = securityTypesModel.get(currentIndex).type; - } + } PasswordField { - id: wepWpaPasswordField + id: passwordField Kirigami.FormData.label: i18n("Password:") - width: parent.width - securityType: securityTypesModel.get(securityCombobox.currentIndex).type + text: secrets["psk"] + visible: securityTypesModel.get(securityCombobox.currentIndex).type !== PlasmaNM.Enums.NoneSecurity + onTextChanged: securitySettings["password"] = text } Controls.ComboBox { id: authComboBox Kirigami.FormData.label: i18n("Authentication:") - visible: securityCombobox.currentIndex == 2 || securityCombobox.currentIndex == 4 - model: [i18n("TLS"), i18n("LEAP"), i18n("FAST"), i18n("Tunneled TLS"), i18n("Protected EAP")] // more - SIM, AKA, PWD ? + visible: securityCombobox.currentIndex === 2 + || securityCombobox.currentIndex === 4 + model: [i18n("TLS"), i18n("LEAP"), i18n("FAST"), i18n( + "Tunneled TLS"), i18n( + "Protected EAP")] // more - SIM, AKA, PWD ? } Controls.Label { - visible: authComboBox.visible + visible: securityCombobox.currentIndex !== 3 && securityCombobox.currentIndex !== 0 text: "----Not yet implemented----" color: "red" } Kirigami.Separator { Kirigami.FormData.label: i18n("IP settings") Kirigami.FormData.isSection: true } Controls.ComboBox { - id: ipMethodComb - width: parent.width + id: ipMethodCombobox model: [i18n("Automatic"), i18n("Manual")] + currentIndex: ipSettings["method"] === "manual" ? 1 : 0 + property var manualIp: currentIndex === 1 onCurrentIndexChanged: { - manualIp = currentIndex == 1 - - if (manualIp) { - ipmap = { - "method": "manual", - "address": address, - "prefix": prefix, - "gateway": gateway, - "dns": dns - } - } else { - ipmap = {"method": "auto"} - } + ipSettings["method"] = currentIndex === 1 ? "manual" : "auto" } } Controls.TextField { id: manualIPaddress - visible: manualIp Kirigami.FormData.label: i18n("IP Address:") - placeholderText: "193.168.1.128" - text: address + visible: ipMethodCombobox.manualIp + placeholderText: "192.168.1.128" + text: ipSettings["address"] ? ipSettings["address"] : "" + onTextChanged: ipSettings["address"] = text validator: RegExpValidator { regExp: ipRegex } } Controls.TextField { id: manualIPgateway - visible: manualIp Kirigami.FormData.label: i18n("Gateway:") + visible: ipMethodCombobox.manualIp placeholderText: "192.168.1.1" - text: gateway + text: ipSettings["gateway"] ? ipSettings["gateway"] : "" + onTextChanged: ipSettings["gateway"] = text validator: RegExpValidator { regExp: ipRegex } } Controls.TextField { id: manualIPprefix - visible: manualIp Kirigami.FormData.label: i18n("Network prefix length:") - placeholderText: "32" - text: prefix - validator: IntValidator { bottom: 1; top: 32; } + visible: ipMethodCombobox.manualIp + placeholderText: "16" + text: ipSettings["prefix"] ? ipSettings["prefix"] : "" + onTextChanged: ipSettings["prefix"] = text + validator: IntValidator { + bottom: 1 + top: 32 + } } Controls.TextField { id: manualIPdns - visible: manualIp Kirigami.FormData.label: i18n("DNS:") + visible: ipMethodCombobox.manualIp placeholderText: "8.8.8.8" - text: dns + text: ipSettings["dns"] ? ipSettings["dns"] : "" + onTextChanged: ipSettings["dns"] = text validator: RegExpValidator { regExp: ipRegex } } - } - function setStateFromMap() { - - if (!ipmap) - return; - if (ipmap["method"] === "auto") - ipMethodComb.currentIndex = 0 - if (ipmap["method"] === "manual"){ - address = ipmap["address"]; - gateway = ipmap["gateway"]; - prefix = ipmap["prefix"]; - dns = ipmap["dns"]; - ipMethodComb.currentIndex = 1 - } - - var x = securityMap["key-mgmt"] - switch (x) { - case "none": - securityCombobox.currentIndex = 0 - break; - case "ieee8021x": - securityCombobox.currentIndex = 1 - break; - case "wpa-psk": - securityCombobox.currentIndex = 3 - break; - case "wpa-eap": - securityCombobox.currentIndex = 4 - break; - default: - securityCombobox.currentIndex = -1 - break; - } - wepWpaPasswordField.placeholderText = i18n("(Unchanged)") - securityCombobox.enabled = false - } + Component.onCompleted: { + wirelessSettings = kcm.getConnectionSettings(path, "802-11-wireless") + securitySettings = kcm.getConnectionSettings(path, "802-11-wireless-security") + ipSettings = kcm.getConnectionSettings(path, "ipv4") + secrets = kcm.getConnectionSettings(path, "secrets") - states: [ - State { - name: PlasmaNM.Enums.NoneSecurity - PropertyChanges { - target: securitySectionView; securityMap: {"type" : PlasmaNM.Enums.NoneSecurity } - } - }, - State { - name: PlasmaNM.Enums.StaticWep - PropertyChanges { - target: securitySectionView; securityMap: { "type" : PlasmaNM.Enums.StaticWep, - "password" : password - } - } - }, - State { - name: PlasmaNM.Enums.Wpa2Psk - PropertyChanges { - target: securitySectionView; securityMap: { "type" : PlasmaNM.Enums.Wpa2Psk, - "password" : password - } - } + if (path) { + detailsName.text = wirelessSettings["ssid"] } - ] - Component.onCompleted: { - settings = kcm.getConnectionSettings(path,"connection"); - detailsName.text = settings["id"] - securityMap = kcm.getConnectionSettings(path, "802-11-wireless-security"); - ipmap = kcm.getConnectionSettings(path,"ipv4"); - setStateFromMap(); + securityTypesModel.load() } function save() { - settings = ipmap; - if (password !== "") { //otherwise password is unchanged - settings["802-11-wireless-security"] = detailsSecuritySection.securityMap; - } - kcm.updateConnectionFromQML(path,settings); + var settings = ipSettings + settings["mode"] = "infrastructure" + securitySettings["type"] = securityTypesModel.get(securityCombobox.currentIndex).type + settings["802-11-wireless-security"] = securitySettings + + if (path) + kcm.updateConnectionFromQML(path, settings) + else + kcm.addConnectionFromQML(settings) } } diff --git a/mobile/wifi/package/contents/ui/main.qml b/mobile/wifi/package/contents/ui/main.qml index cfb68907..6150da46 100644 --- a/mobile/wifi/package/contents/ui/main.qml +++ b/mobile/wifi/package/contents/ui/main.qml @@ -1,128 +1,128 @@ /* * Copyright 2017 Martin Kacej * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.6 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.2 as Controls import org.kde.plasma.networkmanagement 0.2 as PlasmaNM import org.kde.kirigami 2.10 as Kirigami import org.kde.kcm 1.2 ScrollViewKCM { id: main PlasmaNM.Handler { id: handler } PlasmaNM.EnabledConnections { id: enabledConnections onWirelessEnabledChanged: { wifiSwitchButton.checked = wifiSwitchButton.enabled && enabled } } PlasmaNM.NetworkModel { id: connectionModel } PlasmaNM.MobileProxyModel { id: mobileProxyModel sourceModel: connectionModel showSavedMode: false } Component.onCompleted: handler.requestScan() Timer { id: scanTimer interval: 10200 repeat: true running: parent.visible onTriggered: handler.requestScan() } header: Kirigami.InlineMessage { id: inlineError showCloseButton: true type: Kirigami.MessageType.Warning Connections { target: handler onConnectionActivationFailed: { inlineError.text = message; inlineError.visible = true; } } } view: ListView { id: view clip: true currentIndex: -1 boundsBehavior: Flickable.StopAtBounds section.property: "Section" section.delegate: Kirigami.ListSectionHeader { text: section } model: mobileProxyModel delegate: ConnectionItemDelegate {} } actions.main: Kirigami.Action { iconName: enabledConnections.wirelessEnabled ? "network-wireless-disconnected" : "network-wireless-connected" text: enabledConnections.wirelessEnabled ? i18n("Disable Wi-Fi") : i18n("Enable Wi-Fi") onTriggered: handler.enableWireless(!enabledConnections.wirelessEnabled); } actions.contextualActions: [ Kirigami.Action { iconName: "edit" text: i18n("Add custom connection") onTriggered: { - kcm.push("ConnectionEditor.qml") + kcm.push("NetworkSettings.qml") contextDrawer.close() } }, Kirigami.Action { iconName: "edit" text: i18n("Create Hotspot") onTriggered: { kcm.push("TetheringSetting.qml") contextDrawer.close() } }, Kirigami.Action { iconName: "edit" text: i18n("Saved Connections") checkable: true checked: false onTriggered: { mobileProxyModel.showSavedMode = !mobileProxyModel.showSavedMode } } ] } diff --git a/mobile/wifi/wifisettings.cpp b/mobile/wifi/wifisettings.cpp index 0b5def9d..e9f08677 100644 --- a/mobile/wifi/wifisettings.cpp +++ b/mobile/wifi/wifisettings.cpp @@ -1,302 +1,305 @@ /* * Copyright 2018 Martin Kacej * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "wifisettings.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_CLASS_WITH_JSON(WifiSettings, "wifisettings.json") WifiSettings::WifiSettings(QObject* parent, const QVariantList& args) : KQuickAddons::ConfigModule(parent, args) { KAboutData* about = new KAboutData("kcm_mobile_wifi", i18n("Wi-Fi networks"), "0.1", QString(), KAboutLicense::LGPL); about->addAuthor(i18n("Martin Kacej"), QString(), "m.kacej@atlas.sk"); setAboutData(about); } WifiSettings::~WifiSettings() { } QVariantMap WifiSettings::getConnectionSettings(const QString &connection, const QString &type) { if (type.isEmpty()) return QVariantMap(); NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection); if (!con) return QVariantMap(); + if (type == "secrets") + return con->secrets(QLatin1String("802-11-wireless-security")).value().value(QLatin1String("802-11-wireless-security")); + QVariantMap map = con->settings()->toMap().value(type); if (type == "ipv4") { NetworkManager::Ipv4Setting::Ptr ipSettings = NetworkManager::Ipv4Setting::Ptr(new NetworkManager::Ipv4Setting()); ipSettings->fromMap(map); map.clear(); if (ipSettings->method() == NetworkManager::Ipv4Setting::Automatic) { map.insert(QLatin1String("method"),QVariant(QLatin1String("auto"))); } if (ipSettings->method() == NetworkManager::Ipv4Setting::Manual) { map.insert(QLatin1String("method"),QVariant(QLatin1String("manual"))); map.insert(QLatin1String("address"),QVariant(ipSettings->addresses().first().ip().toString())); - map.insert(QLatin1String("prefix"),QVariant(ipSettings->addresses().first().netmask().toString())); + map.insert(QLatin1String("prefix"),QVariant(ipSettings->addresses().first().prefixLength())); map.insert(QLatin1String("gateway"),QVariant(ipSettings->addresses().first().gateway().toString())); map.insert(QLatin1String("dns"),QVariant(ipSettings->dns().first().toString())); } } return map; } QVariantMap WifiSettings::getActiveConnectionInfo(const QString &connection) { if (connection.isEmpty()) return QVariantMap(); NetworkManager::ActiveConnection::Ptr activeCon; NetworkManager::Connection::Ptr con = NetworkManager::findConnection(connection); foreach (const NetworkManager::ActiveConnection::Ptr &active, NetworkManager::activeConnections()) { if (active->uuid() == con->uuid()) activeCon = active; } if (!activeCon) { qWarning() << "Active" << connection << "not found"; return QVariantMap(); } QVariantMap map; if (activeCon->ipV4Config().addresses().count() > 0) { map.insert("address",QVariant(activeCon->ipV4Config().addresses().first().ip().toString())); map.insert("prefix",QVariant(activeCon->ipV4Config().addresses().first().netmask().toString())); } map.insert("gateway",QVariant(activeCon->ipV4Config().gateway())); if (activeCon->ipV4Config().nameservers().count() > 0) map.insert("dns",QVariant(activeCon->ipV4Config().nameservers().first().toString())); //qWarning() << map; return map; } void WifiSettings::addConnectionFromQML(const QVariantMap &QMLmap) { if (QMLmap.isEmpty()) return; NetworkManager::ConnectionSettings::Ptr connectionSettings = NetworkManager::ConnectionSettings::Ptr(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless)); connectionSettings->setId(QMLmap.value(QLatin1String("id")).toString()); connectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); NetworkManager::WirelessSetting::Ptr wirelessSettings = NetworkManager::WirelessSetting::Ptr(new NetworkManager::WirelessSetting()); wirelessSettings->setSsid(QMLmap.value(QLatin1String("id")).toString().toUtf8()); if (QMLmap["mode"].toString() == "infrastructure") { wirelessSettings->setMode(NetworkManager::WirelessSetting::Infrastructure); connectionSettings->setAutoconnect(true); } if (QMLmap["mode"].toString() == "ap") { wirelessSettings->setMode(NetworkManager::WirelessSetting::Ap); connectionSettings->setAutoconnect(false); } if (QMLmap.contains("hidden")) { wirelessSettings->setHidden(QMLmap.value("hidden").toBool()); } NetworkManager::Ipv4Setting::Ptr ipSettings = NetworkManager::Ipv4Setting::Ptr(new NetworkManager::Ipv4Setting()); if (QMLmap["method"] == QLatin1String("auto")) { ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Automatic); } if (QMLmap["method"] == QLatin1String("shared")) { ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Shared); } if (QMLmap["method"] == QLatin1String("manual")) { ipSettings->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Manual); NetworkManager::IpAddress ipaddr; ipaddr.setIp(QHostAddress(QMLmap["address"].toString())); ipaddr.setPrefixLength(QMLmap["prefix"].toInt()); ipaddr.setGateway(QHostAddress(QMLmap["gateway"].toString())); ipSettings->setAddresses(QList({ipaddr})); ipSettings->setDns(QList({QHostAddress(QMLmap["dns"].toString())})); } NMVariantMapMap map = connectionSettings->toMap(); map.insert("802-11-wireless",wirelessSettings->toMap()); map.insert("ipv4",ipSettings->toMap()); // TODO can't set password for AP // needs further inspection if (QMLmap.contains("802-11-wireless-security")) { QVariantMap securMap = QMLmap["802-11-wireless-security"].toMap(); int type = securMap["type"].toInt(); if (!type == NetworkManager::NoneSecurity) { NetworkManager::WirelessSecuritySetting::Ptr securitySettings = NetworkManager::WirelessSecuritySetting::Ptr(new NetworkManager::WirelessSecuritySetting()); if (type == NetworkManager::Wpa2Psk ) { if (QMLmap["mode"].toString() == "ap") { securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaNone); } else { securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::WpaPsk); } securitySettings->setAuthAlg(NetworkManager::WirelessSecuritySetting::AuthAlg::Open); securitySettings->setPskFlags(NetworkManager::Setting::SecretFlagType::AgentOwned); securitySettings->setPsk(securMap["password"].toString()); } if (type == NetworkManager::StaticWep) { securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::Wep); securitySettings->setAuthAlg(NetworkManager::WirelessSecuritySetting::AuthAlg::Open); securitySettings->setWepKeyType(NetworkManager::WirelessSecuritySetting::WepKeyType::Hex); securitySettings->setWepKeyFlags(NetworkManager::Setting::SecretFlagType::AgentOwned); securitySettings->setWepKey0(securMap["password"].toString()); } map.insert("802-11-wireless-security",securitySettings->toMap()); } } //qWarning() << map; NetworkManager::addConnection(map); } void WifiSettings::updateConnectionFromQML(const QString &path, const QVariantMap &map) { NetworkManager::Connection::Ptr con = NetworkManager::findConnection(path); if (!con) return; //qWarning() << map; if (map.contains("id")) con->settings()->setId(map.value("id").toString()); NMVariantMapMap toUpdateMap = con->settings()->toMap(); NetworkManager::Ipv4Setting::Ptr ipSetting = con->settings()->setting(NetworkManager::Setting::Ipv4).staticCast(); if (ipSetting->method() == NetworkManager::Ipv4Setting::Automatic || ipSetting->method() == NetworkManager::Ipv4Setting::Manual) { if (map.value("method") == "auto") { ipSetting->setMethod(NetworkManager::Ipv4Setting::Automatic); } if (map.value("method") == "manual") { ipSetting->setMethod(NetworkManager::Ipv4Setting::ConfigMethod::Manual); NetworkManager::IpAddress ipaddr; ipaddr.setIp(QHostAddress(map["address"].toString())); ipaddr.setPrefixLength(map["prefix"].toInt()); ipaddr.setGateway(QHostAddress(map["gateway"].toString())); ipSetting->setAddresses(QList({ipaddr})); ipSetting->setDns(QList({QHostAddress(map["dns"].toString())})); } toUpdateMap.insert("ipv4",ipSetting->toMap()); } NetworkManager::WirelessSetting::Ptr wirelessSetting = con->settings()->setting(NetworkManager::Setting::Wireless).staticCast(); if (map.contains("hidden")) { wirelessSetting->setHidden(map.value("hidden").toBool()); } if (map.contains("id")) { wirelessSetting->setSsid(map.value("id").toByteArray()); } toUpdateMap.insert("802-11-wireless",wirelessSetting->toMap()); if (map.contains("802-11-wireless-security")) { QVariantMap secMap = map.value("802-11-wireless-security").toMap(); //qWarning() << secMap; NetworkManager::WirelessSecuritySetting::Ptr securitySetting = con->settings()->setting(NetworkManager::Setting::WirelessSecurity).staticCast(); if ((securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::Wep) && (secMap.value("type") == NetworkManager::StaticWep)) { securitySetting->setWepKey0(secMap["password"].toString()); } if ((securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaPsk) && (secMap.value("type") == NetworkManager::Wpa2Psk)) { securitySetting->setPsk(secMap["password"].toString()); } // TODO can't set password for AP // needs further inspection if (wirelessSetting->mode() == NetworkManager::WirelessSetting::Ap) { if (securitySetting->toMap().empty()) { //no security if (secMap.value("type") == NetworkManager::Wpa2Psk) { securitySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaNone); securitySetting->setPsk(secMap.value("password").toString()); } } if (securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::WpaNone) { if (secMap.empty()) { securitySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::Unknown); } if (secMap.value("type") == NetworkManager::Wpa2Psk) { securitySetting->setPsk(secMap.value("password").toString()); } } } toUpdateMap.insert("802-11-wireless-security",securitySetting->toMap()); } qWarning() << toUpdateMap; con->update(toUpdateMap); } QString WifiSettings::getAccessPointDevice() { NetworkManager::WirelessDevice::Ptr device; foreach (const NetworkManager::Device::Ptr &dev, NetworkManager::networkInterfaces()) { if (dev->type() == NetworkManager::Device::Wifi){ device = dev.staticCast(); if (device->wirelessCapabilities().testFlag(NetworkManager::WirelessDevice::ApCap)) break; // we have wireless device with access point capability } } if (device) { return device->uni(); } else { qWarning() << "No wireless device found"; } return QString(); } QString WifiSettings::getAccessPointConnection() { foreach (const NetworkManager::Connection::Ptr &con, NetworkManager::listConnections()) { NetworkManager::Setting::Ptr d = con->settings()->setting(NetworkManager::Setting::Wireless); if (!d.isNull()){ if( d.staticCast()->mode() == NetworkManager::WirelessSetting::Ap){ return con->path(); } } } return QString(); } #include "wifisettings.moc"