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

0001 /*
0002     SPDX-FileCopyrightText: 2020 Mikel Johnson <mikel5764@gmail.com>
0003     SPDX-FileCopyrightText: 2021 Kai Uwe Broulik <kde@broulik.de>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 import QtQuick 2.15
0008 import QtQuick.Layouts 1.15
0009 import org.kde.plasma.private.kicker 0.1 as Kicker
0010 import org.kde.plasma.extras 2.0 as PlasmaExtras
0011 import org.kde.plasma.components 3.0 as PC3
0012 import org.kde.plasma.core as PlasmaCore
0013 import org.kde.kirigami 2.20 as Kirigami
0014 import org.kde.kitemmodels as KItemModels
0015 import org.kde.plasma.plasmoid 2.0
0016 
0017 RowLayout {
0018     id: root
0019     readonly property alias buttonImplicitWidth: buttonRepeaterRow.implicitWidth
0020     property bool shouldCollapseButtons: false
0021     spacing: kickoff.backgroundMetrics.spacing
0022 
0023     Kicker.SystemModel {
0024         id: systemModel
0025         favoritesModel: kickoff.rootModel.systemFavoritesModel
0026     }
0027 
0028     component FilteredModel : KItemModels.KSortFilterProxyModel {
0029         sourceModel: systemModel
0030 
0031         function systemFavoritesContainsRow(sourceRow, sourceParent) {
0032             const FavoriteIdRole = sourceModel.KItemModels.KRoleNames.role("favoriteId");
0033             const favoriteId = sourceModel.data(sourceModel.index(sourceRow, 0, sourceParent), FavoriteIdRole);
0034             return String(Plasmoid.configuration.systemFavorites).includes(favoriteId);
0035         }
0036 
0037         function trigger(index) {
0038             const sourceIndex = mapToSource(this.index(index, 0));
0039             systemModel.trigger(sourceIndex.row, "", null);
0040         }
0041 
0042         Component.onCompleted: {
0043             Plasmoid.configuration.valueChanged.connect((key, value) => {
0044                 if (key === "systemFavorites") {
0045                     invalidateFilter();
0046                 }
0047             });
0048         }
0049     }
0050 
0051     FilteredModel {
0052         id: filteredButtonsModel
0053         filterRowCallback: (sourceRow, sourceParent) =>
0054             systemFavoritesContainsRow(sourceRow, sourceParent)
0055     }
0056 
0057     FilteredModel {
0058         id: filteredMenuItemsModel
0059         filterRowCallback: root.shouldCollapseButtons
0060             ? null /*i.e. keep all rows*/
0061             : (sourceRow, sourceParent) => !systemFavoritesContainsRow(sourceRow, sourceParent)
0062     }
0063 
0064     Item {
0065         Layout.fillWidth: !Plasmoid.configuration.showActionButtonCaptions && Plasmoid.configuration.primaryActions === 3
0066     }
0067 
0068     RowLayout {
0069         id: buttonRepeaterRow
0070         // HACK Can't use `visible` property, as the layout needs to be
0071         // visible to be able to update its implicit size, which in turn is
0072         // be used to set shouldCollapseButtons.
0073         enabled: !root.shouldCollapseButtons
0074         opacity: !root.shouldCollapseButtons ? 1 : 0
0075         spacing: parent.spacing
0076         Repeater {
0077             id: buttonRepeater
0078 
0079             model: filteredButtonsModel
0080             delegate: PC3.ToolButton {
0081                 text: model.display
0082                 icon.name: model.decoration
0083                 onClicked: filteredButtonsModel.trigger(index);
0084                 display: Plasmoid.configuration.showActionButtonCaptions ? PC3.AbstractButton.TextBesideIcon : PC3.AbstractButton.IconOnly;
0085                 Layout.rightMargin: model.favoriteId === "switch-user" && Plasmoid.configuration.primaryActions === 3 ? Kirigami.Units.gridUnit : undefined
0086 
0087                 PC3.ToolTip.text: text
0088                 PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
0089                 PC3.ToolTip.visible: display === PC3.AbstractButton.IconOnly && hovered
0090 
0091                 Keys.onTabPressed: event => {
0092                     if (index === buttonRepeater.count - 1 && !leaveButton.shouldBeVisible) {
0093                         kickoff.firstHeaderItem.forceActiveFocus(Qt.TabFocusReason)
0094                     } else {
0095                         event.accepted = false
0096                     }
0097                 }
0098                 Keys.onLeftPressed: event => {
0099                     if (Qt.application.layoutDirection === Qt.LeftToRight) {
0100                         nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason)
0101                     } else if (index < buttonRepeater.count - 1 || leaveButton.shouldBeVisible) {
0102                         nextItemInFocusChain().forceActiveFocus(Qt.TabFocusReason)
0103                     }
0104                 }
0105                 Keys.onRightPressed: event => {
0106                     if (Qt.application.layoutDirection === Qt.RightToLeft) {
0107                         nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason)
0108                     } else if (index < buttonRepeater.count - 1 || leaveButton.shouldBeVisible) {
0109                         nextItemInFocusChain().forceActiveFocus(Qt.TabFocusReason)
0110                     }
0111                 }
0112             }
0113         }
0114     }
0115 
0116     Item {
0117         Layout.fillWidth: !Plasmoid.configuration.showActionButtonCaptions || Plasmoid.configuration.primaryActions !== 3
0118     }
0119 
0120     PC3.ToolButton {
0121         id: leaveButton
0122         readonly property int currentId: Plasmoid.configuration.primaryActions
0123         readonly property bool shouldBeVisible: Plasmoid.configuration.primaryActions !== 3 || root.shouldCollapseButtons
0124         Accessible.role: Accessible.ButtonMenu
0125         icon.width: Kirigami.Units.iconSizes.smallMedium
0126         icon.height: Kirigami.Units.iconSizes.smallMedium
0127         icon.name: ["system-log-out", "system-shutdown", "view-more-symbolic", "view-more-symbolic"][currentId]
0128         display: root.shouldCollapseButtons ? PC3.AbstractButton.TextBesideIcon : PC3.AbstractButton.IconOnly
0129         text: [i18n("Leave"), i18n("Power"), i18n("More"), i18n("More")][currentId]
0130         visible: shouldBeVisible
0131         // Make it look pressed while the menu is open
0132         down: contextMenu.status === PlasmaExtras.Menu.Open || pressed
0133         PC3.ToolTip.text: text
0134         PC3.ToolTip.visible: hovered
0135         PC3.ToolTip.delay: Kirigami.Units.toolTipDelay
0136         Keys.onTabPressed: event => {
0137             kickoff.firstHeaderItem.forceActiveFocus(Qt.TabFocusReason);
0138         }
0139         Keys.onLeftPressed: event => {
0140             if (Qt.application.layoutDirection == Qt.LeftToRight) {
0141                 nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason)
0142             }
0143         }
0144         Keys.onRightPressed: event => {
0145             if (Qt.application.layoutDirection == Qt.RightToLeft) {
0146                 nextItemInFocusChain(false).forceActiveFocus(Qt.BacktabFocusReason)
0147             }
0148         }
0149         onPressed: contextMenu.openRelative()
0150     }
0151 
0152     Instantiator {
0153         model: filteredMenuItemsModel
0154         delegate: PlasmaExtras.MenuItem {
0155             text: model.display
0156             icon: model.decoration
0157             onClicked: filteredMenuItemsModel.trigger(index)
0158         }
0159         onObjectAdded: (index, object) => contextMenu.addMenuItem(object)
0160         onObjectRemoved: (index, object) => contextMenu.removeMenuItem(object)
0161     }
0162 
0163     PlasmaExtras.Menu {
0164         id: contextMenu
0165         visualParent: leaveButton
0166         placement: {
0167             switch (Plasmoid.location) {
0168             case PlasmaCore.Types.LeftEdge:
0169             case PlasmaCore.Types.RightEdge:
0170             case PlasmaCore.Types.TopEdge:
0171                 return PlasmaExtras.Menu.BottomPosedRightAlignedPopup;
0172             case PlasmaCore.Types.BottomEdge:
0173             default:
0174                 return PlasmaExtras.Menu.TopPosedRightAlignedPopup;
0175             }
0176         }
0177     }
0178 }