ApplicationDetails.qml 7.73 KB
Newer Older
1
2
3
4
5
6
/*
 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * SPDX-License-Identifier: LGPL-2.0-or-later
 */

7
8
9
10
import QtQuick 2.12
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.2

11
12
import Qt.labs.qmlmodels 1.0

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import org.kde.kirigami 2.4 as Kirigami

import org.kde.kitemmodels 1.0 as KItemModels
import org.kde.quickcharts 1.0 as Charts

import org.kde.ksysguard.formatter 1.0 as Formatter
import org.kde.ksysguard.process 1.0 as Process
import org.kde.ksysguard.sensors 1.0 as Sensors
import org.kde.ksysguard.table 1.0 as Table

Page {
    id: root

    property var applications: []

    readonly property var firstApplication: applications.length > 0 ? applications[0] : null

    property real headerHeight: Kirigami.Units.gridUnit

    signal close()

    Kirigami.Theme.colorSet: Kirigami.Theme.View

36
37
38
39
40
    background: Rectangle {
        Kirigami.Theme.inherit: false
        Kirigami.Theme.colorSet: Kirigami.Theme.View
        color: Kirigami.Theme.backgroundColor
    }
41
42
43
44
45
46

    header: ToolBar {
        implicitHeight: root.headerHeight
        Kirigami.Theme.inherit: false
        Kirigami.Theme.colorSet: Kirigami.Theme.Window

47
48
49
50
        Label {
            anchors.left: parent.left
            text: i18nc("@title:window", "Details")
        }
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

        ToolButton {
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
            height: Math.min(root.headerHeight, implicitHeight)
            width: height
            icon.name: "dialog-close"
            onClicked: root.close()
        }
    }

    ColumnLayout {
        visible: root.firstApplication != null

        anchors {
            fill: parent
            leftMargin: Kirigami.Units.largeSpacing
            rightMargin: Kirigami.Units.largeSpacing
            topMargin: Kirigami.Units.smallSpacing
        }

        Label {
73
            text: i18nc("@title:group", "CPU")
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
        }

        LineChartCard {
            Layout.fillHeight: false
            Layout.preferredHeight: Kirigami.Units.gridUnit * 3

            yRange { from: 0; to: 100; automatic: false }
            xRange { from: 0; to: 50 }
            unit: Formatter.Units.UnitPercent

            colorSource: Charts.SingleValueSource { value: Kirigami.Theme.negativeTextColor }
            valueSources: [
                Charts.ValueHistorySource {
                    id: cpuHistory
                    maximumHistory: 50
89
                    interval: 2000
90
                    value: root.firstApplication ? root.firstApplication.cpu / cpuCountSensor.value : 0
91
92
                }
            ]
93
94

            Sensors.Sensor { id: cpuCountSensor; sensorId: "system/cores/cores" }
95
96
        }
        Label {
97
            text: i18nc("@title:group", "Memory")
98
99
100
101
102
        }
        LineChartCard {
            Layout.fillHeight: false
            Layout.preferredHeight: Kirigami.Units.gridUnit * 3

103
            yRange { from: 0; to: totalMemorySensor.value; automatic: false }
104
105
106
107
108
109
110
111
112
            xRange { from: 0; to: 50 }
            unit: totalMemorySensor.unit

            colorSource: Charts.SingleValueSource { value: Kirigami.Theme.positiveTextColor }
            valueSources: [
                Charts.ValueHistorySource {
                    id: memoryHistory
                    value: root.firstApplication ? root.firstApplication.memory : 0
                    maximumHistory: 50
113
                    interval: 2000
114
115
116
117
118
119
                }
            ]

            Sensors.Sensor { id: totalMemorySensor; sensorId: "mem/physical/total" }
        }
        Label {
120
            text: i18nc("@title:group", "Network")
121
122
123
124
125
126
127
128
129
130
131
132
133
        }
        LineChartCard {
            Layout.fillHeight: false
            Layout.preferredHeight: Kirigami.Units.gridUnit * 3

            xRange { from: 0; to: 50 }
            unit: Formatter.Units.UnitKiloByteRate

            valueSources: [
                Charts.ValueHistorySource {
                    id: netInboundHistory
                    value: root.firstApplication ? root.firstApplication.netInbound : 0;
                    maximumHistory: 50
134
                    interval: 2000
135
136
137
138
139
                },
                Charts.ValueHistorySource {
                    id: netOutboundHistory
                    value: root.firstApplication ? root.firstApplication.netOutbound : 0;
                    maximumHistory: 50
140
                    interval: 2000
141
142
143
144
                }
            ]
        }
        Label {
145
            text: i18nc("@title:group", "Disk")
146
147
148
149
150
151
152
153
154
155
156
157
158
        }
        LineChartCard {
            Layout.fillHeight: false
            Layout.preferredHeight: Kirigami.Units.gridUnit * 3

            xRange { from: 0; to: 50 }
            unit: Formatter.Units.UnitKiloByteRate

            valueSources: [
                Charts.ValueHistorySource {
                    id: diskReadHistory
                    value: root.firstApplication ? root.firstApplication.diskRead : 0;
                    maximumHistory: 50
159
                    interval: 2000
160
161
162
163
164
                },
                Charts.ValueHistorySource {
                    id: diskWriteHistory
                    value: root.firstApplication ? root.firstApplication.diskWrite : 0;
                    maximumHistory: 50
165
                    interval: 2000
166
167
168
169
                }
            ]
        }

Yuri Chornoivan's avatar
Yuri Chornoivan committed
170
        Label { text: i18nc("@title:group", "Processes: %1", processTable.rows) }
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

        Rectangle {
            Layout.fillWidth: true
            Layout.fillHeight: true
            Layout.leftMargin: -Kirigami.Units.largeSpacing;
            Layout.rightMargin: -Kirigami.Units.largeSpacing;

            color: Kirigami.Theme.backgroundColor
            Kirigami.Theme.colorSet: Kirigami.Theme.View

            Table.BaseTableView {
                id: processTable

                anchors.fill: parent

                columnWidths: [0.5, 0.25, 0.25]
                sortName: "name"
                idRole: Process.ProcessDataModel.Attribute

190
                onSort: sortFilter.sort(column, order)
191

192
193
                model: Table.ProcessSortFilterModel {
                    id: sortFilter
194
                    sourceModel: processModel
195
196
                    hiddenAttributes: ["pid"]
                    filterPids: root.firstApplication ? root.firstApplication.pids : []
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
                }

                Process.ProcessDataModel {
                    id: processModel

                    enabled: root.visible && root.firstApplication != null

                    enabledAttributes: [
                        "name",
                        "usage",
                        "vmPSS",
                        "pid",
                    ]
                }

212
213
214
215
216
217
218
219
220
221
                delegate: DelegateChooser {
                    role: "Attribute"
                    DelegateChoice {
                        roleValue: "usage"
                        Table.BasicCellDelegate {
                            text: Formatter.Formatter.formatValue(parseInt(model.Value) / model.Maximum * 100, model.Unit)
                        }
                    }
                    DelegateChoice { Table.BasicCellDelegate { } }
                }
222
223
224
225
226
227
228
229
230
            }

            Kirigami.Separator { anchors.bottom: processTable.top; width: parent.width }
        }
    }

    Label {
        anchors.fill: parent
        anchors.margins: Kirigami.Units.largeSpacing
231
        text: i18nc("@info:placeholder", "Select an application to see its details.")
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
        wrapMode: Text.WordWrap
        visible: root.firstApplication == null
    }

    onApplicationsChanged: {
        cpuHistory.clear()
        memoryHistory.clear()
        netInboundHistory.clear()
        netOutboundHistory.clear()
        diskReadHistory.clear()
        diskWriteHistory.clear()
    }
    onFirstApplicationChanged: {
        sortFilter.invalidate()
    }
}