controlcenter: polished ethernet panel
This commit is contained in:
parent
1debf488ee
commit
817156aec0
4 changed files with 205 additions and 57 deletions
|
|
@ -16,6 +16,20 @@ Item {
|
||||||
required property Session session
|
required property Session session
|
||||||
readonly property var device: session.ethernet.active
|
readonly property var device: session.ethernet.active
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (device && device.interface) {
|
||||||
|
Network.updateEthernetDeviceDetails(device.interface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeviceChanged: {
|
||||||
|
if (device && device.interface) {
|
||||||
|
Network.updateEthernetDeviceDetails(device.interface);
|
||||||
|
} else {
|
||||||
|
Network.ethernetDeviceDetails = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StyledFlickable {
|
StyledFlickable {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|
@ -79,9 +93,8 @@ Item {
|
||||||
checked: root.device?.connected ?? false
|
checked: root.device?.connected ?? false
|
||||||
toggle.onToggled: {
|
toggle.onToggled: {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
if (root.device?.connection) {
|
// Use connection name if available, otherwise use interface
|
||||||
Network.connectEthernet(root.device.connection);
|
Network.connectEthernet(root.device?.connection || "", root.device?.interface || "");
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (root.device?.connection) {
|
if (root.device?.connection) {
|
||||||
Network.disconnectEthernet(root.device.connection);
|
Network.disconnectEthernet(root.device.connection);
|
||||||
|
|
@ -155,6 +168,82 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.topMargin: Appearance.spacing.large
|
||||||
|
text: qsTr("Connection information")
|
||||||
|
font.pointSize: Appearance.font.size.larger
|
||||||
|
font.weight: 500
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: qsTr("Network connection details")
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: connectionInfo.implicitHeight + Appearance.padding.large * 2
|
||||||
|
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
color: Colours.tPalette.m3surfaceContainer
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: connectionInfo
|
||||||
|
|
||||||
|
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("IP Address")
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: Network.ethernetDeviceDetails?.ipAddress || qsTr("Not available")
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.topMargin: Appearance.spacing.normal
|
||||||
|
text: qsTr("Subnet Mask")
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: Network.ethernetDeviceDetails?.subnet || qsTr("Not available")
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.topMargin: Appearance.spacing.normal
|
||||||
|
text: qsTr("Gateway")
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: Network.ethernetDeviceDetails?.gateway || qsTr("Not available")
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
Layout.topMargin: Appearance.spacing.normal
|
||||||
|
text: qsTr("DNS Servers")
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: (Network.ethernetDeviceDetails && Network.ethernetDeviceDetails.dns && Network.ethernetDeviceDetails.dns.length > 0) ? Network.ethernetDeviceDetails.dns.join(", ") : qsTr("Not available")
|
||||||
|
color: Colours.palette.m3outline
|
||||||
|
font.pointSize: Appearance.font.size.small
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.maximumWidth: parent.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,8 +144,9 @@ ColumnLayout {
|
||||||
function onClicked(): void {
|
function onClicked(): void {
|
||||||
if (modelData.connected && modelData.connection) {
|
if (modelData.connected && modelData.connection) {
|
||||||
Network.disconnectEthernet(modelData.connection);
|
Network.disconnectEthernet(modelData.connection);
|
||||||
} else if (modelData.connection) {
|
} else {
|
||||||
Network.connectEthernet(modelData.connection);
|
// Use connection name if available, otherwise use interface
|
||||||
|
Network.connectEthernet(modelData.connection || "", modelData.interface || "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,56 +81,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.topMargin: Appearance.spacing.large
|
|
||||||
text: qsTr("Debug Info")
|
|
||||||
font.pointSize: Appearance.font.size.larger
|
|
||||||
font.weight: 500
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledRect {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
implicitHeight: debugInfo.implicitHeight + Appearance.padding.large * 2
|
|
||||||
|
|
||||||
radius: Appearance.rounding.normal
|
|
||||||
color: Colours.tPalette.m3surfaceContainer
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: debugInfo
|
|
||||||
|
|
||||||
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("Process running: %1").arg(Network.ethernetProcessRunning ? "Yes" : "No")
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: qsTr("List length: %1").arg(Network.ethernetDevices.length)
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: qsTr("Device count: %1").arg(Network.ethernetDeviceCount)
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
Layout.topMargin: Appearance.spacing.normal
|
|
||||||
text: qsTr("Debug: %1").arg(Network.ethernetDebugInfo || "No info")
|
|
||||||
font.pointSize: Appearance.font.size.small
|
|
||||||
color: Colours.palette.m3outline
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
Layout.maximumWidth: parent.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ Singleton {
|
||||||
property int ethernetDeviceCount: 0
|
property int ethernetDeviceCount: 0
|
||||||
property string ethernetDebugInfo: ""
|
property string ethernetDebugInfo: ""
|
||||||
property bool ethernetProcessRunning: false
|
property bool ethernetProcessRunning: false
|
||||||
|
property var ethernetDeviceDetails: null
|
||||||
|
|
||||||
function enableWifi(enabled: bool): void {
|
function enableWifi(enabled: bool): void {
|
||||||
const cmd = enabled ? "on" : "off";
|
const cmd = enabled ? "on" : "off";
|
||||||
|
|
@ -88,14 +89,46 @@ Singleton {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function connectEthernet(connectionName: string): void {
|
function connectEthernet(connectionName: string, interfaceName: string): void {
|
||||||
connectEthernetProc.exec(["nmcli", "connection", "up", connectionName]);
|
if (connectionName && connectionName.length > 0) {
|
||||||
|
// Use connection name if available
|
||||||
|
connectEthernetProc.exec(["nmcli", "connection", "up", connectionName]);
|
||||||
|
} else if (interfaceName && interfaceName.length > 0) {
|
||||||
|
// Fallback to device interface if no connection name
|
||||||
|
connectEthernetProc.exec(["nmcli", "device", "connect", interfaceName]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function disconnectEthernet(connectionName: string): void {
|
function disconnectEthernet(connectionName: string): void {
|
||||||
disconnectEthernetProc.exec(["nmcli", "connection", "down", connectionName]);
|
disconnectEthernetProc.exec(["nmcli", "connection", "down", connectionName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateEthernetDeviceDetails(interfaceName: string): void {
|
||||||
|
if (interfaceName && interfaceName.length > 0) {
|
||||||
|
getEthernetDetailsProc.exec(["nmcli", "device", "show", interfaceName]);
|
||||||
|
} else {
|
||||||
|
ethernetDeviceDetails = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cidrToSubnetMask(cidr: string): string {
|
||||||
|
// Convert CIDR notation (e.g., "24") to subnet mask (e.g., "255.255.255.0")
|
||||||
|
const cidrNum = parseInt(cidr);
|
||||||
|
if (isNaN(cidrNum) || cidrNum < 0 || cidrNum > 32) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const mask = (0xffffffff << (32 - cidrNum)) >>> 0;
|
||||||
|
const octets = [
|
||||||
|
(mask >>> 24) & 0xff,
|
||||||
|
(mask >>> 16) & 0xff,
|
||||||
|
(mask >>> 8) & 0xff,
|
||||||
|
mask & 0xff
|
||||||
|
];
|
||||||
|
|
||||||
|
return octets.join(".");
|
||||||
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
running: true
|
running: true
|
||||||
command: ["nmcli", "m"]
|
command: ["nmcli", "m"]
|
||||||
|
|
@ -484,6 +517,13 @@ Singleton {
|
||||||
|
|
||||||
onExited: {
|
onExited: {
|
||||||
getEthernetDevices();
|
getEthernetDevices();
|
||||||
|
// Refresh device details after connection
|
||||||
|
Qt.callLater(() => {
|
||||||
|
const activeDevice = root.ethernetDevices.find(function(d) { return d.connected; });
|
||||||
|
if (activeDevice && activeDevice.interface) {
|
||||||
|
updateEthernetDeviceDetails(activeDevice.interface);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: getEthernetDevices()
|
onRead: getEthernetDevices()
|
||||||
|
|
@ -503,6 +543,10 @@ Singleton {
|
||||||
|
|
||||||
onExited: {
|
onExited: {
|
||||||
getEthernetDevices();
|
getEthernetDevices();
|
||||||
|
// Clear device details after disconnection
|
||||||
|
Qt.callLater(() => {
|
||||||
|
root.ethernetDeviceDetails = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
onRead: getEthernetDevices()
|
onRead: getEthernetDevices()
|
||||||
|
|
@ -517,6 +561,70 @@ Singleton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: getEthernetDetailsProc
|
||||||
|
|
||||||
|
environment: ({
|
||||||
|
LANG: "C.UTF-8",
|
||||||
|
LC_ALL: "C.UTF-8"
|
||||||
|
})
|
||||||
|
stdout: StdioCollector {
|
||||||
|
onStreamFinished: {
|
||||||
|
const output = text.trim();
|
||||||
|
if (!output || output.length === 0) {
|
||||||
|
root.ethernetDeviceDetails = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lines = output.split("\n");
|
||||||
|
const details = {
|
||||||
|
ipAddress: "",
|
||||||
|
gateway: "",
|
||||||
|
dns: [],
|
||||||
|
subnet: "",
|
||||||
|
macAddress: "",
|
||||||
|
speed: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i];
|
||||||
|
const parts = line.split(":");
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
const key = parts[0].trim();
|
||||||
|
const value = parts.slice(1).join(":").trim();
|
||||||
|
|
||||||
|
if (key.startsWith("IP4.ADDRESS")) {
|
||||||
|
// Extract IP and subnet from format like "10.13.1.45/24"
|
||||||
|
const ipParts = value.split("/");
|
||||||
|
details.ipAddress = ipParts[0] || "";
|
||||||
|
if (ipParts[1]) {
|
||||||
|
// Convert CIDR notation to subnet mask
|
||||||
|
details.subnet = root.cidrToSubnetMask(ipParts[1]);
|
||||||
|
} else {
|
||||||
|
details.subnet = "";
|
||||||
|
}
|
||||||
|
} else if (key === "IP4.GATEWAY") {
|
||||||
|
details.gateway = value;
|
||||||
|
} else if (key.startsWith("IP4.DNS")) {
|
||||||
|
details.dns.push(value);
|
||||||
|
} else if (key === "WIRED-PROPERTIES.MAC") {
|
||||||
|
details.macAddress = value;
|
||||||
|
} else if (key === "WIRED-PROPERTIES.SPEED") {
|
||||||
|
details.speed = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root.ethernetDeviceDetails = details;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
root.ethernetDeviceDetails = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
component AccessPoint: QtObject {
|
component AccessPoint: QtObject {
|
||||||
required property var lastIpcObject
|
required property var lastIpcObject
|
||||||
readonly property string ssid: lastIpcObject.ssid
|
readonly property string ssid: lastIpcObject.ssid
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue