Warning, /plasma/plasma-systemmonitor/src/faces/processtable/contents/ui/FullRepresentation.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
0003 * SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
0004 * SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl>
0005 *
0006 * SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008
0009 import QtQuick
0010 import QtQuick.Controls
0011 import QtQuick.Layouts
0012
0013 import org.kde.kirigami as Kirigami
0014
0015 import org.kde.ksysguard.faces as Faces
0016 import org.kde.ksysguard.process as Process
0017
0018 import org.kde.ksysguard.table as Table
0019
0020 Faces.SensorFace {
0021 id: root
0022
0023 readonly property var config: controller.faceConfiguration
0024
0025 actions: [
0026 Kirigami.Action {
0027 icon.name: "search"
0028 text: i18nc("@action", "Search")
0029 displayHint: Kirigami.DisplayHint.KeepVisible
0030 displayComponent: Kirigami.SearchField {
0031 text: table.nameFilterString
0032 onTextEdited: table.nameFilterString = text;
0033 onAccepted: table.nameFilterString = text;
0034 Component.onCompleted: forceActiveFocus()
0035 }
0036 },
0037
0038 Kirigami.Action {
0039 icon.name: "process-stop"
0040 text: i18nc("@action", "End Process")
0041 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.TerminateSignal)
0042 enabled: table.selection.hasSelection
0043 },
0044
0045 // Note: can't use ActionGroup there because of https://bugreports.qt.io/browse/QTBUG-86860
0046 Kirigami.Action {
0047 id: listAction
0048 icon.name: "view-list-details"
0049 checkable: true
0050 checked: root.config.viewMode === mode
0051 visible: table.treeModeSupported
0052 text: i18nc("@action", "Display as List")
0053
0054 displayHint: Kirigami.DisplayHint.IconOnly
0055 property int mode: 0
0056 onTriggered: {
0057 root.config.viewMode = mode
0058 checked = true;
0059 treeAction.checked = false;
0060 }
0061 },
0062
0063 Kirigami.Action {
0064 id: treeAction
0065 icon.name: "view-list-tree"
0066 checkable: true
0067 checked: root.config.viewMode === mode
0068 visible: table.treeModeSupported
0069 text: i18nc("@action", "Display as Tree")
0070 displayHint: Kirigami.DisplayHint.IconOnly
0071 property int mode: 1
0072 onTriggered: {
0073 root.config.viewMode = mode;
0074 checked = true;
0075 listAction.checked = false;
0076 }
0077 },
0078
0079 Kirigami.Action {
0080 icon.name: showGroup.checkedAction.icon.name
0081 text: i18nc("@action %1 is view type", "Show: %1", showGroup.checkedAction.text)
0082
0083 Kirigami.Action {
0084 text: i18nc("@item:inmenu", "Own Processes")
0085 checkable: true
0086 checked: root.config.userFilterMode == mode
0087 icon.name: "view-process-own"
0088 property int mode: Table.ProcessSortFilterModel.ViewOwn
0089 ActionGroup.group: showGroup
0090 }
0091
0092 Kirigami.Action {
0093 text: i18nc("@item:inmenu", "User Processes")
0094 checkable: true
0095 checked: root.config.userFilterMode == mode
0096 icon.name: "view-process-users"
0097 property int mode: Table.ProcessSortFilterModel.ViewUser
0098 ActionGroup.group: showGroup
0099 }
0100
0101 Kirigami.Action {
0102 text: i18nc("@item:inmenu", "System Processes")
0103 checkable: true
0104 checked: root.config.userFilterMode == mode
0105 icon.name: "view-process-system"
0106 property int mode: Table.ProcessSortFilterModel.ViewSystem
0107 ActionGroup.group: showGroup
0108 }
0109
0110 Kirigami.Action {
0111 text: i18nc("@item:inmenu", "All Processes")
0112 checkable: true
0113 checked: root.config.userFilterMode == mode
0114 icon.name: "view-process-all"
0115 property int mode: Table.ProcessSortFilterModel.ViewAll
0116 ActionGroup.group: showGroup
0117 }
0118 },
0119
0120 Kirigami.Action {
0121 id: configureColumnsAction
0122 icon.name: "configure"
0123 text: i18nc("@action", "Configure columns…")
0124 onTriggered: columnDialog.open()
0125 }
0126 ]
0127
0128 ActionGroup { id: showGroup; onTriggered: root.config.userFilterMode = action.mode }
0129
0130 contentItem: ProcessTableView {
0131 id: table
0132
0133 flatList: root.config.viewMode === 0
0134 viewMode: root.config.userFilterMode
0135 onViewModeChanged: root.config.userFilterMode = viewMode
0136
0137 columnWidths: root.config.columnWidths
0138 onColumnWidthsChanged: root.config.columnWidths = columnWidths
0139 sortName: root.config.sortColumn
0140 onSortNameChanged: root.config.sortColumn = sortName
0141 sortOrder: root.config.sortDirection
0142 onSortOrderChanged: root.config.sortDirection = sortOrder
0143
0144 onContextMenuRequested: (index, position) => {
0145 contextMenu.popup(null, position.x, position.y)
0146 }
0147
0148 onHeaderContextMenuRequested: (column, position) => {
0149 headerContextMenu.popup(null, position)
0150 }
0151
0152 enabledColumns: columnDialog.visibleColumns
0153 columnDisplay: columnDialog.columnDisplay
0154
0155 Keys.onPressed: event => {
0156 if (event.matches(StandardKey.Delete)) {
0157 processHelper.sendSignalToSelection(Process.ProcessController.TerminateSignal);
0158 event.accepted = true;
0159 } else if ((event.modifiers & Qt.ShiftModifier) && (event.key == Qt.Key_Delete)) {
0160 processHelper.sendSignalToSelection(Process.ProcessController.KillSignal);
0161 event.accepted = true;
0162 }
0163 }
0164 }
0165
0166 Menu {
0167 id: contextMenu
0168
0169 // MenuItem { text: i18n("Set priority...") }
0170 Menu {
0171 title: i18nc("@action:inmenu", "Send Signal")
0172
0173 MenuItem {
0174 text: i18nc("@action:inmenu Send Signal", "Suspend (STOP)");
0175 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.StopSignal)
0176 }
0177 MenuItem {
0178 text: i18nc("@action:inmenu Send Signal", "Continue (CONT)")
0179 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.ContinueSignal)
0180 }
0181 MenuItem {
0182 text: i18nc("@action:inmenu Send Signal", "Hangup (HUP)")
0183 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.HangupSignal)
0184 }
0185 MenuItem {
0186 text: i18nc("@action:inmenu Send Signal", "Interrupt (INT)")
0187 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.InterruptSignal)
0188 }
0189 MenuItem {
0190 text: i18nc("@action:inmenu Send Signal", "Terminate (TERM)")
0191 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.TerminateSignal)
0192 }
0193 MenuItem {
0194 text: i18nc("@action:inmenu Send Signal", "Kill (KILL)")
0195 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.KillSignal)
0196 }
0197 MenuItem {
0198 text: i18nc("@action:inmenu Send Signal", "User 1 (USR1)")
0199 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.User1Signal)
0200 }
0201 MenuItem {
0202 text: i18nc("@action:inmenu Send Signal", "User 2 (USR2)")
0203 onTriggered: processHelper.sendSignalToSelection(Process.ProcessController.User2Signal)
0204 }
0205 }
0206 // MenuItem { text: i18nc("@action:inmenu", "Show Application Window") }
0207 MenuSeparator { }
0208 MenuItem {
0209 icon.name: "process-stop";
0210 text: i18ncp("@action:inmenu", "End Process", "End %1 Processes", killDialog.items.length);
0211 onTriggered: {
0212 processHelper.sendSignalToSelection(Process.ProcessController.TerminateSignal)
0213 }
0214
0215 }
0216 }
0217
0218 Menu {
0219 id: headerContextMenu
0220
0221 MenuItem {
0222 text: i18nc("@action:inmenu", "Configure Columns…")
0223 onClicked: columnDialog.open()
0224 }
0225 }
0226
0227 Table.KillDialog {
0228 id: killDialog
0229
0230 property int signalToSend
0231
0232 title: i18ncp("@title:window", "End Process", "End %1 Processes", items.length)
0233 killButtonText: i18ncp("@action:button", "End Process", "End Processes", items.length)
0234 killButtonIcon: "process-stop"
0235 questionText: i18np("Are you sure you want to end this process?\nAny unsaved work may be lost.",
0236 "Are you sure you want to end these %1 processes?\nAny unsaved work may be lost.", items.length)
0237
0238 items: table.selectedProcesses
0239
0240 delegate: Kirigami.Padding {
0241 horizontalPadding: Kirigami.Units.largeSpacing
0242 verticalPadding: Kirigami.Units.smallSpacing
0243
0244 contentItem: Kirigami.TitleSubtitle {
0245 title: modelData.name
0246 subtitle: i18nc("@item:intable %1 is process id, %2 is user name", "Process ID %1, owned by %2", modelData.pid, modelData.username)
0247 }
0248 }
0249
0250 onAccepted: {
0251 root.config.askWhenKilling = !killDialog.doNotAskAgain
0252 var pids = items.map(i => i.pid)
0253 processHelper.sendSignal(pids, signalToSend)
0254 }
0255 }
0256
0257 Process.ProcessController {
0258 id: processHelper
0259
0260 property var killSignals: [
0261 Process.ProcessController.TerminateSignal,
0262 Process.ProcessController.KillSignal
0263 ]
0264
0265 function sendSignalToSelection(sig) {
0266 if (root.config.askWhenKilling && killSignals.includes(sig)) {
0267 killDialog.signalToSend = sig
0268 killDialog.open()
0269 } else {
0270 var pids = table.selectedProcesses.map(i => i.pid)
0271 sendSignal(pids, sig);
0272 }
0273 }
0274 }
0275
0276 Table.ColumnConfigurationDialog {
0277 id: columnDialog
0278
0279 sourceModel: table.processModel.attributesModel
0280
0281 sortedColumns: root.config.sortedColumns
0282
0283 fixedColumns: ["name"]
0284
0285 onAccepted: {
0286 root.config.sortedColumns = sortedColumns
0287 root.config.columnDisplay = JSON.stringify(columnDisplay)
0288 }
0289
0290 Component.onCompleted: {
0291 setColumnDisplay(JSON.parse(root.config.columnDisplay))
0292 }
0293 }
0294 }