controlcenter: wireless panel rewrite
This commit is contained in:
parent
ffe14748a2
commit
fc223237f0
10 changed files with 483 additions and 775 deletions
|
|
@ -36,7 +36,7 @@ ClippingRectangle {
|
||||||
|
|
||||||
Pane {
|
Pane {
|
||||||
index: 1
|
index: 1
|
||||||
sourceComponent: NetworkPane {
|
sourceComponent: WirelessPane {
|
||||||
session: root.session
|
session: root.session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,514 +0,0 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import ".."
|
|
||||||
import qs.components
|
|
||||||
import qs.components.controls
|
|
||||||
import qs.components.effects
|
|
||||||
import qs.components.containers
|
|
||||||
import qs.services
|
|
||||||
import qs.config
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property Session session
|
|
||||||
readonly property var network: {
|
|
||||||
// Try pendingNetwork first, then fall back to active network selection
|
|
||||||
if (session.network.pendingNetwork) {
|
|
||||||
return session.network.pendingNetwork;
|
|
||||||
}
|
|
||||||
// Fallback to active network if available
|
|
||||||
if (session.network.active) {
|
|
||||||
return session.network.active;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
visible: session.network.showPasswordDialog
|
|
||||||
enabled: visible
|
|
||||||
focus: visible
|
|
||||||
|
|
||||||
// Ensure network is set when dialog opens
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (visible && !session.network.pendingNetwork && session.network.active) {
|
|
||||||
session.network.pendingNetwork = session.network.active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onVisibleChanged(): void {
|
|
||||||
if (visible && !session.network.pendingNetwork && session.network.active) {
|
|
||||||
session.network.pendingNetwork = session.network.active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onEscapePressed: {
|
|
||||||
root.session.network.showPasswordDialog = false;
|
|
||||||
passwordField.text = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.5)
|
|
||||||
opacity: root.visible ? 1 : 0
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
root.session.network.showPasswordDialog = false;
|
|
||||||
passwordField.text = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
id: dialog
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
implicitWidth: 400
|
|
||||||
implicitHeight: content.implicitHeight + Appearance.padding.large * 2
|
|
||||||
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
color: Colours.tPalette.m3surface
|
|
||||||
opacity: root.visible ? 1 : 0
|
|
||||||
scale: root.visible ? 1 : 0.9
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onEscapePressed: {
|
|
||||||
root.session.network.showPasswordDialog = false;
|
|
||||||
passwordField.text = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: content
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.margins: Appearance.padding.large
|
|
||||||
|
|
||||||
spacing: Appearance.spacing.normal
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: "lock"
|
|
||||||
font.pointSize: Appearance.font.size.extraLarge * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: qsTr("Enter password")
|
|
||||||
font.pointSize: Appearance.font.size.large
|
|
||||||
font.weight: 500
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: root.network ? qsTr("Network: %1").arg(root.network.ssid) : ""
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: statusText
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.topMargin: Appearance.spacing.small
|
|
||||||
visible: Network.connectionStatus.length > 0 || connectButton.connecting
|
|
||||||
text: {
|
|
||||||
if (Network.connectionStatus.length > 0) {
|
|
||||||
return Network.connectionStatus;
|
|
||||||
} else if (connectButton.connecting) {
|
|
||||||
return qsTr("Connecting...");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
color: {
|
|
||||||
const status = Network.connectionStatus;
|
|
||||||
if (status.includes("Error") || status.includes("error") || status.includes("failed")) {
|
|
||||||
return Colours.palette.m3error;
|
|
||||||
} else if (status.includes("successful") || status.includes("Connected") || status.includes("success")) {
|
|
||||||
return Colours.palette.m3primary;
|
|
||||||
}
|
|
||||||
return Colours.palette.m3onSurfaceVariant;
|
|
||||||
}
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
font.weight: (Network.connectionStatus.includes("Error") || Network.connectionStatus.includes("error")) ? 500 : 400
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
Layout.maximumWidth: parent.width - Appearance.padding.large * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.topMargin: Appearance.spacing.large
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: passwordField.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
|
||||||
border.width: passwordField.activeFocus ? 2 : 1
|
|
||||||
border.color: passwordField.activeFocus ? Colours.palette.m3primary : Colours.palette.m3outline
|
|
||||||
|
|
||||||
Behavior on border.color {
|
|
||||||
CAnim {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledTextField {
|
|
||||||
id: passwordField
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.margins: Appearance.padding.normal
|
|
||||||
|
|
||||||
echoMode: TextField.Password
|
|
||||||
placeholderText: qsTr("Password")
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (root.visible) {
|
|
||||||
forceActiveFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onVisibleChanged(): void {
|
|
||||||
if (root.visible) {
|
|
||||||
passwordField.forceActiveFocus();
|
|
||||||
passwordField.text = "";
|
|
||||||
Network.connectionStatus = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: Network
|
|
||||||
function onConnectionStatusChanged(): void {
|
|
||||||
// Status updated, ensure it's visible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
if (connectButton.enabled) {
|
|
||||||
connectButton.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keys.onEnterPressed: {
|
|
||||||
if (connectButton.enabled) {
|
|
||||||
connectButton.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.topMargin: Appearance.spacing.normal
|
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: Appearance.spacing.normal
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: cancelButton
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: Colours.palette.m3secondaryContainer
|
|
||||||
onColor: Colours.palette.m3onSecondaryContainer
|
|
||||||
text: qsTr("Cancel")
|
|
||||||
|
|
||||||
function onClicked(): void {
|
|
||||||
root.session.network.showPasswordDialog = false;
|
|
||||||
passwordField.text = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: connectButton
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: Colours.palette.m3primary
|
|
||||||
onColor: Colours.palette.m3onPrimary
|
|
||||||
text: qsTr("Connect")
|
|
||||||
enabled: passwordField.text.length > 0
|
|
||||||
|
|
||||||
property bool connecting: false
|
|
||||||
|
|
||||||
function onClicked(): void {
|
|
||||||
Network.connectionStatus = "";
|
|
||||||
|
|
||||||
// Get password first
|
|
||||||
const password = passwordField.text;
|
|
||||||
|
|
||||||
// Try multiple ways to get the network
|
|
||||||
let networkToUse = null;
|
|
||||||
|
|
||||||
// Try 1: root.network (computed property)
|
|
||||||
if (root.network) {
|
|
||||||
networkToUse = root.network;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try 2: pendingNetwork
|
|
||||||
if (!networkToUse && root.session.network.pendingNetwork) {
|
|
||||||
networkToUse = root.session.network.pendingNetwork;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try 3: active network
|
|
||||||
if (!networkToUse && root.session.network.active) {
|
|
||||||
networkToUse = root.session.network.active;
|
|
||||||
root.session.network.pendingNetwork = networkToUse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check all conditions
|
|
||||||
const hasNetwork = !!networkToUse;
|
|
||||||
const hasPassword = password && password.length > 0;
|
|
||||||
const notConnecting = !connecting;
|
|
||||||
|
|
||||||
if (hasNetwork && hasPassword && notConnecting) {
|
|
||||||
// Set status immediately
|
|
||||||
Network.connectionStatus = qsTr("Preparing to connect...");
|
|
||||||
|
|
||||||
// Keep dialog open and track connection
|
|
||||||
connecting = true;
|
|
||||||
connectButton.enabled = false;
|
|
||||||
connectButton.text = qsTr("Connecting...");
|
|
||||||
|
|
||||||
// Force immediate UI update
|
|
||||||
statusText.visible = true;
|
|
||||||
|
|
||||||
// Store target SSID for later comparison
|
|
||||||
const ssidToConnect = networkToUse.ssid || "";
|
|
||||||
const bssidToConnect = networkToUse.bssid || "";
|
|
||||||
|
|
||||||
// Store the SSID we're connecting to so we can compare later
|
|
||||||
// even if root.network changes
|
|
||||||
content.connectingToSsid = ssidToConnect;
|
|
||||||
|
|
||||||
// Execute connection immediately
|
|
||||||
Network.connectToNetwork(
|
|
||||||
ssidToConnect,
|
|
||||||
password,
|
|
||||||
bssidToConnect,
|
|
||||||
() => {
|
|
||||||
// Callback if connection fails - keep dialog open
|
|
||||||
connecting = false;
|
|
||||||
connectButton.enabled = true;
|
|
||||||
connectButton.text = qsTr("Connect");
|
|
||||||
content.connectingToSsid = ""; // Clear on failure
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Start connection check timer immediately
|
|
||||||
connectionCheckTimer.checkCount = 0;
|
|
||||||
connectionCheckTimer.start();
|
|
||||||
|
|
||||||
// Also check immediately after a short delay to catch quick connections
|
|
||||||
Qt.callLater(() => {
|
|
||||||
if (root.visible) {
|
|
||||||
closeDialogIfConnected();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Show error in status
|
|
||||||
Network.connectionStatus = qsTr("Error: Cannot connect - missing network or password");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the SSID we're connecting to when connection starts
|
|
||||||
property string connectingToSsid: ""
|
|
||||||
|
|
||||||
property string targetSsid: {
|
|
||||||
// Track the SSID we're trying to connect to
|
|
||||||
// Prefer explicitly stored connectingToSsid, then computed values
|
|
||||||
if (connectingToSsid && connectingToSsid.length > 0) {
|
|
||||||
return connectingToSsid;
|
|
||||||
}
|
|
||||||
if (root.network && root.network.ssid) {
|
|
||||||
return root.network.ssid;
|
|
||||||
}
|
|
||||||
if (root.session.network.pendingNetwork && root.session.network.pendingNetwork.ssid) {
|
|
||||||
return root.session.network.pendingNetwork.ssid;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeDialogIfConnected(): bool {
|
|
||||||
// Check if we're connected to the network we're trying to connect to
|
|
||||||
const ssid = targetSsid;
|
|
||||||
|
|
||||||
if (!ssid || ssid.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Network.active) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const activeSsid = Network.active.ssid || "";
|
|
||||||
|
|
||||||
if (activeSsid === ssid) {
|
|
||||||
// Connection succeeded - close dialog
|
|
||||||
connectionCheckTimer.stop();
|
|
||||||
aggressiveCheckTimer.stop();
|
|
||||||
connectionCheckTimer.checkCount = 0;
|
|
||||||
connectButton.connecting = false;
|
|
||||||
Network.connectionStatus = "";
|
|
||||||
root.session.network.showPasswordDialog = false;
|
|
||||||
passwordField.text = "";
|
|
||||||
content.connectingToSsid = ""; // Clear stored SSID
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: connectionCheckTimer
|
|
||||||
interval: 1000 // Check every 1 second for faster response
|
|
||||||
repeat: true
|
|
||||||
triggeredOnStart: false
|
|
||||||
property int checkCount: 0
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
checkCount++;
|
|
||||||
|
|
||||||
// Try to close dialog if connected
|
|
||||||
const closed = content.closeDialogIfConnected();
|
|
||||||
if (closed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectButton.connecting) {
|
|
||||||
// Still connecting, check again
|
|
||||||
// Limit to 20 checks (20 seconds total)
|
|
||||||
if (checkCount >= 20) {
|
|
||||||
connectionCheckTimer.stop();
|
|
||||||
connectionCheckTimer.checkCount = 0;
|
|
||||||
connectButton.connecting = false;
|
|
||||||
connectButton.enabled = true;
|
|
||||||
connectButton.text = qsTr("Connect");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Not connecting anymore, stop timer
|
|
||||||
connectionCheckTimer.stop();
|
|
||||||
connectionCheckTimer.checkCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: Network
|
|
||||||
function onActiveChanged(): void {
|
|
||||||
// Check immediately when active network changes
|
|
||||||
if (root.visible) {
|
|
||||||
// Check immediately - if connected, close right away
|
|
||||||
if (content.closeDialogIfConnected()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also check after a delay in case the active network isn't fully updated yet
|
|
||||||
Qt.callLater(() => {
|
|
||||||
if (root.visible) {
|
|
||||||
content.closeDialogIfConnected();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also check when dialog becomes visible
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function onVisibleChanged(): void {
|
|
||||||
if (root.visible) {
|
|
||||||
// Check immediately when dialog opens
|
|
||||||
Qt.callLater(() => {
|
|
||||||
if (root.visible) {
|
|
||||||
closeDialogIfConnected();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aggressive polling timer - checks every 500ms when dialog is visible and connecting
|
|
||||||
// This ensures we catch the connection even if signals are missed
|
|
||||||
Timer {
|
|
||||||
id: aggressiveCheckTimer
|
|
||||||
interval: 500
|
|
||||||
repeat: true
|
|
||||||
running: root.visible && connectButton.connecting
|
|
||||||
triggeredOnStart: true
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
if (root.visible && connectButton.connecting) {
|
|
||||||
if (content.closeDialogIfConnected()) {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component Button: StyledRect {
|
|
||||||
property color onColor: Colours.palette.m3onSurface
|
|
||||||
property alias disabled: stateLayer.disabled
|
|
||||||
property alias text: label.text
|
|
||||||
property alias enabled: stateLayer.enabled
|
|
||||||
|
|
||||||
function onClicked(): void {
|
|
||||||
}
|
|
||||||
|
|
||||||
radius: Appearance.rounding.small
|
|
||||||
implicitHeight: label.implicitHeight + Appearance.padding.small * 2
|
|
||||||
opacity: enabled ? 1 : 0.5
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: stateLayer
|
|
||||||
|
|
||||||
enabled: parent.enabled
|
|
||||||
color: parent.onColor
|
|
||||||
|
|
||||||
function onClicked(): void {
|
|
||||||
if (enabled) {
|
|
||||||
parent.onClicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: label
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
animate: true
|
|
||||||
color: parent.onColor
|
|
||||||
font.pointSize: Appearance.font.size.normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import ".."
|
|
||||||
import qs.components
|
|
||||||
import qs.components.controls
|
|
||||||
import qs.components.effects
|
|
||||||
import qs.services
|
|
||||||
import qs.config
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property Session session
|
|
||||||
|
|
||||||
spacing: Appearance.spacing.normal
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: "wifi"
|
|
||||||
font.pointSize: Appearance.font.size.extraLarge * 3
|
|
||||||
font.bold: true
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: qsTr("Network settings")
|
|
||||||
font.pointSize: Appearance.font.size.large
|
|
||||||
font.bold: true
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.topMargin: Appearance.spacing.large
|
|
||||||
text: qsTr("WiFi status")
|
|
||||||
font.pointSize: Appearance.font.size.larger
|
|
||||||
font.weight: 500
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: qsTr("General WiFi settings")
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: wifiStatus.implicitHeight + Appearance.padding.large * 2
|
|
||||||
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: wifiStatus
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.margins: Appearance.padding.large
|
|
||||||
|
|
||||||
spacing: Appearance.spacing.larger
|
|
||||||
|
|
||||||
Toggle {
|
|
||||||
label: qsTr("WiFi enabled")
|
|
||||||
checked: Network.wifiEnabled
|
|
||||||
toggle.onToggled: {
|
|
||||||
Network.enableWifi(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.topMargin: Appearance.spacing.large
|
|
||||||
text: qsTr("Network information")
|
|
||||||
font.pointSize: Appearance.font.size.larger
|
|
||||||
font.weight: 500
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: qsTr("Current network connection")
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: networkInfo.implicitHeight + Appearance.padding.large * 2
|
|
||||||
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: networkInfo
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.margins: Appearance.padding.large
|
|
||||||
|
|
||||||
spacing: Appearance.spacing.small / 2
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: qsTr("Connected network")
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: Network.active ? Network.active.ssid : qsTr("Not connected")
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.topMargin: Appearance.spacing.normal
|
|
||||||
text: qsTr("Signal strength")
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: Network.active ? qsTr("%1%").arg(Network.active.strength) : qsTr("N/A")
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.topMargin: Appearance.spacing.normal
|
|
||||||
text: qsTr("Security")
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: Network.active ? (Network.active.isSecure ? qsTr("Secured") : qsTr("Open")) : qsTr("N/A")
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.topMargin: Appearance.spacing.normal
|
|
||||||
text: qsTr("Frequency")
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: Network.active ? qsTr("%1 MHz").arg(Network.active.frequency) : qsTr("N/A")
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component Toggle: RowLayout {
|
|
||||||
required property string label
|
|
||||||
property alias checked: toggle.checked
|
|
||||||
property alias toggle: toggle
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: Appearance.spacing.normal
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: parent.label
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledSwitch {
|
|
||||||
id: toggle
|
|
||||||
|
|
||||||
cLayer: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
36
modules/controlcenter/network/SimpleButton.qml
Normal file
36
modules/controlcenter/network/SimpleButton.qml
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import qs.components
|
||||||
|
import qs.components.effects
|
||||||
|
import qs.config
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property color onColor: Colours.palette.m3onSurface
|
||||||
|
property alias disabled: stateLayer.disabled
|
||||||
|
property alias text: label.text
|
||||||
|
property alias enabled: stateLayer.enabled
|
||||||
|
|
||||||
|
implicitWidth: label.implicitWidth + Appearance.padding.normal * 2
|
||||||
|
implicitHeight: label.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
id: stateLayer
|
||||||
|
color: parent.onColor
|
||||||
|
function onClicked(): void {
|
||||||
|
if (parent.enabled !== false) {
|
||||||
|
parent.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: label
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: parent.onColor
|
||||||
|
}
|
||||||
|
|
||||||
|
signal clicked
|
||||||
|
}
|
||||||
|
|
||||||
46
modules/controlcenter/network/WirelessConnectionHelper.qml
Normal file
46
modules/controlcenter/network/WirelessConnectionHelper.qml
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import ".."
|
||||||
|
import qs.services
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property Session session
|
||||||
|
|
||||||
|
function connectToNetwork(network: var): void {
|
||||||
|
if (!network) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If already connected to a different network, disconnect first
|
||||||
|
if (Network.active && Network.active.ssid !== network.ssid) {
|
||||||
|
Network.disconnectFromNetwork();
|
||||||
|
Qt.callLater(() => {
|
||||||
|
performConnect(network);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
performConnect(network);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function performConnect(network: var): void {
|
||||||
|
if (network.isSecure) {
|
||||||
|
// Try connecting without password first (in case it's saved)
|
||||||
|
Network.connectToNetworkWithPasswordCheck(
|
||||||
|
network.ssid,
|
||||||
|
network.isSecure,
|
||||||
|
() => {
|
||||||
|
// Callback: connection failed, show password dialog
|
||||||
|
root.session.network.showPasswordDialog = true;
|
||||||
|
root.session.network.pendingNetwork = network;
|
||||||
|
},
|
||||||
|
network.bssid
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Network.connectToNetwork(network.ssid, "", network.bssid, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import ".."
|
import ".."
|
||||||
|
import "."
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.components.controls
|
import qs.components.controls
|
||||||
import qs.components.effects
|
import qs.components.effects
|
||||||
|
|
@ -16,6 +17,10 @@ Item {
|
||||||
required property Session session
|
required property Session session
|
||||||
readonly property var network: session.network.active
|
readonly property var network: session.network.active
|
||||||
|
|
||||||
|
readonly property var connectionHelper: WirelessConnectionHelper {
|
||||||
|
session: root.session
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (network && network.active) {
|
if (network && network.active) {
|
||||||
Network.updateWirelessDeviceDetails();
|
Network.updateWirelessDeviceDetails();
|
||||||
|
|
@ -70,41 +75,14 @@ Item {
|
||||||
checked: root.network?.active ?? false
|
checked: root.network?.active ?? false
|
||||||
toggle.onToggled: {
|
toggle.onToggled: {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
// If already connected to a different network, disconnect first
|
root.connectionHelper.connectToNetwork(root.network);
|
||||||
if (Network.active && Network.active.ssid !== root.network.ssid) {
|
|
||||||
Network.disconnectFromNetwork();
|
|
||||||
// Wait a moment before connecting to new network
|
|
||||||
Qt.callLater(() => {
|
|
||||||
connectToNetwork();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
connectToNetwork();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Network.disconnectFromNetwork();
|
Network.disconnectFromNetwork();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectToNetwork(): void {
|
|
||||||
if (root.network.isSecure) {
|
|
||||||
// Try connecting without password first (in case it's saved)
|
|
||||||
Network.connectToNetworkWithPasswordCheck(
|
|
||||||
root.network.ssid,
|
|
||||||
root.network.isSecure,
|
|
||||||
() => {
|
|
||||||
// Callback: connection failed, show password dialog
|
|
||||||
root.session.network.showPasswordDialog = true;
|
|
||||||
root.session.network.pendingNetwork = root.network;
|
|
||||||
},
|
|
||||||
root.network.bssid
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
Network.connectToNetwork(root.network.ssid, "", root.network.bssid, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
SimpleButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Appearance.spacing.normal
|
Layout.topMargin: Appearance.spacing.normal
|
||||||
visible: root.network && root.network.ssid && Network.savedConnections.includes(root.network.ssid)
|
visible: root.network && root.network.ssid && Network.savedConnections.includes(root.network.ssid)
|
||||||
|
|
@ -176,38 +154,5 @@ Item {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
component Button: StyledRect {
|
|
||||||
property color onColor: Colours.palette.m3onSurface
|
|
||||||
property alias disabled: stateLayer.disabled
|
|
||||||
property alias text: label.text
|
|
||||||
property alias enabled: stateLayer.enabled
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: label.implicitHeight + Appearance.padding.normal * 2
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
id: stateLayer
|
|
||||||
color: parent.onColor
|
|
||||||
function onClicked(): void {
|
|
||||||
if (parent.enabled !== false) {
|
|
||||||
parent.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: label
|
|
||||||
anchors.centerIn: parent
|
|
||||||
color: parent.onColor
|
|
||||||
}
|
|
||||||
|
|
||||||
signal clicked
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import ".."
|
import ".."
|
||||||
|
import "."
|
||||||
import qs.components
|
import qs.components
|
||||||
import qs.components.controls
|
import qs.components.controls
|
||||||
import qs.components.containers
|
import qs.components.containers
|
||||||
|
|
@ -14,6 +15,10 @@ ColumnLayout {
|
||||||
|
|
||||||
required property Session session
|
required property Session session
|
||||||
|
|
||||||
|
readonly property var connectionHelper: WirelessConnectionHelper {
|
||||||
|
session: root.session
|
||||||
|
}
|
||||||
|
|
||||||
spacing: Appearance.spacing.small
|
spacing: Appearance.spacing.small
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -180,34 +185,7 @@ ColumnLayout {
|
||||||
if (modelData.active) {
|
if (modelData.active) {
|
||||||
Network.disconnectFromNetwork();
|
Network.disconnectFromNetwork();
|
||||||
} else {
|
} else {
|
||||||
// If already connected to a different network, disconnect first
|
root.connectionHelper.connectToNetwork(modelData);
|
||||||
if (Network.active && Network.active.ssid !== modelData.ssid) {
|
|
||||||
Network.disconnectFromNetwork();
|
|
||||||
// Wait a moment before connecting to new network
|
|
||||||
Qt.callLater(() => {
|
|
||||||
connectToNetwork();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
connectToNetwork();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function connectToNetwork(): void {
|
|
||||||
if (modelData.isSecure) {
|
|
||||||
// Try connecting without password first (in case it's saved)
|
|
||||||
Network.connectToNetworkWithPasswordCheck(
|
|
||||||
modelData.ssid,
|
|
||||||
modelData.isSecure,
|
|
||||||
() => {
|
|
||||||
// Callback: connection failed, show password dialog
|
|
||||||
root.session.network.showPasswordDialog = true;
|
|
||||||
root.session.network.pendingNetwork = modelData;
|
|
||||||
},
|
|
||||||
modelData.bssid
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
Network.connectToNetwork(modelData.ssid, "", modelData.bssid, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,3 +204,4 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ RowLayout {
|
||||||
Layout.minimumWidth: 420
|
Layout.minimumWidth: 420
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
NetworkList {
|
WirelessList {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
anchors.margins: Appearance.padding.large + Appearance.padding.normal
|
||||||
anchors.leftMargin: Appearance.padding.large
|
anchors.leftMargin: Appearance.padding.large
|
||||||
|
|
@ -121,7 +121,7 @@ RowLayout {
|
||||||
flickableDirection: Flickable.VerticalFlick
|
flickableDirection: Flickable.VerticalFlick
|
||||||
contentHeight: settingsInner.height
|
contentHeight: settingsInner.height
|
||||||
|
|
||||||
Settings {
|
WirelessSettings {
|
||||||
id: settingsInner
|
id: settingsInner
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -134,13 +134,13 @@ RowLayout {
|
||||||
Component {
|
Component {
|
||||||
id: details
|
id: details
|
||||||
|
|
||||||
Details {
|
WirelessDetails {
|
||||||
session: root.session
|
session: root.session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PasswordDialog {
|
WirelessPasswordDialog {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
session: root.session
|
session: root.session
|
||||||
z: 1000
|
z: 1000
|
||||||
|
|
@ -152,3 +152,4 @@ RowLayout {
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
299
modules/controlcenter/network/WirelessPasswordDialog.qml
Normal file
299
modules/controlcenter/network/WirelessPasswordDialog.qml
Normal file
|
|
@ -0,0 +1,299 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import ".."
|
||||||
|
import "."
|
||||||
|
import qs.components
|
||||||
|
import qs.components.controls
|
||||||
|
import qs.components.effects
|
||||||
|
import qs.components.containers
|
||||||
|
import qs.services
|
||||||
|
import qs.config
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property Session session
|
||||||
|
|
||||||
|
readonly property var network: {
|
||||||
|
// Prefer pendingNetwork, then active network
|
||||||
|
if (session.network.pendingNetwork) {
|
||||||
|
return session.network.pendingNetwork;
|
||||||
|
}
|
||||||
|
if (session.network.active) {
|
||||||
|
return session.network.active;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: session.network.showPasswordDialog
|
||||||
|
enabled: visible
|
||||||
|
focus: visible
|
||||||
|
|
||||||
|
Keys.onEscapePressed: {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.5)
|
||||||
|
opacity: root.visible ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation { duration: 200 }
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: closeDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
id: dialog
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
implicitWidth: 400
|
||||||
|
implicitHeight: content.implicitHeight + Appearance.padding.large * 2
|
||||||
|
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
color: Colours.tPalette.m3surface
|
||||||
|
opacity: root.visible ? 1 : 0
|
||||||
|
scale: root.visible ? 1 : 0.9
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation { duration: 200 }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation { duration: 200 }
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEscapePressed: closeDialog();
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.margins: Appearance.padding.large
|
||||||
|
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: "lock"
|
||||||
|
font.pointSize: Appearance.font.size.extraLarge * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: qsTr("Enter password")
|
||||||
|
font.pointSize: Appearance.font.size.large
|
||||||
|
font.weight: 500
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: root.network ? qsTr("Network: %1").arg(root.network.ssid) : ""
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: statusText
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: Appearance.spacing.small
|
||||||
|
visible: Network.connectionStatus.length > 0 || connectButton.connecting
|
||||||
|
text: {
|
||||||
|
if (Network.connectionStatus.length > 0) {
|
||||||
|
return Network.connectionStatus;
|
||||||
|
} else if (connectButton.connecting) {
|
||||||
|
return qsTr("Connecting...");
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
color: {
|
||||||
|
const status = Network.connectionStatus;
|
||||||
|
if (status.includes("Error") || status.includes("error") || status.includes("failed")) {
|
||||||
|
return Colours.palette.m3error;
|
||||||
|
} else if (status.includes("successful") || status.includes("Connected") || status.includes("success")) {
|
||||||
|
return Colours.palette.m3primary;
|
||||||
|
}
|
||||||
|
return Colours.palette.m3onSurfaceVariant;
|
||||||
|
}
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
font.weight: (Network.connectionStatus.includes("Error") || Network.connectionStatus.includes("error")) ? 500 : 400
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
Layout.maximumWidth: parent.width - Appearance.padding.large * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.topMargin: Appearance.spacing.large
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: passwordField.implicitHeight + Appearance.padding.normal * 2
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
|
border.width: passwordField.activeFocus ? 2 : 1
|
||||||
|
border.color: passwordField.activeFocus ? Colours.palette.m3primary : Colours.palette.m3outline
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledTextField {
|
||||||
|
id: passwordField
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.margins: Appearance.padding.normal
|
||||||
|
|
||||||
|
echoMode: TextField.Password
|
||||||
|
placeholderText: qsTr("Password")
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
function onVisibleChanged(): void {
|
||||||
|
if (root.visible) {
|
||||||
|
passwordField.forceActiveFocus();
|
||||||
|
passwordField.text = "";
|
||||||
|
Network.clearConnectionStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (connectButton.enabled) {
|
||||||
|
connectButton.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (connectButton.enabled) {
|
||||||
|
connectButton.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.topMargin: Appearance.spacing.normal
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
SimpleButton {
|
||||||
|
id: cancelButton
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: Colours.palette.m3secondaryContainer
|
||||||
|
onColor: Colours.palette.m3onSecondaryContainer
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
|
||||||
|
onClicked: closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleButton {
|
||||||
|
id: connectButton
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: Colours.palette.m3primary
|
||||||
|
onColor: Colours.palette.m3onPrimary
|
||||||
|
text: qsTr("Connect")
|
||||||
|
enabled: passwordField.text.length > 0 && !connecting
|
||||||
|
|
||||||
|
property bool connecting: false
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (!root.network || connecting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const password = passwordField.text;
|
||||||
|
if (!password || password.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set connecting state
|
||||||
|
connecting = true;
|
||||||
|
enabled = false;
|
||||||
|
text = qsTr("Connecting...");
|
||||||
|
Network.clearConnectionStatus();
|
||||||
|
|
||||||
|
// Connect to network
|
||||||
|
Network.connectToNetwork(
|
||||||
|
root.network.ssid,
|
||||||
|
password,
|
||||||
|
root.network.bssid || "",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
// Start monitoring connection
|
||||||
|
connectionMonitor.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: connectionMonitor
|
||||||
|
interval: 1000
|
||||||
|
repeat: true
|
||||||
|
triggeredOnStart: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
// Check if we're connected to the target network
|
||||||
|
if (root.network && Network.active && Network.active.ssid === root.network.ssid) {
|
||||||
|
// Successfully connected
|
||||||
|
stop();
|
||||||
|
connectButton.connecting = false;
|
||||||
|
connectButton.text = qsTr("Connect");
|
||||||
|
closeDialog();
|
||||||
|
} else if (connectButton.connecting) {
|
||||||
|
// Still connecting, check status
|
||||||
|
const status = Network.connectionStatus;
|
||||||
|
if (status.includes("Error") || status.includes("error") || status.includes("failed")) {
|
||||||
|
// Connection failed
|
||||||
|
stop();
|
||||||
|
connectButton.connecting = false;
|
||||||
|
connectButton.enabled = true;
|
||||||
|
connectButton.text = qsTr("Connect");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not connecting anymore
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Network
|
||||||
|
function onActiveChanged() {
|
||||||
|
if (root.visible && root.network && Network.active && Network.active.ssid === root.network.ssid) {
|
||||||
|
// Connected successfully
|
||||||
|
connectionMonitor.stop();
|
||||||
|
connectButton.connecting = false;
|
||||||
|
connectButton.text = qsTr("Connect");
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDialog(): void {
|
||||||
|
session.network.showPasswordDialog = false;
|
||||||
|
passwordField.text = "";
|
||||||
|
connectButton.connecting = false;
|
||||||
|
connectButton.text = qsTr("Connect");
|
||||||
|
connectionMonitor.stop();
|
||||||
|
Network.clearConnectionStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
82
modules/controlcenter/network/WirelessSettings.qml
Normal file
82
modules/controlcenter/network/WirelessSettings.qml
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import ".."
|
||||||
|
import qs.components
|
||||||
|
import qs.components.controls
|
||||||
|
import qs.components.effects
|
||||||
|
import qs.services
|
||||||
|
import qs.config
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property Session session
|
||||||
|
|
||||||
|
spacing: Appearance.spacing.normal
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: "wifi"
|
||||||
|
font.pointSize: Appearance.font.size.extraLarge * 3
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: qsTr("Network settings")
|
||||||
|
font.pointSize: Appearance.font.size.large
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionHeader {
|
||||||
|
Layout.topMargin: Appearance.spacing.large
|
||||||
|
title: qsTr("WiFi status")
|
||||||
|
description: qsTr("General WiFi settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionContainer {
|
||||||
|
ToggleRow {
|
||||||
|
label: qsTr("WiFi enabled")
|
||||||
|
checked: Network.wifiEnabled
|
||||||
|
toggle.onToggled: {
|
||||||
|
Network.enableWifi(checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionHeader {
|
||||||
|
Layout.topMargin: Appearance.spacing.large
|
||||||
|
title: qsTr("Network information")
|
||||||
|
description: qsTr("Current network connection")
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionContainer {
|
||||||
|
contentSpacing: Appearance.spacing.small / 2
|
||||||
|
|
||||||
|
PropertyRow {
|
||||||
|
label: qsTr("Connected network")
|
||||||
|
value: Network.active ? Network.active.ssid : qsTr("Not connected")
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyRow {
|
||||||
|
showTopMargin: true
|
||||||
|
label: qsTr("Signal strength")
|
||||||
|
value: Network.active ? qsTr("%1%").arg(Network.active.strength) : qsTr("N/A")
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyRow {
|
||||||
|
showTopMargin: true
|
||||||
|
label: qsTr("Security")
|
||||||
|
value: Network.active ? (Network.active.isSecure ? qsTr("Secured") : qsTr("Open")) : qsTr("N/A")
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyRow {
|
||||||
|
showTopMargin: true
|
||||||
|
label: qsTr("Frequency")
|
||||||
|
value: Network.active ? qsTr("%1 MHz").arg(Network.active.frequency) : qsTr("N/A")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue