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 }