Warning, /plasma/plasma-desktop/applets/taskmanager/package/contents/ui/GroupDialog.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2012-2013 Eike Hein <hein@kde.org>
0003     SPDX-FileCopyrightText: 2021 Fushan Wen <qydwhotmail@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 import QtQuick 2.15
0009 // Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6.
0010 import QtQml 2.15
0011 import QtQml.Models 2.15
0012 import QtQuick.Window 2.15
0013 
0014 import org.kde.plasma.core as PlasmaCore
0015 import org.kde.plasma.components 3.0 as PlasmaComponents3
0016 import org.kde.draganddrop 2.0
0017 import org.kde.kirigami 2.20 as Kirigami
0018 import org.kde.plasma.plasmoid 2.0
0019 
0020 import "code/layout.js" as LayoutManager
0021 
0022 PlasmaCore.Dialog {
0023     id: groupDialog
0024     visible: true
0025 
0026     type: PlasmaCore.Dialog.PopupMenu
0027     flags: Qt.WindowStaysOnTopHint
0028     hideOnWindowDeactivate: true
0029     location: Plasmoid.location
0030 
0031     readonly property real preferredWidth: Screen.width / (3 * Screen.devicePixelRatio)
0032     readonly property real preferredHeight: Screen.height / (2 * Screen.devicePixelRatio)
0033     readonly property real contentWidth: mainItem.width // No padding here to avoid text elide.
0034 
0035     property alias overflowing: scrollView.overflowing
0036     property var _oldAppletStatus: PlasmaCore.Types.UnknownStatus
0037 
0038     function findActiveTaskIndex() {
0039         if (!tasksModel.activeTask) {
0040             return;
0041         }
0042         for (let i = 0; i < groupListView.count; i++) {
0043             if (tasksModel.makeModelIndex(visualParent.index, i) === tasksModel.activeTask) {
0044                 groupListView.positionViewAtIndex(i, ListView.Contain); // Prevent visual glitches
0045                 groupListView.currentIndex = i;
0046                 return;
0047             }
0048         }
0049     }
0050 
0051     mainItem: MouseHandler {
0052         id: mouseHandler
0053         width: Math.min(groupDialog.preferredWidth, Math.max(groupListView.maxWidth, groupDialog.visualParent.width))
0054         height: Math.min(groupDialog.preferredHeight, groupListView.maxHeight)
0055 
0056         target: groupListView
0057         handleWheelEvents: !scrollView.overflowing
0058         isGroupDialog: true
0059 
0060         Keys.onEscapePressed: groupDialog.visible = false
0061 
0062         function moveRow(event, insertAt) {
0063             if (!(event.modifiers & Qt.ControlModifier) || !(event.modifiers & Qt.ShiftModifier)) {
0064                 event.accepted = false;
0065                 return;
0066             } else if (insertAt < 0 || insertAt >= groupListView.count) {
0067                 return;
0068             }
0069 
0070             const parentModelIndex = tasksModel.makeModelIndex(groupDialog.visualParent.index);
0071             const status = tasksModel.move(groupListView.currentIndex, insertAt, parentModelIndex);
0072             if (!status) {
0073                 return;
0074             }
0075 
0076             groupListView.currentIndex = insertAt;
0077         }
0078 
0079         PlasmaComponents3.ScrollView {
0080             id: scrollView
0081             anchors.fill: parent
0082             readonly property bool overflowing: leftPadding > 0 || rightPadding > 0 // Scrollbar is visible
0083 
0084             ListView {
0085                 id: groupListView
0086 
0087                 readonly property real maxWidth: groupFilter.maxTextWidth
0088                                                 + LayoutManager.horizontalMargins()
0089                                                 + Kirigami.Units.iconSizes.medium
0090                                                 + 2 * (LayoutManager.labelMargin + LayoutManager.iconMargin)
0091                                                 + scrollView.leftPadding + scrollView.rightPadding
0092                 // Use groupFilter.count because sometimes count is not updated in time (BUG 446105)
0093                 readonly property real maxHeight: groupFilter.count * (LayoutManager.verticalMargins() + Math.max(Kirigami.Units.iconSizes.sizeForLabels, Kirigami.Units.iconSizes.medium))
0094 
0095                 model: DelegateModel {
0096                     id: groupFilter
0097 
0098                     readonly property TextMetrics textMetrics: TextMetrics {}
0099                     property real maxTextWidth: 0
0100 
0101                     model: tasksModel
0102                     rootIndex: tasksModel.makeModelIndex(groupDialog.visualParent.index)
0103                     delegate: Task {
0104                         width: groupListView.width
0105                         visible: true
0106                         inPopup: true
0107 
0108                         ListView.onRemove: Qt.callLater(groupFilter.updateMaxTextWidth)
0109                         Connections {
0110                             enabled: index < 20 // 20 is based on performance considerations.
0111 
0112                             function onLabelTextChanged() { // ListView.onAdd included
0113                                 if (groupFilter.maxTextWidth === 0) {
0114                                     // Update immediately to avoid shrinking
0115                                     groupFilter.updateMaxTextWidth();
0116                                 } else {
0117                                     Qt.callLater(groupFilter.updateMaxTextWidth);
0118                                 }
0119                             }
0120                         }
0121                     }
0122 
0123                     function updateMaxTextWidth() {
0124                         let tempMaxTextWidth = 0;
0125                         // 20 is based on performance considerations.
0126                         for (let i = 0; i < Math.min(count, 20); i++) {
0127                             textMetrics.text = items.get(i).model.display;
0128                             if (textMetrics.boundingRect.width > tempMaxTextWidth) {
0129                                 tempMaxTextWidth = textMetrics.boundingRect.width;
0130                             }
0131                         }
0132                         maxTextWidth = tempMaxTextWidth;
0133                     }
0134                 }
0135 
0136                 reuseItems: false
0137 
0138                 Keys.onUpPressed: mouseHandler.moveRow(event, groupListView.currentIndex - 1);
0139                 Keys.onDownPressed: mouseHandler.moveRow(event, groupListView.currentIndex + 1);
0140 
0141                 onCountChanged: {
0142                     if (count > 0) {
0143                         backend.cancelHighlightWindows()
0144                     } else {
0145                         groupDialog.visible = false;
0146                     }
0147                 }
0148             }
0149         }
0150     }
0151 
0152     onVisibleChanged: {
0153         if (visible) {
0154             _oldAppletStatus = Plasmoid.status;
0155             Plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus;
0156 
0157             groupDialog.requestActivate();
0158             groupListView.forceActiveFocus(); // Active focus on ListView so keyboard navigation can work.
0159             Qt.callLater(findActiveTaskIndex);
0160         } else {
0161             Plasmoid.status = _oldAppletStatus;
0162             tasks.groupDialog = null;
0163             destroy();
0164         }
0165     }
0166 }