From 49809b08669dc13dd36bee083e1881596d9d5d0e Mon Sep 17 00:00:00 2001 From: caixiangrong Date: Wed, 15 Oct 2025 15:27:49 +0800 Subject: [PATCH] fix: Add switch button Add switch button pms: BUG-329459 --- dcc-network/qml/NetUtils.js | 45 +- dcc-network/qml/PageSystemProxy.qml | 569 +++++++++++++------------ dcc-network/qml/PageVPN.qml | 365 ++++++++-------- dcc-network/qml/PageWiredDevice.qml | 80 ++-- dcc-network/qml/PageWirelessDevice.qml | 94 ++-- dcc-network/qml/networkMain.qml | 49 ++- net-view/operation/netitem.h | 4 +- 7 files changed, 647 insertions(+), 559 deletions(-) diff --git a/dcc-network/qml/NetUtils.js b/dcc-network/qml/NetUtils.js index 4cf9c183e..21e94aba6 100644 --- a/dcc-network/qml/NetUtils.js +++ b/dcc-network/qml/NetUtils.js @@ -1,7 +1,5 @@ // SPDX-FileCopyrightText: 2024 - 2027 UnionTech Software Technology Co., Ltd. // SPDX-License-Identifier: GPL-3.0-or-later -.pragma library - const VpnTypeEnum = Object.freeze({ "l2tp": 0x01, "pptp": 0x02, @@ -63,7 +61,7 @@ function removeTrailingNull(str) { function numToIp(num) { const ips = [0, 0, 0, 0] - for (let i = 0; i < 4; i++) { + for (var i = 0; i < 4; i++) { ips[i] = (num >> (i * 8)) & 255 } return ips.join('.') @@ -77,7 +75,7 @@ function ipToNum(ip) { if (ips.length !== 4) { return 0 } - for (let i = 0; i < ips.length; i++) { + for (var i = 0; i < ips.length; i++) { const ipStr = ips[i] const num = parseInt(ipStr, 10) ipNum |= ((num & 255) << cidr) @@ -93,7 +91,7 @@ function prefixToIp(subnetMask) { const maskArray = [255, 255, 255, 255] - for (let i = 0; i < 4; i++) { + for (var i = 0; i < 4; i++) { const byteBits = i * 8 + 8 - subnetMask if (byteBits > 0) { maskArray[i] = (255 << byteBits) & 255 @@ -107,10 +105,10 @@ function ipToPrefix(decimalSubnet) { const octets = decimalSubnet.split('.') let cidr = 0 - for (let j = 0; j < octets.length; j++) { + for (var j = 0; j < octets.length; j++) { const octet = octets[j] const num = parseInt(octet, 10) - for (let i = 0; i < 8; i++) { + for (var i = 0; i < 8; i++) { if ((num & (1 << (7 - i))) !== 0) { cidr++ } else { @@ -124,7 +122,7 @@ function ipToPrefix(decimalSubnet) { } function macToStr(mac) { - return Array.prototype.map.call(new Uint8Array(mac), function(x) { + return Array.prototype.map.call(new Uint8Array(mac), function (x) { return ('00' + x.toString(16)).toUpperCase().slice(-2) }).join(':') } @@ -134,7 +132,7 @@ function strToMac(str) { return new Uint8Array() const arr = str.split(":") const hexArr = arr.join("") - return new Uint8Array(hexArr.match(/[\da-f]{2}/gi).map(function(bb) { + return new Uint8Array(hexArr.match(/[\da-f]{2}/gi).map(function (bb) { return parseInt(bb, 16) })).buffer } @@ -143,7 +141,7 @@ function strToMac(str) { function strToByteArray(data) { if (typeof data === 'string') { const arr = [] - for (let i = 0; i < data.length; ++i) { + for (var i = 0; i < data.length; ++i) { let charcode = data.charCodeAt(i) if (charcode < 0x80) { arr.push(charcode) @@ -175,3 +173,30 @@ function strToByteArray(data) { } return undefined } + +function getStatusName(status) { + switch (status) { + case NetType.DS_Disabled: + return qsTr("Off") + case NetType.DS_ObtainIpFailed: + case NetType.DS_ConnectFailed: + return qsTr("Failed") + case NetType.DS_Connected: + case NetType.DS_ConnectNoInternet: + return qsTr("Connected") + case NetType.DS_IpConflicted: + return qsTr("IP conflict") + case NetType.DS_Connecting: + return qsTr("Connecting") + case NetType.DS_ObtainingIP: + return qsTr("Obtaining address") + case NetType.DS_Authenticating: + return qsTr("Authenticating") + case NetType.DS_Unknown: + case NetType.DS_Enabled: + case NetType.DS_NoCable: + case NetType.DS_Disconnected: + default: + return qsTr("Disconnected") + } +} diff --git a/dcc-network/qml/PageSystemProxy.qml b/dcc-network/qml/PageSystemProxy.qml index 7a13f33fe..b8ef7e78e 100644 --- a/dcc-network/qml/PageSystemProxy.qml +++ b/dcc-network/qml/PageSystemProxy.qml @@ -38,326 +38,341 @@ DccObject { displayName: qsTr("System Proxy") description: qsTr("Set up proxy servers") icon: "dcc_system_agent" - page: DccSettingsView { - Component.onCompleted: root.resetData() + pageType: DccObject.MenuEditor + page: devCheck + Component { + id: devCheck + D.Switch { + checked: item.isEnabled + enabled: item.enabledable + onClicked: { + dccData.exec(item.isEnabled ? NetManager.DisabledDevice : NetManager.EnabledDevice, item.id, {}) + } + } } - DccObject { - name: "body" + name: "menu" parentName: root.name - pageType: DccObject.Item + page: DccSettingsView { + Component.onCompleted: root.resetData() + } DccObject { - name: "title" - parentName: root.name + "/body" - displayName: root.displayName - icon: "dcc_system_agent" - weight: 10 - backgroundType: DccObject.Normal - pageType: DccObject.Editor - page: D.Switch { - checked: root.method !== NetType.None - enabled: item.enabledable - onClicked: { - if (checked) { - root.method = item.lastMethod - } else { - root.method = NetType.None - dccData.exec(NetManager.SetConnectInfo, item.id, { - "method": method - }) + name: "body" + parentName: root.name + "/menu" + pageType: DccObject.Item + DccObject { + name: "title" + parentName: root.name + "/menu/body" + displayName: root.displayName + icon: "dcc_system_agent" + weight: 10 + backgroundType: DccObject.Normal + pageType: DccObject.Editor + page: D.Switch { + checked: root.method !== NetType.None + enabled: item.enabledable + onClicked: { + if (checked) { + root.method = item.lastMethod + } else { + root.method = NetType.None + dccData.exec(NetManager.SetConnectInfo, item.id, { + "method": method + }) + } } } - } - Connections { - target: item - function onMethodChanged(m) { - method = m + Connections { + target: item + function onMethodChanged(m) { + method = m + } } } - } - DccObject { - id: methodObj + DccObject { + id: methodObj - name: "method" - parentName: root.name + "/body" - displayName: qsTr("Proxy Type") - weight: 20 - backgroundType: DccObject.Normal - visible: method !== NetType.None - pageType: DccObject.Editor - page: ComboBox { - flat: true - textRole: "text" - valueRole: "value" - currentIndex: indexOfValue(method) - onActivated: { - method = currentValue - } - model: [{ - "value": NetType.Auto, - "text": qsTr("Auto") - }, { - "value": NetType.Manual, - "text": qsTr("Manual") - }] - Component.onCompleted: { - currentIndex = indexOfValue(method) - } - Connections { - target: root - function onMethodChanged() { + name: "method" + parentName: root.name + "/menu/body" + displayName: qsTr("Proxy Type") + weight: 20 + backgroundType: DccObject.Normal + visible: method !== NetType.None + pageType: DccObject.Editor + page: ComboBox { + flat: true + textRole: "text" + valueRole: "value" + currentIndex: indexOfValue(method) + onActivated: { + method = currentValue + } + model: [{ + "value": NetType.Auto, + "text": qsTr("Auto") + }, { + "value": NetType.Manual, + "text": qsTr("Manual") + }] + Component.onCompleted: { currentIndex = indexOfValue(method) } + Connections { + target: root + function onMethodChanged() { + currentIndex = indexOfValue(method) + } + } } } - } - DccObject { - id: autoUrl - property var config: item.autoProxy - name: "autoUrl" - parentName: root.name + "/body" - displayName: qsTr("Configuration URL") - weight: 30 - backgroundType: DccObject.Normal - pageType: DccObject.Editor - visible: method === NetType.Auto - page: D.LineEdit { - topInset: 4 - bottomInset: 4 - placeholderText: qsTr("Required") - text: dccObj.config - Layout.fillWidth: true - showAlert: autoUrlAlert - onTextChanged: { - autoUrlAlert = false - if (text.length === 0) { - inputItem &= 0x0f - } else { - inputItem |= 0x10 - } + DccObject { + id: autoUrl + property var config: item.autoProxy + name: "autoUrl" + parentName: root.name + "/menu/body" + displayName: qsTr("Configuration URL") + weight: 30 + backgroundType: DccObject.Normal + pageType: DccObject.Editor + visible: method === NetType.Auto + page: D.LineEdit { + topInset: 4 + bottomInset: 4 + placeholderText: qsTr("Required") + text: dccObj.config + Layout.fillWidth: true + showAlert: autoUrlAlert + onTextChanged: { + autoUrlAlert = false + if (text.length === 0) { + inputItem &= 0x0f + } else { + inputItem |= 0x10 + } - if (dccObj.config !== text) { - dccObj.config = text + if (dccObj.config !== text) { + dccObj.config = text + } } - } - onShowAlertChanged: { - if (showAlert) { - this.forceActiveFocus() + onShowAlertChanged: { + if (showAlert) { + this.forceActiveFocus() + } } } } - } - SystemProxyConfigItem { - id: http - name: "http" - parentName: root.name + "/body" - displayName: qsTr("HTTP Proxy") - visible: method === NetType.Manual - weight: 40 - config: root.item.manualProxy.http - onHasUrlChanged: { - if (hasUrl) { - inputItem |= 0x01 - } else { - inputItem &= ~0x01 + SystemProxyConfigItem { + id: http + name: "http" + parentName: root.name + "/menu/body" + displayName: qsTr("HTTP Proxy") + visible: method === NetType.Manual + weight: 40 + config: root.item.manualProxy.http + onHasUrlChanged: { + if (hasUrl) { + inputItem |= 0x01 + } else { + inputItem &= ~0x01 + } } } - } - SystemProxyConfigItem { - id: https - name: "https" - parentName: root.name + "/body" - displayName: qsTr("HTTPS Proxy") - visible: method === NetType.Manual - weight: 50 - config: root.item.manualProxy.https - onHasUrlChanged: { - if (hasUrl) { - inputItem |= 0x02 - } else { - inputItem &= ~0x02 + SystemProxyConfigItem { + id: https + name: "https" + parentName: root.name + "/menu/body" + displayName: qsTr("HTTPS Proxy") + visible: method === NetType.Manual + weight: 50 + config: root.item.manualProxy.https + onHasUrlChanged: { + if (hasUrl) { + inputItem |= 0x02 + } else { + inputItem &= ~0x02 + } } } - } - SystemProxyConfigItem { - id: ftp - name: "ftp" - parentName: root.name + "/body" - displayName: qsTr("FTP Proxy") - visible: method === NetType.Manual - weight: 60 - config: root.item.manualProxy.ftp - onHasUrlChanged: { - if (hasUrl) { - inputItem |= 0x04 - } else { - inputItem &= ~0x04 + SystemProxyConfigItem { + id: ftp + name: "ftp" + parentName: root.name + "/menu/body" + displayName: qsTr("FTP Proxy") + visible: method === NetType.Manual + weight: 60 + config: root.item.manualProxy.ftp + onHasUrlChanged: { + if (hasUrl) { + inputItem |= 0x04 + } else { + inputItem &= ~0x04 + } } } - } - SystemProxyConfigItem { - id: socks - name: "socks" - parentName: root.name + "/body" - displayName: qsTr("SOCKS Proxy") - visible: method === NetType.Manual - weight: 70 - config: root.item.manualProxy.socks - onHasUrlChanged: { - if (hasUrl) { - inputItem |= 0x08 - } else { - inputItem &= ~0x08 + SystemProxyConfigItem { + id: socks + name: "socks" + parentName: root.name + "/menu/body" + displayName: qsTr("SOCKS Proxy") + visible: method === NetType.Manual + weight: 70 + config: root.item.manualProxy.socks + onHasUrlChanged: { + if (hasUrl) { + inputItem |= 0x08 + } else { + inputItem &= ~0x08 + } } } - } - DccObject { - id: ignoreHosts - property var config: root.item.manualProxy.ignoreHosts + DccObject { + id: ignoreHosts + property var config: root.item.manualProxy.ignoreHosts - name: "ignoreHosts" - parentName: root.name + "/body" - visible: method === NetType.Manual - weight: 80 - pageType: DccObject.Item - page: TextArea { - wrapMode: TextEdit.WordWrap - text: dccObj.config - onTextChanged: { - if (dccObj.config !== text) { - dccObj.config = text + name: "ignoreHosts" + parentName: root.name + "/menu/body" + visible: method === NetType.Manual + weight: 80 + pageType: DccObject.Item + page: TextArea { + wrapMode: TextEdit.WordWrap + text: dccObj.config + onTextChanged: { + if (dccObj.config !== text) { + dccObj.config = text + } } } } - } - DccObject { - name: "ignoreHostsTips" - parentName: root.name + "/body" - displayName: qsTr("Ignore the proxy configurations for the above hosts and domains") - weight: 90 - visible: ignoreHosts.visibleToApp - pageType: DccObject.Item - page: Label { - text: dccObj.displayName - wrapMode: Text.WordWrap + DccObject { + name: "ignoreHostsTips" + parentName: root.name + "/menu/body" + displayName: qsTr("Ignore the proxy configurations for the above hosts and domains") + weight: 90 + visible: ignoreHosts.visibleToApp + pageType: DccObject.Item + page: Label { + text: dccObj.displayName + wrapMode: Text.WordWrap + } } } - } - DccObject { - name: "footer" - parentName: root.name - pageType: DccObject.Item DccObject { - name: "spacer" - parentName: root.name + "/footer" - visible: method !== NetType.None - weight: 20 + name: "footer" + parentName: root.name + "/menu" pageType: DccObject.Item - page: Item { - Layout.fillWidth: true + DccObject { + name: "spacer" + parentName: root.name + "/menu/footer" + visible: method !== NetType.None + weight: 20 + pageType: DccObject.Item + page: Item { + Layout.fillWidth: true + } } - } - DccObject { - name: "cancel" - parentName: root.name + "/footer" - visible: method !== NetType.None - displayName: qsTr("Cancel") - weight: 30 - pageType: DccObject.Item - page: Button { - implicitHeight: implicitContentHeight + 10 - implicitWidth: implicitContentWidth + 10 - topPadding: 0 - bottomPadding: 0 - leftPadding: 0 - rightPadding: 0 - spacing: 0 - text: dccObj.displayName - Layout.alignment: Qt.AlignRight - onClicked: root.resetData() + DccObject { + name: "cancel" + parentName: root.name + "/menu/footer" + visible: method !== NetType.None + displayName: qsTr("Cancel") + weight: 30 + pageType: DccObject.Item + page: Button { + implicitHeight: implicitContentHeight + 10 + implicitWidth: implicitContentWidth + 10 + topPadding: 0 + bottomPadding: 0 + leftPadding: 0 + rightPadding: 0 + spacing: 0 + text: dccObj.displayName + Layout.alignment: Qt.AlignRight + onClicked: root.resetData() + } } - } - DccObject { - name: "Save" - parentName: root.name + "/footer" - displayName: qsTr("Save") - visible: method !== NetType.None - weight: 40 - pageType: DccObject.Item - page: Button { - implicitHeight: implicitContentHeight + 10 - implicitWidth: implicitContentWidth + 10 - topPadding: 0 - bottomPadding: 0 - leftPadding: 0 - rightPadding: 0 - spacing: 0 - enabled: (method === NetType.Auto && (inputItem & 0xf0)) || (method === NetType.Manual && (inputItem & 0x0f)) - text: dccObj.displayName - Layout.alignment: Qt.AlignRight - function printfObj(obj) { - for (let k in obj) { - console.log(k, obj[k]) + DccObject { + name: "Save" + parentName: root.name + "/menu/footer" + displayName: qsTr("Save") + visible: method !== NetType.None + weight: 40 + pageType: DccObject.Item + page: Button { + implicitHeight: implicitContentHeight + 10 + implicitWidth: implicitContentWidth + 10 + topPadding: 0 + bottomPadding: 0 + leftPadding: 0 + rightPadding: 0 + spacing: 0 + enabled: (method === NetType.Auto && (inputItem & 0xf0)) || (method === NetType.Manual && (inputItem & 0x0f)) + text: dccObj.displayName + Layout.alignment: Qt.AlignRight + function printfObj(obj) { + for (let k in obj) { + console.log(k, obj[k]) + } } - } - onClicked: { - console.log("save:", method) - console.log("autoUrl.config :", autoUrl.config) - console.log("http.config:", http.config) - printfObj(http.config) - console.log("https.config:", https.config) - printfObj(https.config) - console.log("ftp.config:", ftp.config) - printfObj(ftp.config) - console.log("socks.config:", socks.config) - printfObj(socks.config) - console.log("ignoreHosts.config:", ignoreHosts.config) - let config = {} - switch (method) { - case NetType.None: - break - case NetType.Auto: - autoUrlAlert = false - if (autoUrl.config.length === 0) { - autoUrlAlert = true - return - } + onClicked: { + console.log("save:", method) + console.log("autoUrl.config :", autoUrl.config) + console.log("http.config:", http.config) + printfObj(http.config) + console.log("https.config:", https.config) + printfObj(https.config) + console.log("ftp.config:", ftp.config) + printfObj(ftp.config) + console.log("socks.config:", socks.config) + printfObj(socks.config) + console.log("ignoreHosts.config:", ignoreHosts.config) + let config = {} + switch (method) { + case NetType.None: + break + case NetType.Auto: + autoUrlAlert = false + if (autoUrl.config.length === 0) { + autoUrlAlert = true + return + } - config["autoUrl"] = autoUrl.config - break - case NetType.Manual: - if (!http.checkInput() || !https.checkInput() || !ftp.checkInput() || !socks.checkInput()) { - return - } - config["httpAddr"] = http.config["url"] - config["httpPort"] = http.config["port"] - config["httpAuth"] = http.config["auth"] - config["httpUser"] = http.config["user"] - config["httpPassword"] = http.config["password"] + config["autoUrl"] = autoUrl.config + break + case NetType.Manual: + if (!http.checkInput() || !https.checkInput() || !ftp.checkInput() || !socks.checkInput()) { + return + } + config["httpAddr"] = http.config["url"] + config["httpPort"] = http.config["port"] + config["httpAuth"] = http.config["auth"] + config["httpUser"] = http.config["user"] + config["httpPassword"] = http.config["password"] - config["httpsAddr"] = https.config["url"] - config["httpsPort"] = https.config["port"] - config["httpsAuth"] = https.config["auth"] - config["httpsUser"] = https.config["user"] - config["httpsPassword"] = https.config["password"] + config["httpsAddr"] = https.config["url"] + config["httpsPort"] = https.config["port"] + config["httpsAuth"] = https.config["auth"] + config["httpsUser"] = https.config["user"] + config["httpsPassword"] = https.config["password"] - config["ftpAddr"] = ftp.config["url"] - config["ftpPort"] = ftp.config["port"] - config["ftpAuth"] = ftp.config["auth"] - config["ftpUser"] = ftp.config["user"] - config["ftpPassword"] = ftp.config["password"] + config["ftpAddr"] = ftp.config["url"] + config["ftpPort"] = ftp.config["port"] + config["ftpAuth"] = ftp.config["auth"] + config["ftpUser"] = ftp.config["user"] + config["ftpPassword"] = ftp.config["password"] - config["socksAddr"] = socks.config["url"] - config["socksPort"] = socks.config["port"] - config["socksAuth"] = socks.config["auth"] - config["socksUser"] = socks.config["user"] - config["socksPassword"] = socks.config["password"] - config["ignoreHosts"] = ignoreHosts.config - break + config["socksAddr"] = socks.config["url"] + config["socksPort"] = socks.config["port"] + config["socksAuth"] = socks.config["auth"] + config["socksUser"] = socks.config["user"] + config["socksPassword"] = socks.config["password"] + config["ignoreHosts"] = ignoreHosts.config + break + } + config["method"] = method + dccData.exec(NetManager.SetConnectInfo, item.id, config) } - config["method"] = method - dccData.exec(NetManager.SetConnectInfo, item.id, config) } } } diff --git a/dcc-network/qml/PageVPN.qml b/dcc-network/qml/PageVPN.qml index b56ab345c..ec24fbee3 100644 --- a/dcc-network/qml/PageVPN.qml +++ b/dcc-network/qml/PageVPN.qml @@ -19,7 +19,8 @@ DccObject { displayName: qsTr("VPN") description: qsTr("Connect, add, import") icon: "dcc_vpn" - page: DccSettingsView {} + pageType: DccObject.MenuEditor + page: devCheck Component { id: devCheck D.Switch { @@ -30,220 +31,224 @@ DccObject { } } } - DccObject { - name: "body" + name: "menu" parentName: root.name - pageType: DccObject.Item - DccObject { - name: "title" - parentName: root.name + "/body" - displayName: root.displayName - icon: "dcc_vpn" - weight: 10 - backgroundType: DccObject.Normal - pageType: DccObject.Editor - page: devCheck - } + page: DccSettingsView {} DccObject { - name: "networkList" - parentName: root.name + "/body" - weight: 20 + name: "body" + parentName: root.name + "/menu" pageType: DccObject.Item - backgroundType: DccObject.Normal - page: ColumnLayout { - clip: true - spacing: 0 - Repeater { - id: repeater - model: NetItemModel { - root: item - } + DccObject { + name: "title" + parentName: root.name + "/menu/body" + displayName: root.displayName + icon: "dcc_vpn" + weight: 10 + backgroundType: DccObject.Normal + pageType: DccObject.Editor + page: devCheck + } + DccObject { + name: "networkList" + parentName: root.name + "/menu/body" + weight: 20 + pageType: DccObject.Item + backgroundType: DccObject.Normal + page: ColumnLayout { + clip: true + spacing: 0 + Repeater { + id: repeater + model: NetItemModel { + root: item + } - delegate: ItemDelegate { - id: itemDelegate - implicitHeight: 36 - text: model.item.name - hoverEnabled: true - checked: true - backgroundVisible: false - corners: getCornersForBackground(index, repeater.count) - cascadeSelected: true - Layout.fillWidth: true - content: RowLayout { - BusyIndicator { - running: model.item.status === NetType.CS_Connecting - visible: running - } - DccCheckIcon { - visible: model.item.status === NetType.CS_Connected && !itemDelegate.hovered - } - NetButton { - implicitHeight: implicitContentHeight - 4 - topInset: -4 - bottomInset: -4 - visible: model.item.status !== NetType.CS_Connecting && itemDelegate.hovered - text: model.item.status === NetType.CS_Connected ? qsTr("Disconnect") : qsTr("Connect") - Layout.alignment: Qt.AlignCenter - onClicked: { - dccData.exec(model.item.status === NetType.CS_Connected ? NetManager.Disconnect : NetManager.ConnectOrInfo, model.item.id, {}) + delegate: ItemDelegate { + id: itemDelegate + implicitHeight: 36 + text: model.item.name + hoverEnabled: true + checked: true + backgroundVisible: false + corners: getCornersForBackground(index, repeater.count) + cascadeSelected: true + Layout.fillWidth: true + content: RowLayout { + BusyIndicator { + running: model.item.status === NetType.CS_Connecting + visible: running } - } - D.IconLabel { - icon { - name: "arrow_ordinary_right" - palette: D.DTK.makeIconPalette(palette) + DccCheckIcon { + visible: model.item.status === NetType.CS_Connected && !itemDelegate.hovered } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton + NetButton { + implicitHeight: implicitContentHeight - 4 + topInset: -4 + bottomInset: -4 + visible: model.item.status !== NetType.CS_Connecting && itemDelegate.hovered + text: model.item.status === NetType.CS_Connected ? qsTr("Disconnect") : qsTr("Connect") + Layout.alignment: Qt.AlignCenter onClicked: { - dccData.exec(NetManager.ConnectInfo, model.item.id, {}) + dccData.exec(model.item.status === NetType.CS_Connected ? NetManager.Disconnect : NetManager.ConnectOrInfo, model.item.id, {}) + } + } + D.IconLabel { + icon { + name: "arrow_ordinary_right" + palette: D.DTK.makeIconPalette(palette) + } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton + onClicked: { + dccData.exec(NetManager.ConnectInfo, model.item.id, {}) + } } } } - } - onDoubleClicked: { - if (model.item.status === NetType.CS_UnConnected) { - dccData.exec(NetManager.ConnectOrInfo, model.item.id, {}) + onDoubleClicked: { + if (model.item.status === NetType.CS_UnConnected) { + dccData.exec(NetManager.ConnectOrInfo, model.item.id, {}) + } + } + background: DccItemBackground { + separatorVisible: true } - } - background: DccItemBackground { - separatorVisible: true } } } - } - PageVPNSettings { - id: vpnSettings - name: "vpnSettings" - parentName: root.name + "/body/networkList" - onFinished: DccApp.showPage(root) - Connections { - target: dccData - function onRequest(cmd, id, param) { - if (cmd !== NetManager.ConnectInfo) { - return - } - const items = new Array(root.item) - while (items.length !== 0) { - let tmpItem = items[0] - if (tmpItem.id === id) { - if (tmpItem.itemType === NetType.VPNControlItem) { - vpnSettings.displayName = qsTr("Add VPN") - } else { - vpnSettings.displayName = tmpItem.name - } - vpnSettings.item = tmpItem - vpnSettings.setConfig(param) - - DccApp.showPage(vpnSettings) - break + PageVPNSettings { + id: vpnSettings + name: "vpnSettings" + parentName: root.name + "/menu/body/networkList" + onFinished: DccApp.showPage(root) + Connections { + target: dccData + function onRequest(cmd, id, param) { + if (cmd !== NetManager.ConnectInfo) { + return } - for (let i in tmpItem.children) { - items.push(tmpItem.children[i]) + const items = new Array(root.item) + while (items.length !== 0) { + let tmpItem = items[0] + if (tmpItem.id === id) { + if (tmpItem.itemType === NetType.VPNControlItem) { + vpnSettings.displayName = qsTr("Add VPN") + } else { + vpnSettings.displayName = tmpItem.name + } + vpnSettings.item = tmpItem + vpnSettings.setConfig(param) + + DccApp.showPage(vpnSettings) + break + } + for (let i in tmpItem.children) { + items.push(tmpItem.children[i]) + } + items.shift() } - items.shift() } } } } } - } - DccObject { - name: "footer" - parentName: root.name - pageType: DccObject.Item - DccObject { - name: "spacer" - parentName: root.name + "/footer" - weight: 20 - pageType: DccObject.Item - page: Item { - Layout.fillWidth: true - } - } DccObject { - name: "importVPN" - parentName: root.name + "/footer" - weight: 30 + name: "footer" + parentName: root.name + "/menu" pageType: DccObject.Item - page: NetButton { - text: qsTr("Import VPN") - Layout.alignment: Qt.AlignRight - onClicked: { - importFileDialog.createObject(this).open() + DccObject { + name: "spacer" + parentName: root.name + "/menu/footer" + weight: 20 + pageType: DccObject.Item + page: Item { + Layout.fillWidth: true } } - Connections { - target: dccData - function onRequest(cmd, id, param) { - if (cmd === NetManager.ImportError && id === root.item.id) { - importErrorDialog.createObject(this).show() + DccObject { + name: "importVPN" + parentName: root.name + "/menu/footer" + weight: 30 + pageType: DccObject.Item + page: NetButton { + text: qsTr("Import VPN") + Layout.alignment: Qt.AlignRight + onClicked: { + importFileDialog.createObject(this).open() } } - } - - Component { - id: importFileDialog - FileDialog { - visible: false - nameFilters: [qsTr("*.conf")] - onAccepted: { - dccData.exec(NetManager.ImportConnect, item.id, { - "file": currentFile.toString().replace("file://", "") - }) - this.destroy(10) + Connections { + target: dccData + function onRequest(cmd, id, param) { + if (cmd === NetManager.ImportError && id === root.item.id) { + importErrorDialog.createObject(this).show() + } } - onRejected: this.destroy(10) } - } - Component { - id: importErrorDialog - D.DialogWindow { - modality: Qt.ApplicationModal - width: 380 - icon: "dialog-error" - onClosing: this.destroy(10) - ColumnLayout { - width: parent.width - Label { - Layout.fillWidth: true - Layout.leftMargin: 50 - Layout.rightMargin: 50 - text: qsTr("Import Error") - font.bold: true - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter - } - Label { - Layout.fillWidth: true - Layout.leftMargin: 50 - Layout.rightMargin: 50 - text: qsTr("File error") - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter + + Component { + id: importFileDialog + FileDialog { + visible: false + nameFilters: [qsTr("*.conf")] + onAccepted: { + dccData.exec(NetManager.ImportConnect, item.id, { + "file": currentFile.toString().replace("file://", "") + }) + this.destroy(10) } - Button { - Layout.fillWidth: true - Layout.margins: 10 - text: qsTr("OK") - onClicked: close() + onRejected: this.destroy(10) + } + } + Component { + id: importErrorDialog + D.DialogWindow { + modality: Qt.ApplicationModal + width: 380 + icon: "dialog-error" + onClosing: this.destroy(10) + ColumnLayout { + width: parent.width + Label { + Layout.fillWidth: true + Layout.leftMargin: 50 + Layout.rightMargin: 50 + text: qsTr("Import Error") + font.bold: true + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + } + Label { + Layout.fillWidth: true + Layout.leftMargin: 50 + Layout.rightMargin: 50 + text: qsTr("File error") + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + } + Button { + Layout.fillWidth: true + Layout.margins: 10 + text: qsTr("OK") + onClicked: close() + } } } } } - } - DccObject { - name: "addVPN" - parentName: root.name + "/footer" - weight: 40 - pageType: DccObject.Item - page: NetButton { - text: qsTr("Add VPN") - Layout.alignment: Qt.AlignRight - onClicked: { - dccData.exec(NetManager.ConnectInfo, item.id, {}) + DccObject { + name: "addVPN" + parentName: root.name + "/menu/footer" + weight: 40 + pageType: DccObject.Item + page: NetButton { + text: qsTr("Add VPN") + Layout.alignment: Qt.AlignRight + onClicked: { + dccData.exec(NetManager.ConnectInfo, item.id, {}) + } } } } diff --git a/dcc-network/qml/PageWiredDevice.qml b/dcc-network/qml/PageWiredDevice.qml index 5694e61d3..127e9513f 100644 --- a/dcc-network/qml/PageWiredDevice.qml +++ b/dcc-network/qml/PageWiredDevice.qml @@ -11,10 +11,20 @@ import org.deepin.dtk 1.0 as D import org.deepin.dcc 1.0 import org.deepin.dcc.network 1.0 +import "NetUtils.js" as NetUtils + DccObject { id: root property var item: null + component DevCheck: D.Switch { + checked: item.isEnabled + enabled: item.enabledable + onClicked: { + dccData.exec(item.isEnabled ? NetManager.DisabledDevice : NetManager.EnabledDevice, item.id, {}) + } + } + name: "wired" + item.pathIndex parentName: "network" displayName: item.name @@ -23,19 +33,11 @@ DccObject { icon: "dcc_ethernet" weight: 1010 + item.pathIndex pageType: DccObject.MenuEditor - page: devCheck - - Component { - id: devCheck - RowLayout { - D.Switch { - checked: item.isEnabled - enabled: item.enabledable - onClicked: { - dccData.exec(item.isEnabled ? NetManager.DisabledDevice : NetManager.EnabledDevice, item.id, {}) - } - } + page: RowLayout { + DccLabel { + text: NetUtils.getStatusName(item.status) } + DevCheck {} } DccObject { @@ -54,7 +56,7 @@ DccObject { weight: 10 backgroundType: DccObject.Normal pageType: DccObject.Editor - page: devCheck + page: DevCheck {} } DccObject { name: "nocable" @@ -100,9 +102,9 @@ DccObject { cascadeSelected: true Layout.fillWidth: true leftPadding: 10 - rightPadding: 0 // 移除右边距,让箭头区域能扩展到边缘 - topPadding: 0 // 恢复适量上边距 - bottomPadding: 0 // 恢复适量下边距 + rightPadding: 0 // 移除右边距,让箭头区域能扩展到边缘 + topPadding: 0 // 恢复适量上边距 + bottomPadding: 0 // 恢复适量下边距 spacing: 10 icon { name: "network-online-symbolic" @@ -129,52 +131,52 @@ DccObject { dccData.exec(model.item.status === NetType.CS_Connected ? NetManager.Disconnect : NetManager.ConnectOrInfo, model.item.id, {}) } } - + // 箭头悬浮效果 - 右侧圆角(包含分割线) Item { - width: 30 // 20px悬浮区域 + 10px扩展到边缘 + width: 30 // 20px悬浮区域 + 10px扩展到边缘 height: 40 // 填满ItemDelegate高度 - + Canvas { id: hoverCanvas anchors.fill: parent property color bgColor: "transparent" - + onPaint: { var ctx = getContext("2d") ctx.clearRect(0, 0, width, height) - + if (bgColor.a > 0) { ctx.fillStyle = bgColor ctx.beginPath() - + // 绘制右侧圆角的矩形 - ctx.moveTo(0, 0) // 左上角 - ctx.lineTo(width - 6, 0) // 右上角前 - ctx.arcTo(width, 0, width, 6, 6) // 右上圆角 - ctx.lineTo(width, height - 6) // 右下角前 + ctx.moveTo(0, 0) // 左上角 + ctx.lineTo(width - 6, 0) // 右上角前 + ctx.arcTo(width, 0, width, 6, 6) // 右上圆角 + ctx.lineTo(width, height - 6) // 右下角前 ctx.arcTo(width, height, width - 6, height, 6) // 右下圆角 - ctx.lineTo(0, height) // 左下角 - ctx.lineTo(0, 0) // 回到左上角 - + ctx.lineTo(0, height) // 左下角 + ctx.lineTo(0, 0) // 回到左上角 + ctx.fill() } } - + onBgColorChanged: requestPaint() } - + // 分割线 - 一直显示 Rectangle { width: 1 height: 20 anchors.left: parent.left - anchors.leftMargin: 0 // 在悬浮区域最左边 + anchors.leftMargin: 0 // 在悬浮区域最左边 anchors.verticalCenter: parent.verticalCenter color: palette.windowText opacity: 0.05 } - + D.IconLabel { anchors.centerIn: parent icon { @@ -182,28 +184,28 @@ DccObject { palette: D.DTK.makeIconPalette(palette) } } - + MouseArea { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.LeftButton - + onClicked: { dccData.exec(NetManager.ConnectInfo, model.item.id, {}) } - + onEntered: { hoverCanvas.bgColor = Qt.rgba(palette.windowText.r, palette.windowText.g, palette.windowText.b, 0.1) } - + onExited: { hoverCanvas.bgColor = "transparent" } - + onPressed: { hoverCanvas.bgColor = Qt.rgba(palette.windowText.r, palette.windowText.g, palette.windowText.b, 0.2) } - + onReleased: { if (containsMouse) { hoverCanvas.bgColor = Qt.rgba(palette.windowText.r, palette.windowText.g, palette.windowText.b, 0.1) diff --git a/dcc-network/qml/PageWirelessDevice.qml b/dcc-network/qml/PageWirelessDevice.qml index 6b675ba3a..03b633647 100644 --- a/dcc-network/qml/PageWirelessDevice.qml +++ b/dcc-network/qml/PageWirelessDevice.qml @@ -11,12 +11,21 @@ import org.deepin.dtk 1.0 as D import org.deepin.dcc 1.0 import org.deepin.dcc.network 1.0 +import "NetUtils.js" as NetUtils + DccObject { id: root property var item: null property var airplaneItem: null readonly property var c_levelString: ["-signal-no", "-signal-low", "-signal-medium", "-signal-high", "-signal-full"] + component DevCheck: D.Switch { + checked: root.item.isEnabled + enabled: root.item.enabledable + onClicked: { + dccData.exec(root.item.isEnabled ? NetManager.DisabledDevice : NetManager.EnabledDevice, root.item.id, {}) + } + } name: "wireless" + item.pathIndex parentName: "network" displayName: item.name @@ -25,19 +34,30 @@ DccObject { icon: "dcc_wifi" weight: 2010 + item.pathIndex pageType: DccObject.MenuEditor - page: devCheck - - Component { - id: devCheck - RowLayout { - D.Switch { - checked: root.item.isEnabled - enabled: root.item.enabledable - onClicked: { - dccData.exec(root.item.isEnabled ? NetManager.DisabledDevice : NetManager.EnabledDevice, root.item.id, {}) + page: RowLayout { + DccLabel { + text: { + switch (item.status) { + case NetType.DS_Connected: + case NetType.DS_ConnectNoInternet: + var childrenItem = [item] + while (childrenItem.length > 0) { + var childItem = childrenItem.pop() + if (childItem.itemType === NetType.WirelessItem && childItem.status === NetType.CS_Connected) { + return childItem.name + } + for (let i in childItem.children) { + childrenItem.push(childItem.children[i]) + } + } + break + default: + break } + return NetUtils.getStatusName(item.status) } } + DevCheck {} } Component { @@ -66,9 +86,9 @@ DccObject { cascadeSelected: true Layout.fillWidth: true leftPadding: 10 - rightPadding: 0 // 移除右边距,让箭头区域能扩展到边缘 - topPadding: 0 // 恢复适量上边距 - bottomPadding: 0 // 恢复适量下边距 + rightPadding: 0 // 移除右边距,让箭头区域能扩展到边缘 + topPadding: 0 // 恢复适量上边距 + bottomPadding: 0 // 恢复适量下边距 spacing: 10 icon { name: "network-wireless" + (item.flags ? "-6" : "") + c_levelString[item.strengthLevel] + (item.secure ? "-secure" : "") + "-symbolic" @@ -95,52 +115,52 @@ DccObject { dccData.exec(model.item.status === NetType.CS_Connected ? NetManager.Disconnect : NetManager.ConnectOrInfo, model.item.id, {}) } } - + // 箭头悬浮效果 - 右侧圆角(包含分割线) Item { - width: 30 // 20px悬浮区域 + 10px扩展到边缘 + width: 30 // 20px悬浮区域 + 10px扩展到边缘 height: 40 // 填满ItemDelegate高度 - + Canvas { id: hoverCanvas anchors.fill: parent property color bgColor: "transparent" - + onPaint: { var ctx = getContext("2d") ctx.clearRect(0, 0, width, height) - + if (bgColor.a > 0) { ctx.fillStyle = bgColor ctx.beginPath() - + // 绘制右侧圆角的矩形 - ctx.moveTo(0, 0) // 左上角 - ctx.lineTo(width - 6, 0) // 右上角前 - ctx.arcTo(width, 0, width, 6, 6) // 右上圆角 - ctx.lineTo(width, height - 6) // 右下角前 + ctx.moveTo(0, 0) // 左上角 + ctx.lineTo(width - 6, 0) // 右上角前 + ctx.arcTo(width, 0, width, 6, 6) // 右上圆角 + ctx.lineTo(width, height - 6) // 右下角前 ctx.arcTo(width, height, width - 6, height, 6) // 右下圆角 - ctx.lineTo(0, height) // 左下角 - ctx.lineTo(0, 0) // 回到左上角 - + ctx.lineTo(0, height) // 左下角 + ctx.lineTo(0, 0) // 回到左上角 + ctx.fill() } } - + onBgColorChanged: requestPaint() } - + // 分割线 - 一直显示 Rectangle { width: 1 height: 20 anchors.left: parent.left - anchors.leftMargin: 0 // 在悬浮区域最左边 + anchors.leftMargin: 0 // 在悬浮区域最左边 anchors.verticalCenter: parent.verticalCenter color: palette.windowText opacity: 0.05 } - + D.IconLabel { anchors.centerIn: parent icon { @@ -148,28 +168,28 @@ DccObject { palette: D.DTK.makeIconPalette(palette) } } - + MouseArea { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.LeftButton - + onClicked: { dccData.exec(NetManager.ConnectInfo, model.item.id, {}) } - + onEntered: { hoverCanvas.bgColor = Qt.rgba(palette.windowText.r, palette.windowText.g, palette.windowText.b, 0.1) } - + onExited: { hoverCanvas.bgColor = "transparent" } - + onPressed: { hoverCanvas.bgColor = Qt.rgba(palette.windowText.r, palette.windowText.g, palette.windowText.b, 0.2) } - + onReleased: { if (containsMouse) { hoverCanvas.bgColor = Qt.rgba(palette.windowText.r, palette.windowText.g, palette.windowText.b, 0.1) @@ -228,7 +248,7 @@ DccObject { weight: 10 backgroundType: DccObject.Normal pageType: DccObject.Editor - page: devCheck + page: DevCheck {} } DccObject { name: "mineTitle" diff --git a/dcc-network/qml/networkMain.qml b/dcc-network/qml/networkMain.qml index 090d62537..123804f2b 100644 --- a/dcc-network/qml/networkMain.qml +++ b/dcc-network/qml/networkMain.qml @@ -111,7 +111,17 @@ DccObject { property var showPage: root.showPage } } - + DccTitleObject { + name: "connectionSettings" + parentName: "network" + displayName: qsTr("Connection settings") + weight: 5 + onParentItemChanged: { + if (parentItem) { + parentItem.topPadding = 10 + } + } + } PageVPN { id: vpnPage property var showPage: root.showPage @@ -119,19 +129,23 @@ DccObject { parentName: "network" weight: 3010 } - PageSystemProxy { - id: systemProxyPage + PageDSL { + id: dslPage property var showPage: root.showPage - name: "systemProxy" + name: "dsl" parentName: "network" weight: 3020 } - PageAppProxy { - id: appProxyPage - property var showPage: root.showPage - name: "applicationProxy" + DccTitleObject { + name: "relatedSettings" parentName: "network" - weight: 3030 + displayName: qsTr("Related Settings") + weight: 3025 + onParentItemChanged: { + if (parentItem) { + parentItem.topPadding = 10 + } + } } PageHotspot { id: hotspotPage @@ -139,19 +153,26 @@ DccObject { name: "personalHotspot" parentName: "network" isAirplane: dccData.root.isEnabled - weight: 3040 + weight: 3030 } PageAirplane { name: "airplaneMode" property var showPage: root.showPage parentName: "network" - weight: 3050 + weight: 3040 item: dccData.root } - PageDSL { - id: dslPage + PageSystemProxy { + id: systemProxyPage property var showPage: root.showPage - name: "dsl" + name: "systemProxy" + parentName: "network" + weight: 3050 + } + PageAppProxy { + id: appProxyPage + property var showPage: root.showPage + name: "applicationProxy" parentName: "network" weight: 3060 } diff --git a/net-view/operation/netitem.h b/net-view/operation/netitem.h index 1473fcc5f..f9fb0ae4e 100644 --- a/net-view/operation/netitem.h +++ b/net-view/operation/netitem.h @@ -23,8 +23,8 @@ class NetItemPrivate; class NetItem : public QObject { Q_OBJECT - Q_PROPERTY(QString id READ id) - Q_PROPERTY(NetType::NetItemType itemType READ itemType) + Q_PROPERTY(QString id READ id FINAL) + Q_PROPERTY(NetType::NetItemType itemType READ itemType CONSTANT) Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QVector children READ getChildren NOTIFY childrenChanged DESIGNABLE false)