punktdateien/kde/plasma/plasmoids/org.kde.nsw_dbus/contents/ui/CompactRepresentation.qml
2024-02-14 21:14:16 +01:00

991 lines
42 KiB
QML

/*
* Copyright 2023 LeeVD thoth360@hotmail.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http: //www.gnu.org/licenses/>.
*/
// useful:
// Run widget:
// plasmoidviewer -a org.kde.nbm_wip -l topedge -f horizontal
// serialised settings:
// home/user/.config/plasmoidviewer-appletsrc
import QtQuick 2.15
import QtQuick.Layouts 1.1
import org.kde.plasma.core 2.0 as PlasmaCore
//import org.kde.plasma.components 3.0 as PlasmaComponents // used in tooltip section
//import org.kde.plasma.extras 2.0 as PlasmaExtras // used in tooltip section
Item {
id: itemParent
anchors.fill: parent
property double marginFactor: 0.2
// PRIMARY UI INTERFACE DATA VARIABLES
property double downSpeed: 0
property double upSpeed: 0
property bool singleLine: {
if (!showSeparately) {
return true
}
switch (speedLayout) {
case 'row': return true // SIDE BY SIDE
case 'column': return false // ONE ABOVE OTHER
default: return height / 2 * fontSizeScale < theme.smallestFont.pixelSize && plasmoid.formFactor !== PlasmaCore.Types.Vertical
}
}
property double marginWidth: speedTextMetrics.font.pixelSize * marginFactor
property double iconWidth: showIcons ? iconTextMetrics.width + marginWidth : 0
property double doubleIconWidth: showIcons ? (doubleIconTextMetrics.width + marginWidth) : 0
property double speedWidth: speedTextMetrics.width + 2*marginWidth
property double unitWidth: showUnits ? unitTextMetrics.width + marginWidth : 0
//property double toolTipWidth: showTooltip ? TextMetrics2 : 0
property double aspectRatio: {
if (showSeparately) {
if (singleLine) {
return (2*iconWidth + 2*speedWidth + 2*unitWidth + marginWidth) * fontSizeScale / speedTextMetrics.height
} else {
return (iconWidth + speedWidth + unitWidth) * fontSizeScale / (2*speedTextMetrics.height)
}
} else {
return (doubleIconWidth + speedWidth + unitWidth) * fontSizeScale / speedTextMetrics.height
}
}
property double fontHeightRatio: speedTextMetrics.font.pixelSize / speedTextMetrics.height
property double offset: {
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
return (width - height * aspectRatio) / 2
} else {
return 0
}
}
property bool boolUnits: {
if (speedUnits !== 'bits') return false;
else return true;
}
property double getBinDec: {
if (binaryDecimal === 'binary') return 1024; // binary
else return 1000; // decimal
}
Layout.minimumWidth: {
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
return 0
} else if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) {
return Math.ceil(height * aspectRatio)
} else {
return Math.ceil(height * aspectRatio)
}
}
Layout.minimumHeight: {
if (plasmoid.formFactor === PlasmaCore.Types.Vertical) {
return Math.ceil(width / aspectRatio * fontSizeScale * fontSizeScale)
} else if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) {
return 0
} else {
return Math.ceil(theme.smallestFont.pixelSize / fontSizeScale)
}
}
Layout.preferredWidth: Layout.minimumWidth
Layout.preferredHeight: Layout.minimumHeight
TextMetrics {
id: iconTextMetrics
text: iconStyle(1)
font.pixelSize: 64
}
TextMetrics {
id: doubleIconTextMetrics
text: iconStyle(2)
font.pixelSize: 64
}
TextMetrics {
id: speedTextMetrics
text: getDecimalPlace() //'1000.0'
font.pixelSize: 64
}
TextMetrics {
id: unitTextMetrics
text: {
if (speedUnits === 'bits') {
return shortUnits ? 'm' : 'Mib/s'
} else {
return shortUnits ? 'M' : 'MiB/s'
}
}
font.pixelSize: 64
}
Item {
id: offsetItem
width: offset
height: parent.height
x: 0
y: 0
}
// USED FOR TESTING UI
// Rectangle{
// id: rec_t1
// height: dataShown('t1', 'height')
// width: dataShown('t1', 'width')
// anchors.left: dataShown('t1', 'anchorL')
// anchors.leftMargin: dataShown('t1', 'anchorLMargin')
// y: dataShown('t1', 'y')
// visible: true //dataShown('t1', 'visible')
// color: "red"
// }
// Rectangle{
// id: rec_t2
// height: dataShown('t2', 'height')
// width: dataShown('t2', 'width')
// anchors.left: dataShown('t2', 'anchorL')
// anchors.leftMargin: dataShown('t2', 'anchorLMargin')
// y: dataShown('t2', 'y')
// visible: true //dataShown('t2', 'visible')
// color: "blue"
// }
// Rectangle{
// id: rec_t3
// height: dataShown('t3', 'height')
// width: dataShown('t3', 'width')
// anchors.left: dataShown('t3', 'anchorL')
// anchors.leftMargin: dataShown('t3', 'anchorLMargin')
// y: dataShown('t3', 'y')
// visible: true //dataShown('t3', 'visible')
// color: "green"
// }
// Rectangle{
// id: rec_b1
// height: dataShown('b1', 'height')
// width: dataShown('b1', 'width')
// anchors.left: dataShown('b1', 'anchorL')
// anchors.leftMargin: dataShown('b1', 'anchorLMargin')
// y: dataShown('b1', 'y')
// visible: true //dataShown('b1', 'visible')
// color: "dark blue"
// }
// Rectangle{
// id: rec_b2
// height: dataShown('b2', 'height')
// width: dataShown('b2', 'width')
// anchors.left: dataShown('b2', 'anchorL')
// anchors.leftMargin: dataShown('b2', 'anchorLMargin')
// y: dataShown('b2', 'y')
// visible: true //dataShown('b2', 'visible')
// color: "purple"
// }
// Rectangle{
// id: rec_b3
// height: dataShown('b3', 'height')
// width: dataShown('b3', 'width')
// anchors.left: dataShown('b3', 'anchorL')
// anchors.leftMargin: dataShown('b3', 'anchorLMargin')
// y: dataShown('b3', 'y')
// visible: true //dataShown('b3', 'visible')
// color: "pink"
// }
Text {
id: t1 //topIcon
height: dataShown('t1', 'height')
width: dataShown('t1', 'width')
verticalAlignment: dataShown('t1', 'vertiAlign')
horizontalAlignment:dataShown('t1', 'horizAlign')
anchors.left: dataShown('t1', 'anchorL')
anchors.leftMargin: dataShown('t1', 'anchorLMargin')
y: dataShown('t1', 'y')
font.pixelSize: dataShown('t1', 'fontPixSize')
renderType: dataShown('t1', 'renderType')
text: dataShown('t1', 'text')
color: dataShown('t1', 'color')
visible: dataShown('t1', 'visible')
bottomPadding: dataShown('t1', 'padding') //-10.0
}
Text {
id: t2 //topText
height: dataShown('t2', 'height')
width: dataShown('t2', 'width')
verticalAlignment: dataShown('t2', 'vertiAlign')
horizontalAlignment:dataShown('t2', 'horizAlign')
anchors.left: dataShown('t2', 'anchorL')
anchors.leftMargin: dataShown('t2', 'anchorLMargin')
y: dataShown('t2', 'y')
font.pixelSize: dataShown('t2', 'fontPixSize')
renderType: dataShown('t2', 'renderType')
text: dataShown('t2', 'text')
color: dataShown('t2', 'color')
visible: dataShown('t2', 'visible')
bottomPadding: dataShown('t2', 'padding') //-10.0
}
Text {
id: t3 //topUnitText
height: dataShown('t3', 'height')
width: dataShown('t3', 'width')
verticalAlignment: dataShown('t3', 'vertiAlign')
horizontalAlignment:dataShown('t3', 'horizAlign')
anchors.left: dataShown('t3', 'anchorL')
anchors.leftMargin: dataShown('t3', 'anchorLMargin')
y: dataShown('t3', 'y')
font.pixelSize: dataShown('t3', 'fontPixSize')
renderType: dataShown('t3', 'renderType')
text: dataShown('t3', 'text')
color: dataShown('t3', 'color')
visible: dataShown('t3', 'visible')
bottomPadding: dataShown('t3', 'padding') //-10.0
}
Text {
id: b1 //bottomIcon
height: dataShown('b1', 'height')
width: dataShown('b1', 'width')
verticalAlignment: dataShown('b1', 'vertiAlign')
horizontalAlignment:dataShown('b1', 'horizAlign')
anchors.left: dataShown('b1', 'anchorL')
anchors.leftMargin: dataShown('b1', 'anchorLMargin')
y: dataShown('b1', 'y')
font.pixelSize: dataShown('b1', 'fontPixSize')
renderType: dataShown('b1', 'renderType')
text: dataShown('b1', 'text')
color: dataShown('b1', 'color')
visible: dataShown('b1', 'visible')
topPadding: dataShown('b1', 'padding') //-10.0
//bottomPadding: 30.0
//topPadding: -10.0
}
Text {
id: b2 //bottomText
height: dataShown('b2', 'height')
width: dataShown('b2', 'width')
verticalAlignment: dataShown('b2', 'vertiAlign')
horizontalAlignment:dataShown('b2', 'horizAlign')
anchors.left: dataShown('b2', 'anchorL')
anchors.leftMargin: dataShown('b2', 'anchorLMargin')
y: dataShown('b2', 'y')
font.pixelSize: dataShown('b2', 'fontPixSize')
renderType: dataShown('b2', 'renderType')
text: dataShown('b2', 'text')
color: dataShown('b2', 'color')
visible: dataShown('b2', 'visible')
topPadding: dataShown('b2', 'padding') //-10.0
}
Text {
id: b3 //bottomUnitText
height: dataShown('b3', 'height')
width: dataShown('b3', 'width')
verticalAlignment: dataShown('b3', 'vertiAlign')
horizontalAlignment:dataShown('b3', 'horizAlign')
anchors.left: dataShown('b3', 'anchorL')
anchors.leftMargin: dataShown('b3', 'anchorLMargin')
y: dataShown('b3', 'y')
font.pixelSize: dataShown('b3', 'fontPixSize')
renderType: dataShown('b3', 'renderType')
text: dataShown('b3', 'text')
color: dataShown('b3', 'color')
visible: dataShown('b3', 'visible')
topPadding: dataShown('b3', 'padding') //-10.0
}
PlasmaCore.ToolTipArea {
anchors.fill: parent
interactive: true
mainText: i18n("Network Bandwidth Monitor")
subText: i18n("DBUS Data Source")
icon: 'network-connect'
}
function dataShown(caller, properties){
var height = singleLine ? itemParent.height : itemParent.height / 2
var fontPixelSize = height * fontHeightRatio * fontSizeScale
if (iconPosition === true) { // true = icons on right
// DIFFERENT VARIABLES WITH ICONS ON RIGHT
switch (properties) {
case 'width':
var a = (showSeparately ? 1 : 2) * iconTextMetrics.width / iconTextMetrics.height * height * fontSizeScale
var b = speedTextMetrics.width / speedTextMetrics.height * height * fontSizeScale
var c = unitTextMetrics.width / unitTextMetrics.height * height * fontSizeScale
var d = iconTextMetrics.width / iconTextMetrics.height * height * fontSizeScale
switch (caller) {
case 't1': return b //a
case 't2': return c //b
case 't3': return a //c
case 'b1': return b //d
case 'b2': return c //b
case 'b3': return d //c
}
case 'horizAlign':
switch (caller) {
// left : text in t2 & b2 | right : text in t1 & b1 | left Alt : see left
case 't1': return Text.AlignRight
case 't2': return Text.AlignLeft
case 't3': return Text.AlignHCenter //Text.AlignVCenter
case 'b1': return Text.AlignRight
case 'b2': return Text.AlignLeft
case 'b3': return Text.AlignHCenter //Text.AlignVCenter
}
case 'anchorL':
switch (caller) {
case 't1': return offsetItem.right
case 't2': return t1.right
case 't3': return showUnits ? t2.right : t1.right
case 'b1': return anchorLfunction() //(singleLine && showIcons) ? t3.right : (singleLine ? t2.right : offsetItem.right) //showIcon
case 'b2': return b1.right
case 'b3': return showUnits ? b2.right : b1.right
}
case 'fontPixSize':
switch (caller) {
case 't1': return Math.round(height * fontHeightRatio * fontSizeScale ) // needs to return int not float
case 't2': return Math.round(height * fontHeightRatio * sufixSize )
case 't3': return Math.round(height * fontHeightRatio * iconSize);
case 'b1': return Math.round(height * fontHeightRatio * fontSizeScale )
case 'b2': return Math.round(height * fontHeightRatio * sufixSize )
case 'b3': return Math.round(height * fontHeightRatio * iconSize)
}
case 'text':
switch (caller) {
case 't1': return speedDisplay('number', showSeparately ? (swapDownUp ? upSpeed : downSpeed) : downSpeed + upSpeed)
case 't2': return speedDisplay('suffix', showSeparately ? (swapDownUp ? upSpeed : downSpeed) : downSpeed + upSpeed)
case 't3': return showSeparately ? (swapDownUp ? iconStyle(0) : iconStyle(1)) : iconStyle(2)
case 'b1': return speedDisplay('number', swapDownUp ? downSpeed : upSpeed)
case 'b2': return speedDisplay('suffix', swapDownUp ? downSpeed : upSpeed)
case 'b3': return swapDownUp ? iconStyle(1) : iconStyle(0)
}
case 'visible':
return setUiVisible(caller)
}
} else { // false = icons on left [default]
// DIFFERENT VARIABLES WITH ICONS ON LEFT
switch (properties) {
case 'width':
var leftUpIconWidth = (showSeparately ? 1 : 2) * iconTextMetrics.width / iconTextMetrics.height * height * fontSizeScale
var leftTextWidth = speedTextMetrics.width / speedTextMetrics.height * height * fontSizeScale
var leftUnitWidth = unitTextMetrics.width / unitTextMetrics.height * height * fontSizeScale
var leftDownIconWidth = iconTextMetrics.width / iconTextMetrics.height * height * fontSizeScale
switch (caller) {
case 't1': return leftUpIconWidth // icon
case 't2': return leftTextWidth // text
case 't3': return leftUnitWidth // unit
case 'b1': return leftDownIconWidth // icon
case 'b2': return leftTextWidth // text
case 'b3': return leftUnitWidth // unit
}
case 'horizAlign':
switch (caller) {
// left : text in t2 & b2 | right : text in t1 & b1 | left Alt : see left
case 't1': return Text.AlignHCenter //Text.AlignVCenter
case 't2': return Text.AlignRight
case 't3': return Text.AlignLeft
case 'b1': return Text.AlignHCenter //Text.AlignVCenter
case 'b2': return Text.AlignRight
case 'b3': return Text.AlignLeft
}
case 'anchorL':
switch (caller) {
case 't1': return offsetItem.right
case 't2': return showIcons ? t1.right : offsetItem.right
case 't3': return t2.right
case 'b1': return (singleLine && showUnits) ? t3.right : (singleLine ? t2.right : offsetItem.right)
case 'b2': return showIcons ? b1.right : ((singleLine && showUnits) ? t3.right : (singleLine ? t2.right : offsetItem.right))
case 'b3': return b2.right
}
case 'fontPixSize':
switch (caller) {
case 't1': return Math.round(height * fontHeightRatio * iconSize) // needs to return int not float
case 't2': return Math.round(height * fontHeightRatio * fontSizeScale )
case 't3': return Math.round(height * fontHeightRatio * sufixSize )
case 'b1': return Math.round(height * fontHeightRatio * iconSize)
case 'b2': return Math.round(height * fontHeightRatio * fontSizeScale )
case 'b3': return Math.round(height * fontHeightRatio * sufixSize )
}
case 'text':
switch (caller) {
case 't1': return showSeparately ? (swapDownUp ? iconStyle(0) : iconStyle(1)) : iconStyle(2)
case 't2': return speedDisplay('number', showSeparately ? (swapDownUp ? upSpeed : downSpeed) : downSpeed + upSpeed) //speedDisplay(section, value)
case 't3': return speedDisplay('suffix', showSeparately ? (swapDownUp ? upSpeed : downSpeed) : downSpeed + upSpeed)
case 'b1': return swapDownUp ? iconStyle(1) : iconStyle(0)
case 'b2': return speedDisplay('number', swapDownUp ? downSpeed : upSpeed)
case 'b3': return speedDisplay('suffix', swapDownUp ? downSpeed : upSpeed)
}
case 'visible':
return setUiVisible(caller)
}
}
// SAME VARIABLES WITH ICONS EITHER SIDE
switch (properties) {
case 'height': return singleLine ? itemParent.parent.height : itemParent.parent.height / 2
case 'vertiAlign': //return Text.AlignVCenter Text.AlignTop
switch (caller) {
case 't1': return Text.AlignVCenter //Text.AlignBottom
case 't2': return Text.AlignVCenter //Text.AlignBottom
case 't3': return Text.AlignVCenter //Text.AlignBottom
case 'b1': return Text.AlignVCenter //Text.AlignTop
case 'b2': return Text.AlignVCenter //Text.AlignTop
case 'b3': return Text.AlignVCenter //Text.AlignTop
}
case 'anchorLMargin': return fontPixelSize * marginFactor
case 'y':
switch (caller) {
case 't1': return 0
case 't2': return 0
case 't3': return 0
case 'b1': return singleLine ? 0 : itemParent.height / 2
case 'b2': return singleLine ? 0 : itemParent.height / 2
case 'b3': return singleLine ? 0 : itemParent.height / 2
}
case 'renderType': return Text.NativeRendering
case 'color': return theme.textColor
case 'padding': return layoutPadding
}
}
function setUiVisible(caller) {
// UI ELEMENTS VISIBLE BASED ON hideInactive
if (hideInactive === true) {
if (downSpeed === 0 && upSpeed === 0) {
t1.visible = false
t2.visible = false
t3.visible = false
b1.visible = false
b2.visible = false
b3.visible = false
} else {
t1.visible = iconPosition ? true : showIcons
t2.visible = iconPosition ? showUnits : true
t3.visible = iconPosition ? showIcons : showUnits
b1.visible = iconPosition ? showSeparately : showSeparately && showIcons
b2.visible = iconPosition ? showSeparately && showUnits : showSeparately
b3.visible = iconPosition ? showSeparately && showIcons : showSeparately && showUnits
}
} else {
// UI ELEMENTS VISIBLE BASED ON iconPosition
t1.visible = iconPosition ? true : showIcons
t2.visible = iconPosition ? showUnits : true
t3.visible = iconPosition ? showIcons : showUnits
b1.visible = iconPosition ? showSeparately : showSeparately && showIcons
b2.visible = iconPosition ? showSeparately && showUnits : showSeparately
b3.visible = iconPosition ? showSeparately && showIcons : showSeparately && showUnits
}
switch (caller) {
case 't1': return iconPosition ? true : showIcons
case 't2': return iconPosition ? showUnits : true
case 't3': return iconPosition ? showIcons : showUnits
case 'b1': return iconPosition ? showSeparately : showSeparately && showIcons
case 'b2': return iconPosition ? showSeparately && showUnits : showSeparately
case 'b3': return iconPosition ? showSeparately && showIcons : showSeparately && showUnits
}
}
function anchorLfunction() {
switch (singleLine) {
case false : // one above other
return offsetItem.right
case true : // side by side
switch (showUnits) {
case false :
if (showIcons === false) return t1.right
else return t3.right
case true :
if (showIcons === false) return t2.right
else return t3.right
}
}
}
function iconStyle(a) {
var iconArray = []
iconArray = iconType.replace(' ', ',').split(",")
switch(a) {
case 0: return iconArray[1]
case 1: return iconArray[0]
case 2: return iconArray[1] + iconArray[0]
}
}
function getDecimalPlace() {
return Number.parseFloat('1000').toFixed( decimalPlace );
}
function customRound(number) {
var decimalPart = number - Math.floor(number);
if (decimalPart >= 0.445) {
return Math.ceil(number);
} else {
return Math.floor(number);
}
}
function speedDisplay(section, value) {
// data communication 1 kilobit = 1000 bits, while in data storage 1 Kilobyte = 1024 Bytes
var m = getBinDec // binary 1024 | decimal 1000
var dec = decimalPlace // # of decimal places
// BIT CONVERSION TO HIGHER PREFIXES
var kil = m; // One K is 1024 b/B 1024 1000
var meg = m * m; // One M is 1024 Kb/B 1048576 1000000
var gig = m * m * m; // One G is 1024 Mb/B 1073741824 1000000000
var ter = m * m * m * m; // One T is 1024 Gb/B 1099511627776 1000000000000
// NEW THRESHOLD : 4 DIGITS ALLOWED
const fourb = 10000;
const fourk = 10000000;
const fourm = 10000000000;
const fourg = 10000000000000;
const fourt = 10000000000000000;
var result;
var digitNum = value.toString().length;
if (section === 'number') {
if (roundedNumber === 3) {
if (value < kil) {
result = decimalFilter0 ? value.toFixed(dec) : value; // result = '' if less than a Kx
} else if (value < meg) {
result = decimalFilter1 ? (value / kil).toFixed(dec) : customRound(value / kil); // return Kx if less than a Mx
} else if (value < gig) {
result = decimalFilter2 ? (value / meg).toFixed(dec) : customRound(value / meg); // return Mx if less than a Gx
} else if (value < ter) {
result = decimalFilter3 ? (value / gig).toFixed(dec) : customRound(value / gig); // result = Gx if less than a Gx
} else {
result = decimalFilter3 ? (value / ter).toFixed(dec) : customRound(value / ter); // result = Tx if less than a Tx
}
} else {
// roundedNumber SET TO 4 [ EX. BITS= 1211648 RESULT= 1183.25 Kb NOT 1.16 Mb ]
if (value < fourb) {
result = decimalFilter0 ? value.toFixed(dec) : value; // return '' if less than a Kx
} else if (value < fourk) {
result = decimalFilter1 ? (value / kil).toFixed(dec) : customRound(value / kil); // return Kx if less than a Mx
} else if (value < fourm) {
result = decimalFilter2 ? (value / meg).toFixed(dec) : customRound(value / meg); // return Mx if less than a Gx
} else if (value < fourg) {
result = decimalFilter3 ? (value / gig).toFixed(dec) : customRound(value / gig); // return Gx if less than a Tx
} else {
result = decimalFilter3 ? (value / ter).toFixed(dec) : customRound(value / ter); // return Gx if less than a Tx
}
}
} else if (section === 'suffix') {
if (roundedNumber === 3) {
if (value < kil) {
result = shortUnits ? (boolUnits ? 'b' : 'B') : suffix('b')
} else if (value < meg) {
result = shortUnits ? (boolUnits ? 'k' : 'K') : suffix('k')
} else if (value < gig) {
result = shortUnits ? 'M' : suffix('M')
} else if (value < ter) {
result = shortUnits ? 'G' : suffix('G')
} else {
result = shortUnits ? 'T' : suffix('T')
}
} else {
// roundedNumber SET TO 4 [ EX. BITS= 1211648 RESULT= 1183.25 Kb NOT 1.16 Mb ] RETURN Kb NOT Mb
if (value < fourb) {
result = shortUnits ? (boolUnits ? 'b' : 'B') : suffix('b')
} else if (value < fourk) {
result = shortUnits ? (boolUnits ? 'k' : 'K') : suffix('k')
} else if (value < fourm) {
result = shortUnits ? 'M' : suffix('M')
} else if (value < fourg) {
result = shortUnits ? 'G' : suffix('G')
} else {
result = shortUnits ? 'T' : suffix('T')
}
}
}
//console.log("value:", value, " result:", result, " digitNum:", digitNum, " roundedNumber:", roundedNumber);
return result
}
function suffix(unit) { // NEW SOLUTION TO SUFFIX
// https://en-academic.com/dic.nsf/enwiki/8315069#Kibibit_per_second
//! BINARY: DECIMAL:
//! Kibibit = 1024 bits | Kilobit = 1000 bits
//! Kibibyte = 1024 bytes | Kilobyte = 1000 bytes
//! Kib/s Mib/s | kb/s Mb/s
//! KiB/s MiB/s | KB/s MB/s
// APPEND BINARY OR DECIMAL UNIT PREFIX
if (binaryDecimal === 'binary') {
if (unit !== 'b') {
if (unit === 'k') { unit = 'K' }
unit += 'i'
}
}
// CONVERT OR APPEND BIT OR BYTE UNIT PREFIX
if (speedUnits === 'bits') {
if (unit !== 'b') { unit += 'b' }
} else {
if (unit === 'b') { unit = 'B' }
else { unit += 'B' }
}
// APPEND PER SECOND PREFIX
if (showSeconds === true) {
unit += secondsPrefix
}
return unit
}
//################## SERIALISATION FIX ###########################
function netSourceEncode(value) {
return JSON.stringify(value)
}
function netSourceDecode(value) {
try {
return JSON.parse(value)
} catch (E) {
return []
}
}
//#####################################################
//2nd
function addSources() {
var count = 0;
var checkedCount = 0
var sensors = [];
var netPath = []
sensorList = [];
sensors = dbusData.allSensors("network/");
//console.log("sensors: from CR " + sensors)
// qml: Network-sensors:
// network/all,
// network/all/download,
// network/all/downloadBits,
// network/all/totalDownload
// network/all/totalUpload,
// network/all/upload,
// network/all/uploadBits,
// network/wlp2s0,
// network/wlp2s0/download,
// network/wlp2s0/downloadBits,
// network/wlp2s0/ipv4address,
// network/wlp2s0/ipv4dns,
// network/wlp2s0/ipv4gateway,
// network/wlp2s0/ipv4subnet,
// network/wlp2s0/ipv4withPrefixLength,
// network/wlp2s0/ipv6address,
// network/wlp2s0/ipv6dns,
// network/wlp2s0/ipv6gateway,
// network/wlp2s0/ipv6subnet,
// network/wlp2s0/ipv6withPrefixLength,
// network/wlp2s0/network, <<< here
// network/wlp2s0/signal,
// network/wlp2s0/totalDownload,
// network/wlp2s0/totalUpload,
// network/wlp2s0/upload,
// network/wlp2s0/uploadBits,
//var duplicateCheck = {}
for (var idx = 0; idx < sensors.length; idx++) {
if (sensors[idx].endsWith("/network")) {
netPath = { path:sensors[idx].replace("/network", ""),
name:dbusData.stringData(sensors[idx]),
index:idx,
checked:true }
netInterfaces[count] = netPath // ADD INTERFACE ARRAY DATA TO MULTI DEM ARRAY
count += 1;
}
}
// COMPARE EXISTING INTERFACE SETTINGS WITH DISCOVERED INTERFACES
// IF USER SETS AN INTERFACE TO NOT BE MONITORED, STORED SETTINGS WILL
// HAVE IT AS CHECKED:FALSE. ADD THIS CHANGE TO netInterfaces ARRAY.
// IF A NEW INTERFACE IS DISCOVERED, IT WILL BE ADDED / PUSHED TO THE SETTINGS STORE.
//var pcn = plasmoid.configuration.netSources
var pcn = netSourceDecode(plasmoid.configuration.netSources)
//console.log("PCN: "+netSourceEncode(pcn))
var ni = netInterfaces
//console.log("NI: "+netSourceEncode(ni))
for (var i = 0; i < pcn.length; i++) { // LOOP THROUGH FIRST STORED SETTINGS ARRAY
for (var ii = 0; ii < ni.length; ii++) { // LOOP THROUGH SECOND netInterfaces ARRAY
if (pcn[i].path === ni[ii].path) { // PATHS MATCH - NOW COMPARE 'CHECKED'
if (pcn[i].checked !== ni[ii].checked) { // DIFFERENT CHECKED MARK, PCN HAS BEEN UPDATED. MAKE NI SAME AS PCN
//netInterfaces[ii].checked = pcn[i].checked
ni[ii].checked = pcn[i].checked
}
}
// console.log("netInterfaces: PATH: " + netInterfaces[ii].path +
// ", NAME: " + netInterfaces[ii].name +
// ", INDEX: " + netInterfaces[ii].index +
// ", CHECKED: " + netInterfaces[ii].checked)
}
}
plasmoid.configuration.netSources = netSourceEncode(ni) //netInterfaces) // PUSH FOUND INTERFACES TO STORED SETTINGS
//pcn = plasmoid.configuration.netSources // REFRESH DATA IN VARIABLE
//pcn = netSourceEncode(plasmoid.configuration.netSources) // REFRESH DATA IN VARIABLE
//console.log("PCN2:"+netSourceEncode(pcn))
//console.log("NI2: "+netSourceEncode(ni))
netDataBits = []; // RESET ARRAYS
netDataByte = [];
netDataTotal = [];
for (var i = 0; i < ni.length; i++) { // LOOP THROUGH FIRST STORED SETTINGS ARRAY
if (ni[i].checked === true) {
sensorList.push(ni[i].path + "/downloadBits", // CREATE ARRAY TO SUBSCRIBE TO AND POLL FROM DBUS
ni[i].path + "/uploadBits",
ni[i].path + "/download",
ni[i].path + "/upload",
ni[i].path + "/totalDownload",
ni[i].path + "/totalUpload",
ni[i].path + "/signal")
// INITIALIZE AND SET GLOBAL VARIABLES BASED ON CHECKED:TRUE INTERFACES
netDataBits[checkedCount] = { down: 0, up: 0 };
netDataByte[checkedCount] = { down: 0, up: 0 };
netDataTotal[checkedCount] = { down: 0, up: 0 };
checkedCount += 1
}
}
netDataAccumulator = { down: 0, up: 0 };
//console.log(sensorList)
dbusData.subscribe(sensorList);
//numberOfNets = count;
numCheckedNets = checkedCount
ready = true;
}
Connections {
target: plasmoid.configuration
function onNetSourcesChanged() { // TRIGGERED WHEN INTERFACE CHECKED CHANGED IN SETTINGS
dbusData.unsubscribe(sensorList)
if ( !ready ) return
else addSources()
}
}
Connections {
target: sysMonitor
function onStatsUpd(pathKeys, values) {
// TRIGGERED EVERY 500 MILLISECONDS
//console.log("CR-onStatsUpd: "+ pathKeys + " || "+ values)
// qml: CR-onStatsUpd: network/wlp2s0/download,network/wlp2s0/upload || 334,128
// qml: CR-onStatsUpd: network/wlp2s0/downloadBits,network/wlp2s0/totalDownload,network/wlp2s0/uploadBits,network/wlp2s0/totalUpload || 0,49913032,0,169202
var sensorPathKey; // PATH AND KEY OF DBUS FOUND INTERFACE VALUE
var configPath; // PATH OF INTERFACE IN SETTINGS / CONFIG
var slot = 0
var ni = netInterfaces //plasmoid.configuration.netSources
if ( !ready ) return;
for (var i = 0; i < ni.length; i++) { // LOOP SETTINGS INTERFACE AND GRAB PATH OF CHECKED:TRUE
if (ni[i].checked === true) {
configPath = ni[i].path
}else{
continue // SKIP SETTINGS INTERFACE THAT ISNT CHECKED:TRUE
}
for ( var ii = 0; ii < pathKeys.length; ii++ ) { // LOOP DBUS SENSOR PATH & KEYS
sensorPathKey = pathKeys[ii];
if (sensorPathKey.indexOf(configPath) == 0) {
if (sensorPathKey == configPath + "/download") { // DOWNLOAD IN BYTES
netDataByte[slot].down = values[ii]
}
if (sensorPathKey == configPath + "/downloadBits") { // DOWNLOAD IN BITS
netDataBits[slot].down = values[ii]
}
if (sensorPathKey == configPath + "/totalDownload") { // TOTAL DOWNLOAD IN BYTES:
netDataTotal[slot].down = values[ii]
}
if (sensorPathKey == configPath + "/upload") { // UPLOAD IN BYTES
netDataByte[slot].up = values[ii]
}
if (sensorPathKey == configPath + "/uploadBits") { // UPLOAD IN BITS
netDataBits[slot].up = values[ii]
}
if (sensorPathKey == configPath + "/totalUpload") { // TOTAL UPLOAD IN BYTES:
netDataTotal[slot].up = values[ii]
}
}
}
slot += 1
}
if (accumulator) { // ACCUMULATOR SWITCHED ON
activateAccumulator()
}
}
function onUpdateUi() {
// THIS FUNCTION IS TRIGGERED BY updateInterval
setNetData()
setUiVisible('')
}
function setNetData() {
// THIS FUNCTION IS TRIGGERED BY updateInterval
if (numCheckedNets == 0) { // NO NETWORKS ENABLED|CHECKED [undefined fix]
downSpeed = 0
upSpeed = 0
} else { // ONE OR MORE NETWORKS ENABLED|CHECKED
if (accumulator !== 0) { // ACCUMULATOR IS EITHER 1 OR 2
var values = getAccumulatorData()
downSpeed = values[0]
upSpeed = values[1]
return // EXIT FUNCTION
}
var values = multiNetAddition() // ADD VALUES FOR MULTIPLE ACTIVE NETWORKS
downSpeed = values[0]
upSpeed = values[1]
}
}
function multiNetAddition(){
// IF MULTIPLE INTERFACES ARE CHECKED, DATA COLLECTED FROM EACH NEEDS TO BE ADDED TOGETHER AND DISPLAYED
var downloaded = 0
var uploaded = 0
if (speedUnits === 'bits') { // BITS
for (var i = 0; i < netDataBits.length; i++) {
downloaded += netDataBits[i].down
uploaded += netDataBits[i].up
}
} else { // BYTES
for (var i = 0; i < netDataByte.length; i++) {
downloaded += netDataByte[i].down
uploaded += netDataByte[i].up
}
}
return [ downloaded, uploaded ]
}
function getAccumulatorData() {
var downloaded = 0
var uploaded = 0
if (accumulator === 2) { // ACCUMULATOR ON [ ACCUMULATED ]
downloaded = netDataAccumulator.down
uploaded = netDataAccumulator.up
} else if (accumulator === 1) { // ACCUMULATOR ON [ AVERAGE ]
downloaded = getAverage(netDataAccumulator.down)
uploaded = getAverage(netDataAccumulator.up)
}
netDataAccumulator.down = 0 // RESET ACCUMULATOR DATA FOR NEXT COUNT
netDataAccumulator.up = 0
accumulatorCounter = 0 // RESET ACCUMULATOR COUNTER, USED TO TRIGGER updateInterval AT THE CORRECT TIME
return [ downloaded, uploaded ]
}
function activateAccumulator() {
// IF ACTIVATED, WILL TRIGGER EVERY 500 MILLISECONDS
var values = multiNetAddition()
var countx = updateInterval / 500 // GET NUMBER OF TICKS FOR COUNTER
if (accumulatorCounter < countx) {
netDataAccumulator.down += values[0]
netDataAccumulator.up += values[1]
}
accumulatorCounter += 1
}
function getAverage(value) {
var seconds = updateInterval / 1000
return value * 0.5 / seconds
}
}
Component.onCompleted: {
addSources();
}
Component.onDestruction: {
dbusData.unsubscribe(sensorList);
}
}