Warning, /plasma/plasma-systemmonitor/src/faces/applicationstable/contents/ui/ApplicationDetails.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
0003 *
0004 * SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006
0007 import QtQuick
0008 import QtQuick.Controls
0009 import QtQuick.Layouts
0010
0011 import Qt.labs.qmlmodels
0012
0013 import org.kde.kirigami as Kirigami
0014
0015 import org.kde.quickcharts as Charts
0016
0017 import org.kde.ksysguard.formatter as Formatter
0018 import org.kde.ksysguard.process as Process
0019 import org.kde.ksysguard.sensors as Sensors
0020 import org.kde.ksysguard.table as Table
0021
0022 Page {
0023 id: root
0024
0025 property var applications: []
0026
0027 readonly property var firstApplication: applications.length > 0 ? applications[0] : null
0028
0029 property real headerHeight: Kirigami.Units.gridUnit
0030
0031 signal close()
0032
0033 Kirigami.Theme.colorSet: Kirigami.Theme.View
0034
0035 background: Rectangle {
0036 Kirigami.Theme.inherit: false
0037 Kirigami.Theme.colorSet: Kirigami.Theme.View
0038 color: Kirigami.Theme.backgroundColor
0039 }
0040
0041 header: ToolBar {
0042 implicitHeight: root.headerHeight
0043 Kirigami.Theme.inherit: false
0044 Kirigami.Theme.colorSet: Kirigami.Theme.Window
0045
0046 Label {
0047 anchors.left: parent.left
0048 text: i18nc("@title:window", "Details")
0049 }
0050
0051 ToolButton {
0052 anchors.right: parent.right
0053 anchors.verticalCenter: parent.verticalCenter
0054 height: Math.min(root.headerHeight, implicitHeight)
0055 width: height
0056 icon.name: "dialog-close"
0057 onClicked: root.close()
0058 }
0059 }
0060
0061 ColumnLayout {
0062 visible: root.firstApplication != null
0063
0064 anchors {
0065 fill: parent
0066 leftMargin: Kirigami.Units.largeSpacing
0067 rightMargin: Kirigami.Units.largeSpacing
0068 topMargin: Kirigami.Units.smallSpacing
0069 }
0070
0071 Label {
0072 text: i18nc("@title:group", "CPU")
0073 }
0074
0075 LineChartCard {
0076 Layout.fillHeight: false
0077 Layout.preferredHeight: Kirigami.Units.gridUnit * 3
0078
0079 yRange {
0080 from: 0;
0081 to: {
0082 if (!root.firstApplication) {
0083 return 100
0084 }
0085
0086 let mode = root.firstApplication.cpuMode
0087 if (mode === "lineScaled" || mode === "textScaled") {
0088 return 100
0089 } else {
0090 return 100 * cpuCountSensor.value
0091 }
0092 }
0093 automatic: false
0094 }
0095 xRange { from: 0; to: 50 }
0096 unit: Formatter.Units.UnitPercent
0097
0098 colorSource: Charts.SingleValueSource { value: Kirigami.Theme.negativeTextColor }
0099 valueSources: [
0100 Charts.HistoryProxySource {
0101 id: cpuHistory
0102 source: Charts.SingleValueSource {
0103 value: {
0104 if (!root.firstApplication) {
0105 return
0106 }
0107
0108 let mode = root.firstApplication.cpuMode
0109 if (mode === "lineScaled" || mode === "textScaled") {
0110 return root.firstApplication.cpu / cpuCountSensor.value
0111 } else {
0112 return root.firstApplication.cpu
0113 }
0114 }
0115 }
0116 maximumHistory: 50
0117 interval: 2000
0118 }
0119 ]
0120
0121 Sensors.Sensor { id: cpuCountSensor; sensorId: "cpu/all/coreCount" }
0122 }
0123 Label {
0124 text: i18nc("@title:group", "Memory")
0125 }
0126 LineChartCard {
0127 Layout.fillHeight: false
0128 Layout.preferredHeight: Kirigami.Units.gridUnit * 3
0129
0130 yRange { from: 0; to: totalMemorySensor.value ? totalMemorySensor.value : 0; automatic: false }
0131 xRange { from: 0; to: 50 }
0132 unit: totalMemorySensor.unit
0133
0134 colorSource: Charts.SingleValueSource { value: Kirigami.Theme.positiveTextColor }
0135 valueSources: [
0136 Charts.HistoryProxySource {
0137 id: memoryHistory
0138 source: Charts.SingleValueSource {
0139 // ProcessDataModel memory is in KiB but our y range is in B so convert memory correctly.
0140 value: root.firstApplication ? root.firstApplication.memory * 1024 : 0
0141 }
0142 maximumHistory: 50
0143 interval: 2000
0144 }
0145 ]
0146
0147 Sensors.Sensor { id: totalMemorySensor; sensorId: "memory/physical/total" }
0148 }
0149 Label {
0150 text: i18nc("@title:group", "Network")
0151 }
0152 LineChartCard {
0153 Layout.fillHeight: false
0154 Layout.preferredHeight: Kirigami.Units.gridUnit * 3
0155
0156 xRange { from: 0; to: 50 }
0157 unit: Formatter.Units.UnitByteRate
0158
0159 valueSources: [
0160 Charts.HistoryProxySource {
0161 id: netInboundHistory
0162 source: Charts.SingleValueSource { value: root.firstApplication ? root.firstApplication.netInbound : 0; }
0163 maximumHistory: 50
0164 interval: 2000
0165 },
0166 Charts.HistoryProxySource {
0167 id: netOutboundHistory
0168 source: Charts.SingleValueSource { value: root.firstApplication ? root.firstApplication.netOutbound : 0; }
0169 maximumHistory: 50
0170 interval: 2000
0171 }
0172 ]
0173 }
0174 Label {
0175 text: i18nc("@title:group", "Disk")
0176 }
0177 LineChartCard {
0178 Layout.fillHeight: false
0179 Layout.preferredHeight: Kirigami.Units.gridUnit * 3
0180
0181 xRange { from: 0; to: 50 }
0182 unit: Formatter.Units.UnitByteRate
0183
0184 valueSources: [
0185 Charts.HistoryProxySource {
0186 id: diskReadHistory
0187 source: Charts.SingleValueSource { value: root.firstApplication ? root.firstApplication.diskRead : 0; }
0188 maximumHistory: 50
0189 interval: 2000
0190 },
0191 Charts.HistoryProxySource {
0192 id: diskWriteHistory
0193 source: Charts.SingleValueSource { value: root.firstApplication ? root.firstApplication.diskWrite : 0; }
0194 maximumHistory: 50
0195 interval: 2000
0196 }
0197 ]
0198 }
0199
0200 Label {
0201 text: i18nc("@title:group", "Processes: %1", processTable.rows || " ")
0202 }
0203
0204 Rectangle {
0205 Layout.fillWidth: true
0206 Layout.fillHeight: true
0207 Layout.leftMargin: -Kirigami.Units.largeSpacing;
0208 Layout.rightMargin: -Kirigami.Units.largeSpacing;
0209
0210 color: Kirigami.Theme.backgroundColor
0211 Kirigami.Theme.colorSet: Kirigami.Theme.View
0212
0213 Table.BaseTableView {
0214 id: processTable
0215
0216 anchors.fill: parent
0217
0218 columnWidths: [0.5, 0.25, 0.25]
0219 sortName: processModel.enabledAttributes.includes(controller.faceConfiguration.sortColumn) ? controller.faceConfiguration.sortColumn : "vmPSS"
0220 sortOrder: controller.faceConfiguration.sortDirection
0221 onSort: (column, order) => sortFilter.sort(column, order)
0222
0223 model: Table.ProcessSortFilterModel {
0224 id: sortFilter
0225 sourceModel: processModel
0226 hiddenAttributes: ["pid"]
0227 filterPids: root.firstApplication ? root.firstApplication.pids : []
0228 }
0229
0230 Process.ProcessDataModel {
0231 id: processModel
0232
0233 enabled: root.visible && root.firstApplication != null
0234
0235 enabledAttributes: [
0236 "name",
0237 "usage",
0238 "vmPSS",
0239 "pid",
0240 ]
0241 }
0242
0243 delegate: DelegateChooser {
0244 role: "Attribute"
0245 DelegateChoice {
0246 roleValue: "usage"
0247 Table.TextCellDelegate {
0248 text: Formatter.Formatter.formatValue(parseInt(model.Value) / model.Maximum * 100, model.Unit)
0249 }
0250 }
0251 DelegateChoice { Table.TextCellDelegate { } }
0252 }
0253 }
0254
0255 Kirigami.Separator { anchors.bottom: processTable.top; width: parent.width }
0256 }
0257 }
0258
0259 Kirigami.PlaceholderMessage {
0260 anchors.fill: parent
0261 anchors.margins: Kirigami.Units.largeSpacing * 2
0262 text: i18nc("@info:placeholder", "Select an application to see its details")
0263 visible: root.firstApplication == null
0264 }
0265
0266 onApplicationsChanged: {
0267 cpuHistory.clear()
0268 memoryHistory.clear()
0269 netInboundHistory.clear()
0270 netOutboundHistory.clear()
0271 diskReadHistory.clear()
0272 diskWriteHistory.clear()
0273 }
0274 onFirstApplicationChanged: {
0275 sortFilter.invalidate()
0276 }
0277 }