/* SPDX-FileCopyrightText: 2013-2017 Jan Grulich SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import QtQuick.Effects import org.kde.kquickcontrolsaddons as KQuickControlsAddons import org.kde.kirigami as Kirigami import org.kde.plasma.extras as PlasmaExtras import org.kde.plasma.components as PlasmaComponents3 import org.kde.plasma.networkmanagement as PlasmaNM import org.kde.plasma.plasmoid MouseArea { id: detailsMA implicitHeight: detailsGrid.height property var details: [] property var modelIndex: -1 property string networkName: "" property string uuid: "" property var connectionState: PlasmaNM.Enums.Deactivated property double rxBytes: 0 property double txBytes: 0 property double previousRxBytes: 0 property double previousTxBytes: 0 property var connectionModel: null function numberWithCommas(x) { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); } function getModelIndex() { if(uuid !== "" && connectionModel) { modelIndex = connectionModel.match(connectionModel.index(0, 0), PlasmaNM.NetworkModel.UuidRole, uuid)[0]; } else if(networkName !== "" && connectionModel) { modelIndex = connectionModel.match(connectionModel.index(0, 0), PlasmaNM.NetworkModel.ItemUniqueNameRole, networkName)[0]; } } Component.onCompleted: { getModelIndex(); } Timer { id: reloadTimer interval: 2000 repeat: true running: parent.modelIndex !== -1 triggeredOnStart: true // property int can overflow with the amount of bytes. onTriggered: { detailsMA.getModelIndex(); connectionState = detailsMA.connectionModel.data(modelIndex, PlasmaNM.NetworkModel.ConnectionStateRole); details = detailsMA.connectionModel.data(modelIndex, PlasmaNM.NetworkModel.ConnectionDetailsModelRole); detailsMA.Accessible.description = details.accessibilityDescription(); if(connectionState === PlasmaNM.Enums.Activated) { txBytes = detailsMA.connectionModel.data(modelIndex, PlasmaNM.NetworkModel.TxBytesRole); rxBytes = detailsMA.connectionModel.data(modelIndex, PlasmaNM.NetworkModel.RxBytesRole); if(txBytes !== previousTxBytes || rxBytes !== previousRxBytes) { detailsMA.colorizationOpacity = 0.8; colorizationTimer.start(); } previousRxBytes = rxBytes; previousTxBytes = txBytes; } } } property real colorizationOpacity: 0 Timer { id: colorizationTimer interval: 500 onTriggered: { detailsMA.colorizationOpacity = 0; } } acceptedButtons: Qt.RightButton onPressed: mouse => { const item = detailsGrid.childAt(mouse.x, mouse.y); if (!item || !item.isContent) { return; } contextMenu.show(this, item.text, mouse.x, mouse.y); } KQuickControlsAddons.Clipboard { id: clipboard } PlasmaExtras.Menu { id: contextMenu property string text function show(item, text, x, y) { contextMenu.text = text visualParent = item open(x, y) } PlasmaExtras.MenuItem { text: i18n("Copy") icon: "edit-copy" enabled: contextMenu.text !== "" onClicked: clipboard.content = contextMenu.text } } RowLayout { id: connectionText anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right spacing: Kirigami.Units.largeSpacing+1 Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.inherit: false PlasmaComponents3.Label { font: Kirigami.Theme.defaultFont text: i18n("Connection") textFormat: Text.PlainText } Rectangle { Layout.preferredHeight: 1 Layout.fillWidth: true color: "#a0a0a0" } } GridLayout { id: detailsGrid width: parent.width columns: 2 rowSpacing: 1 anchors.top: connectionText.bottom anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: Kirigami.Units.largeSpacing*2-1 anchors.rightMargin: Kirigami.Units.largeSpacing*2-1 anchors.topMargin: Kirigami.Units.smallSpacing Repeater { id: repeater model: details delegate: Item { id: delegateItem // Required properties from ConnectionDetailsModel required property bool isSection required property string sectionTitle required property string detailLabel required property string detailValue Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.inherit: false Layout.fillWidth: true Layout.columnSpan: 2 Layout.preferredHeight: { if (delegateItem.detailLabel || delegateItem.detailValue) { return detailLabelItem.implicitHeight; } return 0; // Hide empty items } // Detail Label PlasmaComponents3.Label { id: detailLabelItem // Renamed from labelItem anchors.left: parent.left anchors.right: parent.horizontalCenter anchors.rightMargin: detailsGrid.columnSpacing / 2 visible: !delegateItem.isSection && (delegateItem.detailLabel || delegateItem.detailValue) elide: Text.ElideNone font: Kirigami.Theme.defaultFont horizontalAlignment: Text.AlignLeft text: `${delegateItem.detailLabel}:` textFormat: Text.PlainText } // Detail Value PlasmaComponents3.Label { id: detailValueItem anchors.left: parent.horizontalCenter anchors.leftMargin: detailsGrid.columnSpacing / 2 anchors.right: parent.right visible: !delegateItem.isSection && (delegateItem.detailLabel || delegateItem.detailValue) elide: Text.ElideRight font: Kirigami.Theme.defaultFont horizontalAlignment: Text.AlignRight text: delegateItem.detailValue textFormat: Text.PlainText opacity: 1 MouseArea { anchors.fill: parent acceptedButtons: Qt.RightButton onPressed: mouse => { contextMenu.show(this, detailValueItem.text, mouse.x, mouse.y); } } } } } } RowLayout { id: activityText anchors.top: detailsGrid.bottom anchors.topMargin: Kirigami.Units.smallSpacing anchors.left: parent.left anchors.right: parent.right spacing: Kirigami.Units.largeSpacing+1 visible: detailsMA.connectionState === PlasmaNM.Enums.Activated Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.inherit: false PlasmaComponents3.Label { font: Kirigami.Theme.defaultFont text: i18n("Activity") textFormat: Text.PlainText } Rectangle { Layout.preferredHeight: 1 Layout.fillWidth: true color: "#a0a0a0" } } GridLayout { anchors.top: activityText.bottom anchors.topMargin: Kirigami.Units.smallSpacing anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: Kirigami.Units.largeSpacing*2-1 anchors.rightMargin: Kirigami.Units.largeSpacing*2-1 visible: detailsMA.connectionState === PlasmaNM.Enums.Activated rows: 2 columns: 5 rowSpacing: 0 Item { Layout.fillWidth: true } RowLayout { Layout.bottomMargin: Kirigami.Units.largeSpacing+2 Layout.rightMargin: Kirigami.Units.largeSpacing spacing: Kirigami.Units.mediumSpacing Text { text: i18n("Sent") } Rectangle { Layout.preferredHeight: 2; Layout.preferredWidth: 20; color: "#a0a0a0" } //Layout.alignment: Qt.AlignVCenter } Item { id: networkIcon Layout.preferredHeight: 48 Layout.preferredWidth: 48 Kirigami.Icon { source: "monitor" Layout.preferredHeight: Kirigami.Units.iconSizes.medium Layout.preferredWidth: Kirigami.Units.iconSizes.medium anchors.top: parent.top anchors.left: parent.left Kirigami.Icon { source: "monitor" anchors.top: parent.top anchors.left: parent.left anchors.leftMargin: 10 anchors.topMargin: -2 width: Kirigami.Units.iconSizes.medium height:Kirigami.Units.iconSizes.medium z: -1 } } Kirigami.Icon { anchors.bottom: parent.bottom anchors.right: parent.right source: "network-wired" Layout.preferredHeight: Kirigami.Units.iconSizes.small Layout.preferredWidth: Kirigami.Units.iconSizes.small roundToIconSize: false } layer.enabled: true layer.effect: MultiEffect { id: iconEffect colorization: detailsMA.colorizationOpacity colorizationColor: "#8bd6f9" } } Rectangle { Layout.bottomMargin: Kirigami.Units.largeSpacing+2; Layout.preferredHeight: 2; Layout.preferredWidth: 20; color: "#a0a0a0" } Text { text: i18n("Received"); Layout.alignment: Qt.AlignRight; Layout.bottomMargin: Kirigami.Units.largeSpacing+2 } Text { text: i18n("Bytes:"); Layout.fillWidth: true } Text { id: txText text: detailsMA.numberWithCommas(detailsMA.txBytes) Layout.preferredWidth: txTextMetrics.width TextMetrics { id: txTextMetrics font.family: txText.font.family text: txText.text.replace(/[0-9]/g, "0"); } } Rectangle { Layout.alignment: Qt.AlignHCenter; Layout.preferredWidth: 2; Layout.rightMargin: 2; Layout.preferredHeight: 16; color: "#a0a0a0" } Item { } Text { id: rxText text: detailsMA.numberWithCommas(detailsMA.rxBytes) Layout.preferredWidth: rxTextMetrics.width TextMetrics { id: rxTextMetrics font.family: rxText.font.family text: rxText.text.replace(/[0-9]/g, "0"); } } } }