Warning, /plasma/plasma-desktop/applets/kicker/package/contents/ui/ItemListDelegate.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2013-2015 Eike Hein <hein@kde.org>
0003
0004 SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006
0007 import QtQuick 2.15
0008
0009 import org.kde.plasma.components 3.0 as PlasmaComponents3
0010 import org.kde.kirigami 2.20 as Kirigami
0011 import org.kde.ksvg 1.0 as KSvg
0012
0013 import "code/tools.js" as Tools
0014
0015 Item {
0016 id: item
0017
0018 height: isSeparator ? separatorHeight : itemHeight
0019 width: ListView.view.width
0020
0021 // if it's not disabled and is either a leaf node or a node with children
0022 enabled: !isSeparator && !model.disabled && (!isParent || (isParent && hasChildren))
0023
0024 signal actionTriggered(string actionId, variant actionArgument)
0025 signal aboutToShowActionMenu(variant actionMenu)
0026
0027 readonly property real fullTextWidth: Math.ceil(icon.width + label.implicitWidth + arrow.width + row.anchors.leftMargin + row.anchors.rightMargin + row.actualSpacing)
0028 property bool isSeparator: (model.isSeparator === true)
0029 property bool sorted: (model.sorted === true)
0030 property bool hasChildren: (model.hasChildren === true)
0031 property bool hasActionList: ((model.favoriteId !== null)
0032 || (("hasActionList" in model) && (model.hasActionList === true)))
0033 property QtObject childDialog: null
0034 property Item menu: actionMenu
0035 readonly property bool pressed: mouseArea.pressed
0036 readonly property bool iconAndLabelsShouldlookSelected: mouseArea.pressed && !hasChildren
0037
0038 Accessible.role: isSeparator ? Accessible.Separator: Accessible.MenuItem
0039 Accessible.name: label.text
0040
0041 onHasChildrenChanged: {
0042 if (!hasChildren && ListView.view.currentItem === item) {
0043 ListView.view.currentIndex = -1;
0044 }
0045 }
0046
0047 onAboutToShowActionMenu: {
0048 var actionList = item.hasActionList ? model.actionList : [];
0049 Tools.fillActionMenu(i18n, actionMenu, actionList, ListView.view.model.favoritesModel, model.favoriteId);
0050 }
0051
0052 onActionTriggered: {
0053 if (Tools.triggerAction(ListView.view.model, model.index, actionId, actionArgument) === true) {
0054 kicker.expanded = false;
0055 }
0056 }
0057
0058 function openActionMenu(visualParent, x, y) {
0059 aboutToShowActionMenu(actionMenu);
0060 actionMenu.visualParent = visualParent;
0061 actionMenu.open(x, y);
0062 }
0063
0064 ActionMenu {
0065 id: actionMenu
0066
0067 onActionClicked: {
0068 item.actionTriggered(actionId, actionArgument);
0069 }
0070 }
0071
0072 MouseArea {
0073 id: mouseArea
0074
0075 anchors {
0076 left: parent.left
0077 right: parent.right
0078 verticalCenter: parent.verticalCenter
0079 }
0080
0081 height: parent.height
0082
0083 property int mouseCol
0084 property bool mousePressed: false
0085 property int pressX: -1
0086 property int pressY: -1
0087
0088 hoverEnabled: true
0089 acceptedButtons: Qt.LeftButton | Qt.RightButton
0090
0091 onPressed: mouse => {
0092 if (mouse.buttons & Qt.RightButton) {
0093 if (item.hasActionList) {
0094 item.openActionMenu(mouseArea, mouse.x, mouse.y);
0095 }
0096 } else {
0097 mousePressed = true;
0098 pressX = mouse.x;
0099 pressY = mouse.y;
0100 }
0101 }
0102
0103 onReleased: mouse => {
0104 if (mousePressed && !item.hasChildren) {
0105 item.ListView.view.model.trigger(index, "", null);
0106 kicker.expanded = false;
0107 }
0108
0109 mousePressed = false;
0110 pressX = -1;
0111 pressY = -1;
0112 }
0113
0114 onPositionChanged: mouse => {
0115 if (pressX !== -1 && model.url && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) {
0116 dragHelper.startDrag(kicker, model.url, model.decoration);
0117 mousePressed = false;
0118 pressX = -1;
0119 pressY = -1;
0120
0121 return;
0122 }
0123
0124 // FIXME: Correct escape angle calc for right screen edge.
0125 if (justOpenedTimer.running || !item.hasChildren) {
0126 item.ListView.view.currentIndex = index;
0127 } else {
0128 mouseCol = mouse.x;
0129
0130 if (index === item.ListView.view.currentIndex) {
0131 updateCurrentItem();
0132 } else if ((index === item.ListView.view.currentIndex - 1) && mouse.y < (itemHeight - 6)
0133 || (index === item.ListView.view.currentIndex + 1) && mouse.y > 5) {
0134
0135 if ((item.childDialog && item.childDialog.facingLeft)
0136 ? mouse.x > item.ListView.view.eligibleWidth - 5 : mouse.x < item.ListView.view.eligibleWidth + 5) {
0137 updateCurrentItem();
0138 }
0139 } else if ((item.childDialog && item.childDialog.facingLeft)
0140 ? mouse.x > item.ListView.view.eligibleWidth : mouse.x < item.ListView.view.eligibleWidth) {
0141 updateCurrentItem();
0142 }
0143
0144 updateCurrentItemTimer.start();
0145 }
0146 }
0147
0148 onContainsMouseChanged: {
0149 if (!containsMouse) {
0150 mousePressed = false;
0151 pressX = -1;
0152 pressY = -1;
0153 updateCurrentItemTimer.stop();
0154 }
0155 }
0156
0157 function updateCurrentItem() {
0158 item.ListView.view.currentIndex = index;
0159 item.ListView.view.eligibleWidth = Math.min(width, mouseCol);
0160 }
0161
0162 Timer {
0163 id: updateCurrentItemTimer
0164
0165 interval: 50
0166 repeat: false
0167
0168 onTriggered: parent.updateCurrentItem()
0169 }
0170 }
0171
0172 Row {
0173 id: row
0174
0175 anchors.left: parent.left
0176 anchors.leftMargin: highlightItemSvg.margins.left
0177 anchors.right: parent.right
0178 anchors.rightMargin: highlightItemSvg.margins.right
0179
0180 height: parent.height
0181
0182 spacing: Kirigami.Units.smallSpacing * 2
0183 readonly property real actualSpacing: ((icon.visible ? 1 : 0) * spacing) + ((arrow.visible ? 1 : 0) * spacing)
0184
0185 LayoutMirroring.enabled: (Qt.application.layoutDirection === Qt.RightToLeft)
0186
0187 Kirigami.Icon {
0188 id: icon
0189
0190 anchors.verticalCenter: parent.verticalCenter
0191
0192 width: visible ? Kirigami.Units.iconSizes.small : 0
0193 height: width
0194
0195 visible: iconsEnabled
0196
0197 animated: false
0198 selected: item.iconAndLabelsShouldlookSelected
0199 source: model.decoration
0200 }
0201
0202 PlasmaComponents3.Label {
0203 id: label
0204
0205 enabled: !isParent || (isParent && item.hasChildren)
0206
0207 anchors.verticalCenter: parent.verticalCenter
0208
0209 width: parent.width - icon.width - arrow.width - parent.actualSpacing
0210
0211 verticalAlignment: Text.AlignVCenter
0212
0213 textFormat: Text.PlainText
0214 wrapMode: Text.NoWrap
0215 elide: Text.ElideRight
0216 color: item.iconAndLabelsShouldlookSelected ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor
0217
0218 text: model.display
0219 }
0220
0221 Kirigami.Icon {
0222 id: arrow
0223
0224 anchors.verticalCenter: parent.verticalCenter
0225
0226 width: visible ? Kirigami.Units.iconSizes.small : 0
0227 height: width
0228
0229 visible: item.hasChildren
0230 opacity: (item.ListView.view.currentIndex === index) ? 1.0 : 0.4
0231 selected: item.iconAndLabelsShouldlookSelected
0232 source: Qt.application.layoutDirection !== Qt.RightToLeft
0233 ? "go-next-symbolic"
0234 : "go-next-rtl-symbolic"
0235 }
0236 }
0237
0238 Component {
0239 id: separatorComponent
0240
0241 KSvg.SvgItem {
0242 width: parent.width
0243 height: lineSvg.horLineHeight
0244
0245 svg: lineSvg
0246 elementId: "horizontal-line"
0247 }
0248 }
0249
0250 Loader {
0251 id: separatorLoader
0252
0253 anchors.left: parent.left
0254 anchors.leftMargin: highlightItemSvg.margins.left
0255 anchors.right: parent.right
0256 anchors.rightMargin: highlightItemSvg.margins.right
0257 anchors.verticalCenter: parent.verticalCenter
0258
0259 // Separator positions don't make sense when sorting everything alphabetically
0260 active: item.isSeparator && !item.sorted
0261
0262 asynchronous: false
0263 sourceComponent: separatorComponent
0264 }
0265
0266 Keys.onPressed: {
0267 if (event.key === Qt.Key_Menu && item.hasActionList) {
0268 event.accepted = true;
0269 item.openActionMenu(mouseArea);
0270 } else if ((event.key === Qt.Key_Enter || event.key === Qt.Key_Return) && !item.hasChildren) {
0271 if (!item.hasChildren) {
0272 event.accepted = true;
0273 item.ListView.view.model.trigger(index, "", null);
0274 kicker.expanded = false;
0275 }
0276 }
0277 }
0278 }