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 }