Warning, /plasma/plasma-systemmonitor/src/faces/applicationstable/contents/ui/ApplicationsTableView.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 
0010 import Qt.labs.qmlmodels
0011 
0012 import org.kde.kirigami as Kirigami
0013 import org.kde.kitemmodels as KItemModels
0014 import org.kde.quickcharts as Charts
0015 
0016 import org.kde.ksysguard.formatter as Formatter
0017 import org.kde.ksysguard.process as Process
0018 import org.kde.ksysguard.table as Table
0019 
0020 Table.BaseTableView {
0021     id: view
0022 
0023     Kirigami.PlaceholderMessage {
0024         visible: !appModel.available
0025         anchors.fill: parent
0026         anchors.margins: Kirigami.Units.largeSpacing
0027         icon.name: "action-unavailable-symbolic"
0028         text: i18nc("Warning message shown on runtime error", "Applications view is unsupported on your system");
0029     }
0030 
0031     property var enabledColumns: []
0032     property alias columnDisplay: displayModel.columnDisplay
0033     property alias sourceModel: appModel
0034 
0035     property alias filterString: sortColumnFilter.filterString
0036 
0037     property var selectedApplications: {
0038         var result = []
0039         var rows = {}
0040 
0041         for (var i of selection.selectedIndexes) {
0042             if (rows[i.row] != undefined) {
0043                 continue
0044             }
0045             rows[i.row] = true
0046 
0047             var index = sortColumnFilter.mapToSource(i)
0048             var item = applicationInformation.createObject()
0049             item.index = index
0050             result.push(item)
0051         }
0052         return result
0053     }
0054 
0055     property Component applicationInformation: ApplicationInformation {
0056         model: appModel
0057         sensorColumns: {
0058             "name": appModel.enabledAttributes.indexOf("appName"),
0059             "cpu": appModel.enabledAttributes.indexOf("usage"),
0060             "memory": appModel.enabledAttributes.indexOf("vmPSS"),
0061             "netInbound": appModel.enabledAttributes.indexOf("netInbound"),
0062             "netOutbound": appModel.enabledAttributes.indexOf("netOutbound"),
0063             "diskRead": appModel.enabledAttributes.indexOf("ioCharactersActuallyReadRate"),
0064             "diskWrite": appModel.enabledAttributes.indexOf("ioCharactersActuallyWrittenRate"),
0065             "iconName": appModel.enabledAttributes.indexOf("iconName")
0066         }
0067         role: Process.ProcessDataModel.Value
0068         pidsRole: Process.ProcessDataModel.PIDs
0069         cpuMode: displayModel.data(displayModel.index(0, appModel.enabledAttributes.indexOf("usage")), Table.ColumnDisplayModel.DisplayStyleRole)
0070     }
0071 
0072     idRole: "Attribute"
0073 
0074     columnWidths: [200, 100, 100, 100, 100]
0075 
0076     onSort: (column, order) => {
0077         sortColumnFilter.sortColumn = column
0078         sortColumnFilter.sortOrder = order
0079     }
0080 
0081     model: KItemModels.KSortFilterProxyModel {
0082         id: sortColumnFilter
0083 
0084         sourceModel: cacheModel
0085         filterKeyColumn: appModel.nameColumn
0086         filterCaseSensitivity: Qt.CaseInsensitive
0087         filterColumnCallback: function(column, parent) {
0088             // Note: This assumes displayModel column == appModel column
0089             // This may not always hold, but we get incorrect results if we try to
0090             // map to source indices when the model is empty.
0091             var sensorId = appModel.enabledAttributes[column]
0092             if (appModel.hiddenAttributes.indexOf(sensorId) != -1) {
0093                 return false
0094             }
0095             return true
0096         }
0097         filterRowCallback: function(row, parent) {
0098             if (filterString.length == 0) {
0099                 return true
0100             }
0101             const name = sourceModel.data(sourceModel.index(row, filterKeyColumn, parent), filterRole).toLowerCase()
0102             const parts = filterString.toLowerCase().split(",").map(s => s.trim()).filter(s => s.length > 0)
0103             return parts.some(part => name.includes(part))
0104         }
0105 
0106         sortRoleName: "Value"
0107 
0108     }
0109 
0110     Table.ComponentCacheProxyModel {
0111         id: cacheModel
0112         sourceModel: displayModel
0113 
0114         component: Charts.HistoryProxySource {
0115             id: history
0116             source: Charts.ModelSource {
0117                 model: history.Table.ComponentCacheProxyModel.model
0118                 column: history.Table.ComponentCacheProxyModel.column
0119                 roleName: "Value"
0120             }
0121             item: Table.ComponentCacheProxyModel.row
0122             maximumHistory: 10
0123             interval: 2000
0124             fillMode: Charts.HistoryProxySource.FillFromEnd
0125         }
0126     }
0127 
0128     Table.ColumnDisplayModel {
0129         id: displayModel
0130         sourceModel: appModel
0131         idRole: "Attribute"
0132     }
0133 
0134     Process.ApplicationDataModel {
0135         id: appModel
0136 
0137         property int nameColumn: enabledAttributes.indexOf("appName")
0138         property int iconColumn: enabledAttributes.indexOf("iconName")
0139 
0140         property var requiredAttributes: [
0141             "iconName",
0142             "appName",
0143             "usage",
0144             "vmPSS",
0145             "netInbound",
0146             "netOutbound",
0147             "ioCharactersActuallyReadRate",
0148             "ioCharactersActuallyWrittenRate",
0149         ]
0150         property var hiddenAttributes: []
0151 
0152         enabled: view.visible
0153 
0154         enabledAttributes: {
0155             var result = []
0156             for (let i of view.enabledColumns) {
0157                 if (appModel.availableAttributes.includes(i)) {
0158                     result.push(i)
0159                 }
0160             }
0161 
0162             var hidden = []
0163             for (let i of requiredAttributes) {
0164                 if (result.indexOf(i) == -1) {
0165                     result.push(i)
0166                     hidden.push(i)
0167                 }
0168             }
0169 
0170             hiddenAttributes = hidden
0171             return result;
0172         }
0173 
0174         Component.onCompleted: {
0175             if (!available) {
0176                 console.error("Implementation matching https://systemd.io/DESKTOP_ENVIRONMENTS/ was not found. ApplicationsView will not be available")
0177             }
0178         }
0179     }
0180 
0181     delegate: DelegateChooser {
0182         role: "displayStyle"
0183         DelegateChoice {
0184             column: view.LayoutMirroring.enabled ? view.model.columnCount() - 1 : 0
0185             Table.FirstCellDelegate {
0186                 iconName: {
0187                     var index = sortColumnFilter.mapToSource(sortColumnFilter.index(model.row, 0));
0188                     index = appModel.index(index.row, appModel.iconColumn)
0189                     return appModel.data(index)
0190                     return ""
0191                 }
0192             }
0193         }
0194         DelegateChoice {
0195             roleValue: "line"
0196             Table.LineChartCellDelegate {
0197                 valueSources: model.cachedComponent != undefined ? model.cachedComponent : []
0198                 maximum: sortColumnFilter.data(sortColumnFilter.index(model.row, model.column), Process.ProcessDataModel.Maximum)
0199             }
0200         }
0201         DelegateChoice {
0202             roleValue: "lineScaled"
0203             Table.LineChartCellDelegate {
0204                 valueSources: model.cachedComponent != undefined ? model.cachedComponent : []
0205                 maximum: sortColumnFilter.data(sortColumnFilter.index(model.row, model.column), Process.ProcessDataModel.Maximum)
0206                 text: Formatter.Formatter.formatValue(parseInt(model.Value) / model.Maximum * 100, model.Unit)
0207             }
0208 
0209         }
0210         DelegateChoice {
0211             roleValue: "textScaled"
0212             Table.TextCellDelegate {
0213                 text: Formatter.Formatter.formatValue(parseInt(model.Value) / model.Maximum * 100, model.Unit)
0214             }
0215         }
0216         DelegateChoice { Table.TextCellDelegate { } }
0217     }
0218 }