mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
Move back wifi kcm to plasma-nm
This commit is contained in:
parent
93ca04deb7
commit
9a35cca1b6
13 changed files with 0 additions and 1351 deletions
|
|
@ -8,4 +8,3 @@ add_subdirectory(powermanagement)
|
||||||
add_subdirectory(time)
|
add_subdirectory(time)
|
||||||
add_subdirectory(virtualkeyboard)
|
add_subdirectory(virtualkeyboard)
|
||||||
add_subdirectory(hotspot)
|
add_subdirectory(hotspot)
|
||||||
add_subdirectory(wifi)
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
|
|
||||||
# SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
kcmutils_add_qml_kcm(kcm_mobile_wifi SOURCES wifisettings.cpp)
|
|
||||||
target_link_libraries(kcm_mobile_wifi PRIVATE
|
|
||||||
Qt::DBus
|
|
||||||
Qt::Gui
|
|
||||||
Qt::Quick
|
|
||||||
Qt::Qml
|
|
||||||
KF6::I18n
|
|
||||||
KF6::NetworkManagerQt
|
|
||||||
Plasma::Plasma
|
|
||||||
KF6::KCMUtilsQuick
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
|
|
||||||
# SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
$XGETTEXT `find . -name \*.cpp -o -name \*.qml` -o $podir/kcm_mobile_wifi.pot
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
{
|
|
||||||
"Categories": "Qt;KDE;X-KDE-settings-system;",
|
|
||||||
"KPlugin": {
|
|
||||||
"Description": "Wireless network setting",
|
|
||||||
"Description[ar]": "إعدادات الشبكة اللاسلكية",
|
|
||||||
"Description[ca@valencia]": "Configureu la xarxa sense fil",
|
|
||||||
"Description[ca]": "Configuració de la xarxa sense fil",
|
|
||||||
"Description[cs]": "Nastavení bezdrátové sítě",
|
|
||||||
"Description[de]": "Einstellungen für drahtloses Netzwerk",
|
|
||||||
"Description[en_GB]": "Wireless network setting",
|
|
||||||
"Description[eo]": "Agordo de sendrata reto",
|
|
||||||
"Description[es]": "Preferencias de la red inalámbrica",
|
|
||||||
"Description[eu]": "Haririk gabeko sare ezarpena",
|
|
||||||
"Description[fi]": "Langattoman verkon asetukset",
|
|
||||||
"Description[fr]": "Configuration des réseaux sans fil",
|
|
||||||
"Description[gl]": "Configuración das redes sen fíos.",
|
|
||||||
"Description[he]": "הגדרות רשת אלחוטית",
|
|
||||||
"Description[hu]": "Vezeték nélküli hálózati beállítások",
|
|
||||||
"Description[ia]": "Preferentia de rete sin cablos",
|
|
||||||
"Description[is]": "Stillingar á þráðlausu neti",
|
|
||||||
"Description[it]": "Impostazioni rete senza fili",
|
|
||||||
"Description[ka]": "უსადენო ქსელის მორგება",
|
|
||||||
"Description[ko]": "무선 네트워크 설정",
|
|
||||||
"Description[lv]": "Bezvadu tīkla iestatījumi",
|
|
||||||
"Description[nl]": "Instelling van draadloos netwerk",
|
|
||||||
"Description[nn]": "Innstilling for trådlaust nettverk",
|
|
||||||
"Description[pa]": "ਬੇਤਾਰ ਨੈੱਟਵਰਕ ਸੈਟਿੰਗ",
|
|
||||||
"Description[pl]": "Ustawienia sieci bezprzewodowej",
|
|
||||||
"Description[pt_BR]": "Configurações da rede sem fio",
|
|
||||||
"Description[ru]": "Настройка беспроводной сети",
|
|
||||||
"Description[sa]": "वायरलेस नेटवर्क सेटिंग्",
|
|
||||||
"Description[sk]": "Nastavenie bezdrôtovej siete",
|
|
||||||
"Description[sl]": "Nastavitve brezžičnega omrežja",
|
|
||||||
"Description[sv]": "Inställning av trådlöst nätverk",
|
|
||||||
"Description[ta]": "கம்பியில்லா பிணையத்திற்கான அமைப்புகள்",
|
|
||||||
"Description[tr]": "Kablosuz ağ ayarı",
|
|
||||||
"Description[uk]": "Налаштовування бездротової мережі",
|
|
||||||
"Description[x-test]": "xxWireless network settingxx",
|
|
||||||
"Description[zh_CN]": "无线网络设置",
|
|
||||||
"Description[zh_TW]": "無線網路設定",
|
|
||||||
"FormFactors": [
|
|
||||||
"handset",
|
|
||||||
"tablet",
|
|
||||||
"mediacenter"
|
|
||||||
],
|
|
||||||
"Icon": "network-wireless-symbolic",
|
|
||||||
"Name": "Wi-Fi",
|
|
||||||
"Name[ar]": "واي فاي",
|
|
||||||
"Name[ast]": "Wi-Fi",
|
|
||||||
"Name[az]": "Wi-Fi",
|
|
||||||
"Name[ca@valencia]": "Wi-Fi",
|
|
||||||
"Name[ca]": "Wi-Fi",
|
|
||||||
"Name[cs]": "Wi-Fi",
|
|
||||||
"Name[de]": "WLAN",
|
|
||||||
"Name[en_GB]": "Wi-Fi",
|
|
||||||
"Name[eo]": "Wifi",
|
|
||||||
"Name[es]": "Wifi",
|
|
||||||
"Name[eu]": "Wi-Fi",
|
|
||||||
"Name[fi]": "Langaton verkko",
|
|
||||||
"Name[fr]": "Wi-Fi",
|
|
||||||
"Name[gl]": "Redes sen fíos",
|
|
||||||
"Name[he]": "רשת אלחוטית",
|
|
||||||
"Name[hu]": "Wi-Fi",
|
|
||||||
"Name[ia]": "Wi-Fi",
|
|
||||||
"Name[is]": "Wi-Fi",
|
|
||||||
"Name[it]": "Wi-Fi",
|
|
||||||
"Name[ka]": "Wi-Fi",
|
|
||||||
"Name[ko]": "Wi-Fi",
|
|
||||||
"Name[lv]": "Wi-Fi",
|
|
||||||
"Name[nl]": "Wi-Fi",
|
|
||||||
"Name[nn]": "Wi-Fi",
|
|
||||||
"Name[pa]": "ਵਾਈ-ਫਾਈ",
|
|
||||||
"Name[pl]": "Wi-Fi",
|
|
||||||
"Name[pt]": "Wi-Fi",
|
|
||||||
"Name[pt_BR]": "Wi-Fi",
|
|
||||||
"Name[ro]": "Wi-Fi",
|
|
||||||
"Name[ru]": "Wi-Fi",
|
|
||||||
"Name[sa]": "वाई-फाई",
|
|
||||||
"Name[sk]": "Wi-Fi",
|
|
||||||
"Name[sl]": "Wi-Fi",
|
|
||||||
"Name[sv]": "Wifi",
|
|
||||||
"Name[ta]": "அருகலை",
|
|
||||||
"Name[tr]": "Wi-Fi",
|
|
||||||
"Name[uk]": "Wi-Fi",
|
|
||||||
"Name[x-test]": "xxWi-Fixx",
|
|
||||||
"Name[zh_CN]": "Wi-Fi",
|
|
||||||
"Name[zh_TW]": "Wi-Fi"
|
|
||||||
},
|
|
||||||
"X-KDE-Keywords": "wifi,network",
|
|
||||||
"X-KDE-Keywords[ca@valencia]": "wifi,wi-fi,xarxa",
|
|
||||||
"X-KDE-Keywords[ca]": "wifi,wi-fi,xarxa",
|
|
||||||
"X-KDE-Keywords[cs]": "wifi,síť",
|
|
||||||
"X-KDE-Keywords[en_GB]": "wifi,network",
|
|
||||||
"X-KDE-Keywords[es]": "wifi,red",
|
|
||||||
"X-KDE-Keywords[eu]": "wifi,sarea",
|
|
||||||
"X-KDE-Keywords[fi]": "wifi,wlan,langaton verkko,verkko",
|
|
||||||
"X-KDE-Keywords[fr]": "wifi, réseau",
|
|
||||||
"X-KDE-Keywords[gl]": "sen fíos,wifi,rede",
|
|
||||||
"X-KDE-Keywords[he]": "רשת אלחוטית,רשת,תקשורת",
|
|
||||||
"X-KDE-Keywords[hu]": "wifi,hálózat",
|
|
||||||
"X-KDE-Keywords[ia]": "wifi,network",
|
|
||||||
"X-KDE-Keywords[it]": "wifi,rete",
|
|
||||||
"X-KDE-Keywords[ka]": "wifi,network, ქსელი",
|
|
||||||
"X-KDE-Keywords[ko]": "wifi,network,네트워크,무선,와이파이",
|
|
||||||
"X-KDE-Keywords[lv]": "wifi,tīkls",
|
|
||||||
"X-KDE-Keywords[nl]": "wifi,netwerk",
|
|
||||||
"X-KDE-Keywords[nn]": "wifi,nettverk,trådlaust",
|
|
||||||
"X-KDE-Keywords[pl]": "wifi,sieć",
|
|
||||||
"X-KDE-Keywords[ru]": "wifi,network,wi-fi,сеть",
|
|
||||||
"X-KDE-Keywords[sa]": "wifi,जालम्",
|
|
||||||
"X-KDE-Keywords[sl]": "wifi,omrežje",
|
|
||||||
"X-KDE-Keywords[sv]": "wifi,nätverk",
|
|
||||||
"X-KDE-Keywords[tr]": "wifi,wi-fi,ağ",
|
|
||||||
"X-KDE-Keywords[uk]": "wifi,network,вайфай,мережа",
|
|
||||||
"X-KDE-Keywords[x-test]": "xxwifixx,xxnetworkxx",
|
|
||||||
"X-KDE-Keywords[zh_CN]": "wifi,network,wangluo,wuxian,网络,无线",
|
|
||||||
"X-KDE-Keywords[zh_TW]": "網路,無線網路",
|
|
||||||
"X-KDE-System-Settings-Parent-Category": "network",
|
|
||||||
"X-KDE-Weight": 70
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2020-2024 Devin Lin <espidev@gmail.com>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick 2.6
|
|
||||||
import QtQuick.Layouts 1.2
|
|
||||||
import QtQuick.Controls 2.2 as Controls
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
|
|
||||||
Kirigami.PromptDialog {
|
|
||||||
id: dialogRoot
|
|
||||||
title: headingText
|
|
||||||
|
|
||||||
property int securityType
|
|
||||||
property string headingText
|
|
||||||
property string devicePath
|
|
||||||
property string specificPath
|
|
||||||
|
|
||||||
signal donePressed(string password)
|
|
||||||
|
|
||||||
function openAndClear() {
|
|
||||||
warning.visible = false;
|
|
||||||
this.open();
|
|
||||||
passwordField.text = "";
|
|
||||||
passwordField.focus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
standardButtons: Controls.Dialog.Ok | Controls.Dialog.Cancel
|
|
||||||
|
|
||||||
onOpened: passwordField.forceActiveFocus()
|
|
||||||
onRejected: {
|
|
||||||
dialogRoot.close();
|
|
||||||
passwordField.focus = false;
|
|
||||||
}
|
|
||||||
onAccepted: {
|
|
||||||
if (passwordField.acceptableInput) {
|
|
||||||
dialogRoot.close();
|
|
||||||
handler.addAndActivateConnection(devicePath, specificPath, passwordField.text);
|
|
||||||
} else {
|
|
||||||
warning.visible = true;
|
|
||||||
}
|
|
||||||
passwordField.focus = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: column
|
|
||||||
spacing: Kirigami.Units.largeSpacing
|
|
||||||
|
|
||||||
PasswordField {
|
|
||||||
id: passwordField
|
|
||||||
Layout.fillWidth: true
|
|
||||||
securityType: dialogRoot.securityType
|
|
||||||
onAccepted: dialogRoot.accept()
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.Label {
|
|
||||||
id: warning
|
|
||||||
text: i18n("Invalid input.")
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2024 Sebastian Kügler <sebas@kde.org>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Controls as Controls
|
|
||||||
import org.kde.coreaddons as KCoreAddons
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
|
||||||
|
|
||||||
|
|
||||||
FormCard.FormCardPage {
|
|
||||||
id: connectionInfo
|
|
||||||
title: i18nc("kcm page title", "Connection Info for \"%1\"", connectionName)
|
|
||||||
|
|
||||||
property string connectionName: ""
|
|
||||||
property var details: []
|
|
||||||
property QtObject delegate: null // for reaching rx/txSpeed
|
|
||||||
|
|
||||||
FormCard.FormHeader {
|
|
||||||
title: i18nc("@title:group", "Transfer Rates")
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
padding: Math.round(Kirigami.Units.gridUnit / 2)
|
|
||||||
|
|
||||||
TrafficMonitor {
|
|
||||||
id: trafficMonitorGraph
|
|
||||||
width: parent.width
|
|
||||||
downloadSpeed: delegate.rxSpeed
|
|
||||||
uploadSpeed: delegate.txSpeed
|
|
||||||
}
|
|
||||||
Controls.Label {
|
|
||||||
font: Kirigami.Theme.smallFont
|
|
||||||
horizontalAlignment: Text.AlignRight
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: i18n("Connected, ↓ %1/s, ↑ %2/s",
|
|
||||||
KCoreAddons.Format.formatByteSize(delegate.rxSpeed),
|
|
||||||
KCoreAddons.Format.formatByteSize(delegate.txSpeed))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormHeader {
|
|
||||||
title: i18nc("@title:group", "Connection Details")
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
Repeater {
|
|
||||||
/* details is the ConnectionDetails property of the
|
|
||||||
* connection model item, a flat stringlist with
|
|
||||||
* title / value pairs.
|
|
||||||
*/
|
|
||||||
model: details.length / 2
|
|
||||||
|
|
||||||
FormCard.FormTextDelegate {
|
|
||||||
text: details[index * 2]
|
|
||||||
description: details[(index * 2) + 1]
|
|
||||||
enabled: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2017 Martin Kacej <m.kacej@atlas.sk>
|
|
||||||
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Window
|
|
||||||
import QtQuick.Controls as Controls
|
|
||||||
|
|
||||||
import org.kde.plasma.networkmanagement as PlasmaNM
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.ksvg as KSvg
|
|
||||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
|
||||||
|
|
||||||
FormCard.AbstractFormDelegate {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool editMode
|
|
||||||
property var map : []
|
|
||||||
property bool predictableWirelessPassword: !Uuid && Type == PlasmaNM.Enums.Wireless &&
|
|
||||||
(SecurityType == PlasmaNM.Enums.StaticWep ||
|
|
||||||
SecurityType == PlasmaNM.Enums.WpaPsk ||
|
|
||||||
SecurityType == PlasmaNM.Enums.Wpa2Psk ||
|
|
||||||
SecurityType == PlasmaNM.Enums.SAE)
|
|
||||||
property real rxSpeed: 0
|
|
||||||
property real txSpeed: 0
|
|
||||||
|
|
||||||
verticalPadding: Kirigami.Units.largeSpacing
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: timer
|
|
||||||
repeat: true
|
|
||||||
interval: 2000
|
|
||||||
running: ConnectionState === PlasmaNM.Enums.Activated
|
|
||||||
triggeredOnStart: true
|
|
||||||
// property int can overflow with the amount of bytes.
|
|
||||||
property double prevRxBytes: 0
|
|
||||||
property double prevTxBytes: 0
|
|
||||||
onTriggered: {
|
|
||||||
rxSpeed = prevRxBytes === 0 ? 0 : (RxBytes - prevRxBytes) * 1000 / interval
|
|
||||||
txSpeed = prevTxBytes === 0 ? 0 : (TxBytes - prevTxBytes) * 1000 / interval
|
|
||||||
prevRxBytes = RxBytes
|
|
||||||
prevTxBytes = TxBytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: RowLayout {
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.rightMargin: Kirigami.Units.gridUnit
|
|
||||||
implicitWidth: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
implicitHeight: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
|
|
||||||
Kirigami.Icon {
|
|
||||||
implicitWidth: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
implicitHeight: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
visible: ConnectionState !== PlasmaNM.Enums.Activating
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: mobileProxyModel.showSavedMode ? "network-wireless-connected-100" : ConnectionIcon
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.BusyIndicator {
|
|
||||||
anchors.fill: parent
|
|
||||||
running: ConnectionState === PlasmaNM.Enums.Activating
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.Label {
|
|
||||||
id: internalTextItem
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: ItemUniqueName
|
|
||||||
elide: Text.ElideRight
|
|
||||||
font.bold: ConnectionState === PlasmaNM.Enums.Activated
|
|
||||||
Accessible.ignored: true // base class sets this text on root already
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Kirigami.Icon {
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium
|
|
||||||
visible: ConnectionState === PlasmaNM.Enums.Activated
|
|
||||||
source: 'checkmark'
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure that the row is always of same height
|
|
||||||
Controls.ToolButton {
|
|
||||||
id: heightMetrics
|
|
||||||
opacity: 0
|
|
||||||
implicitWidth: 0
|
|
||||||
icon.name: 'network-connect'
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
icon.name: "network-connect"
|
|
||||||
text: i18n('Connect')
|
|
||||||
visible: ConnectionState != PlasmaNM.Enums.Activated && root.editMode
|
|
||||||
display: Controls.ToolButton.IconOnly
|
|
||||||
onClicked: changeState()
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
icon.name: "network-disconnect"
|
|
||||||
text: i18n('Disconnect')
|
|
||||||
visible: ConnectionState == PlasmaNM.Enums.Activated && root.editMode
|
|
||||||
display: Controls.ToolButton.IconOnly
|
|
||||||
onClicked: handler.deactivateConnection(ConnectionPath, DevicePath)
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
icon.name: "configure"
|
|
||||||
text: i18n('Configure')
|
|
||||||
visible: (Uuid != "") && root.editMode
|
|
||||||
display: Controls.ToolButton.IconOnly
|
|
||||||
onClicked: {
|
|
||||||
kcm.push("NetworkSettings.qml", {path: ConnectionPath})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
icon.name: "entry-delete"
|
|
||||||
text: i18n('Delete')
|
|
||||||
visible: (Uuid != "") && root.editMode
|
|
||||||
display: Controls.ToolButton.IconOnly
|
|
||||||
onClicked: handler.removeConnection(ConnectionPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
changeState()
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeState() {
|
|
||||||
if (Uuid || !predictableWirelessPassword) {
|
|
||||||
if (ConnectionState == PlasmaNM.Enums.Deactivated) {
|
|
||||||
if (!predictableWirelessPassword && !Uuid) {
|
|
||||||
handler.addAndActivateConnection(DevicePath, SpecificPath);
|
|
||||||
} else {
|
|
||||||
handler.activateConnection(ConnectionPath, DevicePath, SpecificPath);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kcm.push("ConnectionInfo.qml", {details: ConnectionDetails,
|
|
||||||
connectionName: ItemUniqueName,
|
|
||||||
delegate: root})
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (predictableWirelessPassword) {
|
|
||||||
connectionDialog.headingText = i18n("Connect to") + " " + ItemUniqueName;
|
|
||||||
connectionDialog.devicePath = DevicePath;
|
|
||||||
connectionDialog.specificPath = SpecificPath;
|
|
||||||
connectionDialog.securityType = SecurityType;
|
|
||||||
connectionDialog.openAndClear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,283 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2017 Martin Kacej <m.kacej@atlas.sk>
|
|
||||||
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Controls as Controls
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.plasma.networkmanagement as PlasmaNM
|
|
||||||
import org.kde.kcmutils
|
|
||||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
|
||||||
title: path ? wirelessSettings["ssid"] : i18n("Add New Connection")
|
|
||||||
|
|
||||||
property var path
|
|
||||||
|
|
||||||
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: (ipMethodCombobox.currentIndex == 0
|
|
||||||
|| (ipMethodCombobox.currentIndex == 1
|
|
||||||
&& manualIPaddress.acceptableInput
|
|
||||||
&& manualIPgateway.acceptableInput
|
|
||||||
&& manualIPprefix.acceptableInput
|
|
||||||
&& manualIPdns.acceptableInput))
|
|
||||||
|
|
||||||
actions: [
|
|
||||||
Kirigami.Action {
|
|
||||||
icon.name: "dialog-ok"
|
|
||||||
text: i18n("Save")
|
|
||||||
enabled: enabledSave
|
|
||||||
onTriggered: {
|
|
||||||
save()
|
|
||||||
kcm.pop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
topPadding: Kirigami.Units.gridUnit
|
|
||||||
bottomPadding: Kirigami.Units.gridUnit
|
|
||||||
leftPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
FormCard.FormHeader {
|
|
||||||
title: i18nc("@title:group", "General")
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: ssidField
|
|
||||||
label: i18n("SSID")
|
|
||||||
text: wirelessSettings["ssid"] ? wirelessSettings["ssid"] : ""
|
|
||||||
enabled: true
|
|
||||||
onTextChanged: {
|
|
||||||
ipSettings["id"] = text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: ssidField
|
|
||||||
below: hidden
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormSwitchDelegate {
|
|
||||||
id: hidden
|
|
||||||
text: i18n("Hidden Network")
|
|
||||||
checked: wirelessSettings["hidden"] ? wirelessSettings["hidden"] : false
|
|
||||||
onToggled: ipSettings["hidden"] = checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormHeader {
|
|
||||||
title: i18nc("@title:group", "Security")
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
FormCard.FormComboBoxDelegate {
|
|
||||||
id: securityCombobox
|
|
||||||
currentIndex: 0
|
|
||||||
text: i18n("Security type")
|
|
||||||
model: ListModel {
|
|
||||||
id: securityTypesModel
|
|
||||||
// FIXME just placeholder element to set "text" property as default
|
|
||||||
ListElement {
|
|
||||||
text: "placeholder"
|
|
||||||
}
|
|
||||||
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 });
|
|
||||||
append({ "text": i18n("WPA3 Personal"), "type": PlasmaNM.Enums.SAE });
|
|
||||||
append({ "text": i18n("WPA3 Enterprise"), "type": PlasmaNM.Enums.Wpa3SuiteB192 });
|
|
||||||
|
|
||||||
// See https://networkmanager.dev/docs/api/latest/settings-802-11-wireless-security.html
|
|
||||||
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;
|
|
||||||
case "sae":
|
|
||||||
securityCombobox.currentIndex = 5;
|
|
||||||
break;
|
|
||||||
case "wpa-eap-suite-b-192":
|
|
||||||
securityCombobox.currentIndex = 6;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
securityCombobox.currentIndex = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: securityCombobox
|
|
||||||
below: passwordDelegate
|
|
||||||
visible: passwordDelegate.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: passwordDelegate
|
|
||||||
label: i18n("Password")
|
|
||||||
echoMode: TextInput.Password
|
|
||||||
inputMethodHints: Qt.ImhHiddenText
|
|
||||||
text: secrets["psk"]
|
|
||||||
visible: securityTypesModel.get(securityCombobox.currentIndex).type !== PlasmaNM.Enums.NoneSecurity
|
|
||||||
onTextChanged: securitySettings["password"] = text
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: passwordDelegate
|
|
||||||
below: authComboBox
|
|
||||||
visible: authComboBox.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormComboBoxDelegate {
|
|
||||||
id: authComboBox
|
|
||||||
text: i18n("Authentication:")
|
|
||||||
currentIndex: 0
|
|
||||||
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: ![0, 3, 5].includes(securityCombobox.currentIndex) // only supports WPA PSK, SAE
|
|
||||||
text: "----Not yet implemented----"
|
|
||||||
color: "red"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormHeader {
|
|
||||||
title: i18nc("@title:group", "IP Settings")
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
FormCard.FormComboBoxDelegate {
|
|
||||||
id: ipMethodCombobox
|
|
||||||
text: i18n('Method')
|
|
||||||
model: [i18n("Automatic"), i18n("Manual")]
|
|
||||||
currentIndex: ipSettings["method"] === "manual" ? 1 : 0
|
|
||||||
property var manualIp: currentIndex === 1
|
|
||||||
onCurrentIndexChanged: {
|
|
||||||
ipSettings["method"] = currentIndex === 1 ? "manual" : "auto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: ipMethodCombobox
|
|
||||||
below: manualIPaddress
|
|
||||||
visible: manualIPaddress.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: manualIPaddress
|
|
||||||
label: i18n("IP Address")
|
|
||||||
visible: ipMethodCombobox.manualIp
|
|
||||||
placeholderText: "192.168.1.128"
|
|
||||||
text: ipSettings["address"] ? ipSettings["address"] : ""
|
|
||||||
onTextChanged: ipSettings["address"] = text
|
|
||||||
validator: RegularExpressionValidator {
|
|
||||||
regularExpression: ipRegex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: manualIPaddress
|
|
||||||
below: manualIPgateway
|
|
||||||
visible: manualIPgateway.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: manualIPgateway
|
|
||||||
label: i18n("Gateway")
|
|
||||||
visible: ipMethodCombobox.manualIp
|
|
||||||
placeholderText: "192.168.1.1"
|
|
||||||
text: ipSettings["gateway"] ? ipSettings["gateway"] : ""
|
|
||||||
onTextChanged: ipSettings["gateway"] = text
|
|
||||||
validator: RegularExpressionValidator {
|
|
||||||
regularExpression: ipRegex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: manualIPgateway
|
|
||||||
below: manualIPprefix
|
|
||||||
visible: manualIPprefix.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: manualIPprefix
|
|
||||||
label: i18n("Network prefix length")
|
|
||||||
visible: ipMethodCombobox.manualIp
|
|
||||||
placeholderText: "16"
|
|
||||||
text: ipSettings["prefix"] ? ipSettings["prefix"] : ""
|
|
||||||
onTextChanged: ipSettings["prefix"] = text
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
top: 32
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: manualIPprefix
|
|
||||||
below: manualIPdns
|
|
||||||
visible: manualIPdns.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: manualIPdns
|
|
||||||
label: i18n("DNS")
|
|
||||||
visible: ipMethodCombobox.manualIp
|
|
||||||
placeholderText: "8.8.8.8"
|
|
||||||
text: ipSettings["dns"] ? ipSettings["dns"] : ""
|
|
||||||
onTextChanged: ipSettings["dns"] = text
|
|
||||||
validator: RegularExpressionValidator {
|
|
||||||
regularExpression: ipRegex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
securityTypesModel.load()
|
|
||||||
}
|
|
||||||
|
|
||||||
function save() {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick 2.15
|
|
||||||
import org.kde.kirigami 2.10 as Kirigami
|
|
||||||
import org.kde.plasma.networkmanagement as PlasmaNM
|
|
||||||
|
|
||||||
Kirigami.PasswordField {
|
|
||||||
property int securityType
|
|
||||||
placeholderText: i18n("Password…")
|
|
||||||
validator: RegularExpressionValidator {
|
|
||||||
regularExpression: if (securityType == PlasmaNM.Enums.StaticWep) {
|
|
||||||
/^(?:.{5}|[0-9a-fA-F]{10}|.{13}|[0-9a-fA-F]{26}){1}$/
|
|
||||||
} else {
|
|
||||||
/^(?:.{8,64}){1}$/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
||||||
*/
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import org.kde.coreaddons as KCoreAddons
|
|
||||||
import org.kde.quickcharts as QuickCharts
|
|
||||||
import org.kde.quickcharts.controls as QuickChartsControls
|
|
||||||
import org.kde.plasma.components as PlasmaComponents3
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
property alias downloadSpeed: download.value
|
|
||||||
property alias uploadSpeed: upload.value
|
|
||||||
|
|
||||||
spacing: Kirigami.Units.largeSpacing
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: plotter.height + metricsLabel.implicitHeight
|
|
||||||
|
|
||||||
QuickChartsControls.AxisLabels {
|
|
||||||
id: verticalAxisLabels
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
top: plotter.top
|
|
||||||
bottom: plotter.bottom
|
|
||||||
}
|
|
||||||
width: metricsLabel.implicitWidth
|
|
||||||
constrainToBounds: false
|
|
||||||
direction: QuickChartsControls.AxisLabels.VerticalBottomTop
|
|
||||||
delegate: PlasmaComponents3.Label {
|
|
||||||
text: KCoreAddons.Format.formatByteSize(QuickChartsControls.AxisLabels.label) + i18n("/s")
|
|
||||||
font: metricsLabel.font
|
|
||||||
}
|
|
||||||
source: QuickCharts.ChartAxisSource {
|
|
||||||
chart: plotter
|
|
||||||
axis: QuickCharts.ChartAxisSource.YAxis
|
|
||||||
itemCount: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QuickChartsControls.GridLines {
|
|
||||||
anchors.fill: plotter
|
|
||||||
direction: QuickChartsControls.GridLines.Vertical
|
|
||||||
minor.visible: false
|
|
||||||
major.count: 3
|
|
||||||
major.lineWidth: 1
|
|
||||||
// Same calculation as Kirigami Separator
|
|
||||||
major.color: Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.4)
|
|
||||||
}
|
|
||||||
QuickCharts.LineChart {
|
|
||||||
id: plotter
|
|
||||||
anchors {
|
|
||||||
left: verticalAxisLabels.right
|
|
||||||
leftMargin: Kirigami.Units.smallSpacing
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
// Align plotter lines with labels.
|
|
||||||
topMargin: Math.round(metricsLabel.implicitHeight / 2) + Kirigami.Units.smallSpacing
|
|
||||||
}
|
|
||||||
height: Kirigami.Units.gridUnit * 8
|
|
||||||
interpolate: true
|
|
||||||
direction: QuickCharts.XYChart.ZeroAtEnd
|
|
||||||
yRange {
|
|
||||||
minimum: 100 * 1024
|
|
||||||
increment: 100 * 1024
|
|
||||||
}
|
|
||||||
valueSources: [
|
|
||||||
QuickCharts.HistoryProxySource {
|
|
||||||
source: QuickCharts.SingleValueSource {
|
|
||||||
id: upload
|
|
||||||
}
|
|
||||||
maximumHistory: 40
|
|
||||||
fillMode: QuickCharts.HistoryProxySource.FillFromStart
|
|
||||||
},
|
|
||||||
QuickCharts.HistoryProxySource {
|
|
||||||
source: QuickCharts.SingleValueSource {
|
|
||||||
id: download
|
|
||||||
}
|
|
||||||
maximumHistory: 40
|
|
||||||
fillMode: QuickCharts.HistoryProxySource.FillFromStart
|
|
||||||
}
|
|
||||||
]
|
|
||||||
nameSource: QuickCharts.ArraySource {
|
|
||||||
array: [i18n("Upload"), i18n("Download")]
|
|
||||||
}
|
|
||||||
colorSource: QuickCharts.ArraySource {
|
|
||||||
// Array.reverse() mutates the array but colors.colors is read-only.
|
|
||||||
array: [colors.colors[1], colors.colors[0]]
|
|
||||||
}
|
|
||||||
fillColorSource: QuickCharts.ArraySource {
|
|
||||||
array: plotter.colorSource.array.map(color => Qt.lighter(color, 1.5))
|
|
||||||
}
|
|
||||||
QuickCharts.ColorGradientSource {
|
|
||||||
id: colors
|
|
||||||
baseColor: Kirigami.Theme.highlightColor
|
|
||||||
itemCount: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Note: TextMetrics might be using a different renderType by default,
|
|
||||||
// so we need a Label instance anyway.
|
|
||||||
PlasmaComponents3.Label {
|
|
||||||
id: metricsLabel
|
|
||||||
visible: false
|
|
||||||
font: Kirigami.Theme.smallFont
|
|
||||||
// Measure 888.8 KiB/s
|
|
||||||
text: KCoreAddons.Format.formatByteSize(910131) + i18n("/s")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QuickChartsControls.Legend {
|
|
||||||
chart: plotter
|
|
||||||
Layout.leftMargin: Kirigami.Units.smallSpacing
|
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: Kirigami.Units.largeSpacing
|
|
||||||
delegate: RowLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
QuickChartsControls.LegendLayout.maximumWidth: implicitWidth
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: model.color
|
|
||||||
width: Kirigami.Units.smallSpacing
|
|
||||||
height: legendLabel.height
|
|
||||||
}
|
|
||||||
PlasmaComponents3.Label {
|
|
||||||
id: legendLabel
|
|
||||||
font: Kirigami.Theme.smallFont
|
|
||||||
text: model.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,175 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2017 Martin Kacej <m.kacej@atlas.sk>
|
|
||||||
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Controls as Controls
|
|
||||||
|
|
||||||
import org.kde.plasma.networkmanagement as PlasmaNM
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.kcmutils
|
|
||||||
import org.kde.kirigamiaddons.formcard 1 as FormCard
|
|
||||||
|
|
||||||
SimpleKCM {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool editMode: false
|
|
||||||
|
|
||||||
topPadding: Kirigami.Units.gridUnit
|
|
||||||
bottomPadding: Kirigami.Units.gridUnit
|
|
||||||
leftPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
|
|
||||||
actions: [
|
|
||||||
Kirigami.Action {
|
|
||||||
text: i18n("Edit")
|
|
||||||
icon.name: 'entry-edit'
|
|
||||||
checkable: true
|
|
||||||
onCheckedChanged: root.editMode = checked
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
PlasmaNM.Handler {
|
|
||||||
id: handler
|
|
||||||
}
|
|
||||||
|
|
||||||
PlasmaNM.EnabledConnections {
|
|
||||||
id: enabledConnections
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
ConnectDialog {
|
|
||||||
id: connectionDialog
|
|
||||||
parent: root
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
|
|
||||||
Kirigami.InlineMessage {
|
|
||||||
id: inlineError
|
|
||||||
showCloseButton: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
type: Kirigami.MessageType.Warning
|
|
||||||
Connections {
|
|
||||||
target: handler
|
|
||||||
function onConnectionActivationFailed(connectionPath, message) {
|
|
||||||
inlineError.text = message;
|
|
||||||
inlineError.visible = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
FormCard.FormSwitchDelegate {
|
|
||||||
id: wifiSwitch
|
|
||||||
text: i18n("Wi-Fi")
|
|
||||||
checked: enabledConnections.wirelessEnabled
|
|
||||||
onCheckedChanged: {
|
|
||||||
handler.enableWireless(checked);
|
|
||||||
checked = Qt.binding(() => enabledConnections.wirelessEnabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormHeader {
|
|
||||||
visible: savedCard.visible
|
|
||||||
title: i18nc("@title:group", "Saved Networks")
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
id: savedCard
|
|
||||||
visible: enabledConnections.wirelessEnabled && count > 0
|
|
||||||
|
|
||||||
// number of visible entries
|
|
||||||
property int count: 0
|
|
||||||
function updateCount() {
|
|
||||||
count = 0;
|
|
||||||
for (let i = 0; i < connectedRepeater.count; i++) {
|
|
||||||
let item = connectedRepeater.itemAt(i);
|
|
||||||
if (item && item.shouldDisplay) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: connectedRepeater
|
|
||||||
model: mobileProxyModel
|
|
||||||
delegate: ConnectionItemDelegate {
|
|
||||||
editMode: root.editMode
|
|
||||||
|
|
||||||
// connected or saved
|
|
||||||
property bool shouldDisplay: (Uuid != "") || ConnectionState === PlasmaNM.Enums.Activated
|
|
||||||
onShouldDisplayChanged: savedCard.updateCount()
|
|
||||||
|
|
||||||
// separate property for visible since visible is false when the whole card is not visible
|
|
||||||
visible: shouldDisplay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormHeader {
|
|
||||||
visible: enabledConnections.wirelessEnabled
|
|
||||||
title: i18n("Available Networks")
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
id: availableCard
|
|
||||||
visible: enabledConnections.wirelessEnabled && count > 0
|
|
||||||
|
|
||||||
// number of visible entries
|
|
||||||
property int count: 0
|
|
||||||
function updateCount() {
|
|
||||||
count = 0;
|
|
||||||
for (let i = 0; i < availableRepeater.count; i++) {
|
|
||||||
let item = availableRepeater.itemAt(i);
|
|
||||||
if (item && item.shouldDisplay) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: availableRepeater
|
|
||||||
model: mobileProxyModel
|
|
||||||
delegate: ConnectionItemDelegate {
|
|
||||||
editMode: root.editMode
|
|
||||||
|
|
||||||
property bool shouldDisplay: !((Uuid != "") || ConnectionState === PlasmaNM.Enums.Activated)
|
|
||||||
onShouldDisplayChanged: availableCard.updateCount()
|
|
||||||
|
|
||||||
visible: shouldDisplay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
|
||||||
icon.name: 'list-add'
|
|
||||||
text: i18n("Add Custom Connection")
|
|
||||||
visible: enabledConnections.wirelessEnabled
|
|
||||||
onClicked: kcm.push("NetworkSettings.qml")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,292 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "wifisettings.h"
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
#include <KPluginFactory>
|
|
||||||
|
|
||||||
#include <NetworkManagerQt/AccessPoint>
|
|
||||||
#include <NetworkManagerQt/ActiveConnection>
|
|
||||||
#include <NetworkManagerQt/Connection>
|
|
||||||
#include <NetworkManagerQt/ConnectionSettings>
|
|
||||||
#include <NetworkManagerQt/GsmSetting>
|
|
||||||
#include <NetworkManagerQt/Ipv4Setting>
|
|
||||||
#include <NetworkManagerQt/Manager>
|
|
||||||
#include <NetworkManagerQt/Settings>
|
|
||||||
#include <NetworkManagerQt/Utils>
|
|
||||||
#include <NetworkManagerQt/WiredDevice>
|
|
||||||
#include <NetworkManagerQt/WiredSetting>
|
|
||||||
#include <NetworkManagerQt/WirelessDevice>
|
|
||||||
#include <NetworkManagerQt/WirelessSetting>
|
|
||||||
|
|
||||||
K_PLUGIN_CLASS_WITH_JSON(WifiSettings, "kcm_mobile_wifi.json")
|
|
||||||
|
|
||||||
WifiSettings::WifiSettings(QObject *parent, const KPluginMetaData &metaData)
|
|
||||||
: KQuickConfigModule(parent, metaData)
|
|
||||||
{
|
|
||||||
setButtons({});
|
|
||||||
}
|
|
||||||
|
|
||||||
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().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<NetworkManager::IpAddress>({ipaddr}));
|
|
||||||
ipSettings->setDns(QList<QHostAddress>({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());
|
|
||||||
}
|
|
||||||
if (type == NetworkManager::SAE) {
|
|
||||||
securitySettings->setKeyMgmt(NetworkManager::WirelessSecuritySetting::KeyMgmt::SAE);
|
|
||||||
securitySettings->setAuthAlg(NetworkManager::WirelessSecuritySetting::AuthAlg::Open);
|
|
||||||
securitySettings->setPskFlags(NetworkManager::Setting::SecretFlagType::AgentOwned);
|
|
||||||
securitySettings->setPsk(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<NetworkManager::Ipv4Setting>();
|
|
||||||
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<NetworkManager::IpAddress>({ipaddr}));
|
|
||||||
ipSetting->setDns(QList<QHostAddress>({QHostAddress(map["dns"].toString())}));
|
|
||||||
}
|
|
||||||
toUpdateMap.insert("ipv4", ipSetting->toMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkManager::WirelessSetting::Ptr wirelessSetting =
|
|
||||||
con->settings()->setting(NetworkManager::Setting::Wireless).staticCast<NetworkManager::WirelessSetting>();
|
|
||||||
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<NetworkManager::WirelessSecuritySetting>();
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((securitySetting->keyMgmt() == NetworkManager::WirelessSecuritySetting::SAE) && (secMap.value("type") == NetworkManager::SAE)) {
|
|
||||||
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<NetworkManager::WirelessDevice>();
|
|
||||||
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<NetworkManager::WirelessSetting>()->mode() == NetworkManager::WirelessSetting::Ap) {
|
|
||||||
return con->path();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "wifisettings.moc"
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
/*
|
|
||||||
SPDX-FileCopyrightText: 2018 Martin Kacej <m.kacej@atlas.sk>
|
|
||||||
|
|
||||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WIFISETTINGS_H
|
|
||||||
#define WIFISETTINGS_H
|
|
||||||
|
|
||||||
#include <KQuickConfigModule>
|
|
||||||
|
|
||||||
class WifiSettings : public KQuickConfigModule
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
WifiSettings(QObject *parent, const KPluginMetaData &metaData);
|
|
||||||
Q_INVOKABLE QVariantMap getConnectionSettings(const QString &connection, const QString &type);
|
|
||||||
Q_INVOKABLE QVariantMap getActiveConnectionInfo(const QString &connection);
|
|
||||||
Q_INVOKABLE void addConnectionFromQML(const QVariantMap &QMLmap);
|
|
||||||
Q_INVOKABLE void updateConnectionFromQML(const QString &path, const QVariantMap &map);
|
|
||||||
Q_INVOKABLE QString getAccessPointDevice();
|
|
||||||
Q_INVOKABLE QString getAccessPointConnection();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WIFISETTINGS_H
|
|
||||||
Loading…
Reference in a new issue