/*SPDX-FileCopyrightText: 2012-2013 Eike Hein <hein@kde.org>SPDX-FileCopyrightText: 2021 Fushan Wen <qydwhotmail@gmail.com>SPDX-License-Identifier: GPL-2.0-or-later*/pragma ComponentBehavior: Boundimport QtQuickimport QtQml.Modelsimport org.kde.plasma.core as PlasmaCoreimport org.kde.plasma.components as PlasmaComponents3import org.kde.kirigami as Kirigamiimport org.kde.plasma.plasmoidimport plasma.applet.org.kde.plasma.taskmanager as TaskManagerAppletPlasmaCore.PopupPlasmaWindow {id: groupDialogwidth: mouseHandler.implicitWidth + leftPadding + rightPaddingheight: mouseHandler.implicitHeight + topPadding + bottomPaddinganimated: trueremoveBorderStrategy: Plasmoid.location === PlasmaCore.Types.Floating? PlasmaCore.AppletPopup.AtScreenEdges: PlasmaCore.AppletPopup.AtScreenEdges | PlasmaCore.AppletPopup.AtPanelEdgesmargin: (Plasmoid.containmentDisplayHints & PlasmaCore.Types.ContainmentPrefersFloatingApplets) ? Kirigami.Units.largeSpacing : 0Timer {id: closeOnTimerinterval: 100onTriggered: {if (!active && !mouseHandler.containsDrag) {visible = false;}}}onActiveChanged: {if (!active) {closeOnTimer.restart();}}popupDirection: switch (Plasmoid.location) {case PlasmaCore.Types.TopEdge:return Qt.BottomEdgecase PlasmaCore.Types.LeftEdge:return Qt.RightEdgecase PlasmaCore.Types.RightEdge:return Qt.LeftEdgedefault:return Qt.TopEdge}readonly property real preferredWidth: Screen.width / 3readonly property real preferredHeight: Screen.height / 2readonly property real contentWidth: mainItem.width // No padding here to avoid text elide.property /*PlasmaCore.ItemStatus*/int _oldAppletStatus: PlasmaCore.Types.UnknownStatusfunction findActiveTaskIndex(): void {if (!tasksModel.activeTask) {return;}for (let i = 0; i < groupListView.count; i++) {if (tasksModel.makeModelIndex((visualParent as Task).index, i) === tasksModel.activeTask) {groupListView.positionViewAtIndex(i, ListView.Contain); // Prevent visual glitchesgroupListView.currentIndex = i;return;}}}Component.onCompleted: {// Don't bind visible at creation, otherwise it// will be made visible before assigning the visual partent// making the window flickering in the center of the screen before being moved// in the correct positionvisible = true}mainItem: MouseHandler {id: mouseHandlerimplicitWidth: Math.min(groupDialog.preferredWidth, Math.max(groupListView.maxWidth, groupDialog.visualParent.width))implicitHeight: Math.min(groupDialog.preferredHeight, groupListView.maxHeight)target: groupListViewhandleWheelEvents: !scrollView.overflowingisGroupDialog: trueKeys.onEscapePressed: event => {groupDialog.visible = false;}onContainsDragChanged: {if (!active && !containsDrag) {groupDialog.visible = false;}}function moveRow(event: KeyEvent, insertAt: int): void {if (!(event.modifiers & Qt.ControlModifier) || !(event.modifiers & Qt.ShiftModifier)) {event.accepted = false;return;} else if (insertAt < 0 || insertAt >= groupListView.count) {return;}const parentModelIndex = tasksModel.makeModelIndex((groupDialog.visualParent as Task).index);const status = tasksModel.move(groupListView.currentIndex, insertAt, parentModelIndex);if (!status) {return;}groupListView.currentIndex = insertAt;}PlasmaComponents3.ScrollView {id: scrollView// To achieve a bottom-to-top layout on vertical panels, the task manager// is rotated by 180 degrees(see main.qml). This makes the group dialog's// items rotated, so un-rotate them here to fix that.rotation: Plasmoid.configuration.reverseMode && Plasmoid.formFactor === PlasmaCore.Types.Vertical ? 180 : 0anchors.fill: parentreadonly property bool overflowing: leftPadding > 0 || rightPadding > 0 // Scrollbar is visibleListView {id: groupListViewreadonly property real maxWidth: groupFilter.maxTextWidth+ TaskManagerApplet.LayoutMetrics.horizontalMargins()+ Kirigami.Units.iconSizes.medium+ 2 * (TaskManagerApplet.LayoutMetrics.labelMargin + TaskManagerApplet.LayoutMetrics.iconMargin)+ scrollView.leftPadding + scrollView.rightPadding// Use groupFilter.count because sometimes count is not updated in time (BUG 446105)readonly property real maxHeight: groupFilter.count * (TaskManagerApplet.LayoutMetrics.verticalMargins() + Math.max(Kirigami.Units.iconSizes.sizeForLabels, Kirigami.Units.iconSizes.medium))model: DelegateModel {id: groupFilterreadonly property TextMetrics textMetrics: TextMetrics {}property real maxTextWidth: 0model: tasksModelrootIndex: tasksModel.makeModelIndex((groupDialog.visualParent as Task).index)delegate: Task {id: delegatewidth: groupListView.widthvisible: trueinPopup: truetasksRoot: tasksListView.onRemove: Qt.callLater(groupFilter.updateMaxTextWidth)Connections {enabled: delegate.index < 20 // 20 is based on performance considerations.function onLabelTextChanged(): void { // ListView.onAdd includedif (groupFilter.maxTextWidth === 0) {// Update immediately to avoid shrinkinggroupFilter.updateMaxTextWidth();} else {Qt.callLater(groupFilter.updateMaxTextWidth);}}}}function updateMaxTextWidth(): void {let tempMaxTextWidth = 0;// 20 is based on performance considerations.for (let i = 0; i < Math.min(count, 20); i++) {textMetrics.text = items.get(i).model.display;if (textMetrics.boundingRect.width > tempMaxTextWidth) {tempMaxTextWidth = textMetrics.boundingRect.width;}}maxTextWidth = tempMaxTextWidth;}}reuseItems: falseKeys.onUpPressed: event => mouseHandler.moveRow(event, groupListView.currentIndex - 1)Keys.onDownPressed: event => mouseHandler.moveRow(event, groupListView.currentIndex + 1)onCountChanged: {if (count > 0) {tasks.cancelHighlightWindows()} else {groupDialog.visible = false;}}}}}onVisibleChanged: {if (visible) {_oldAppletStatus = Plasmoid.status;Plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus;groupDialog.requestActivate();groupListView.forceActiveFocus(); // Active focus on ListView so keyboard navigation can work.Qt.callLater(findActiveTaskIndex);} else {Plasmoid.status = _oldAppletStatus;tasks.groupDialog = null;destroy();}}}