Warning, /plasma/milou/lib/qml/ResultDelegate.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * This file is part of the KDE Milou Project 0003 * SPDX-FileCopyrightText: 2013-2014 Vishesh Handa <me@vhanda.in> 0004 * SPDX-FileCopyrightText: 2015-2016 Kai Uwe Broulik <kde@privat.broulik.de> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 * 0008 */ 0009 0010 import QtQuick 0011 import QtQuick.Layouts 0012 0013 import org.kde.kirigami as Kirigami 0014 import org.kde.plasma.components as PlasmaComponents3 0015 import org.kde.milou as Milou 0016 import org.kde.ksvg 1.0 as KSvg 0017 0018 PlasmaComponents3.ItemDelegate { 0019 id: resultDelegate 0020 0021 implicitHeight: labelWrapper.implicitHeight + Kirigami.Units.mediumSpacing * 2 0022 down: tapHandler.pressed 0023 hoverEnabled: true 0024 0025 readonly property int indexModifier: reversed ? 0 : 1 0026 readonly property QtObject theModel: model 0027 property bool reversed: false 0028 0029 readonly property bool isCurrent: ListView.isCurrentItem // cannot properly Connect {} to this 0030 readonly property bool sectionHasChanged: (reversed && ListView.section != ListView.nextSection) 0031 || (!reversed && ListView.section != ListView.previousSection) 0032 0033 property int activeAction: -1 0034 0035 property string typeText: sectionHasChanged ? ListView.section : "" 0036 property var additionalActions: typeof actions !== "undefined" ? actions : [] 0037 property int categoryWidth: Kirigami.Units.gridUnit * 10 0038 0039 Accessible.role: Accessible.ListItem 0040 Accessible.name: displayLabel.text 0041 Accessible.description: { 0042 var section = ListView.section; 0043 if (!section) { 0044 return ""; 0045 } 0046 var subtext = subtextLabel.text; 0047 if (subtext.length > 0) { 0048 return i18nd("milou", "%1, in category %2", subtext, section); 0049 } else { 0050 return i18nd("milou", "in category %1", section); 0051 } 0052 } 0053 0054 onIsCurrentChanged: { 0055 if (!isCurrent) { 0056 activeAction = -1 0057 } 0058 } 0059 0060 function activateNextAction() { 0061 if (activeAction === actionsRepeater.count - 1) { // last action, do nothing 0062 return false 0063 } 0064 ++activeAction 0065 return true 0066 } 0067 0068 function activatePreviousAction() { 0069 if (activeAction < 0) { // no action, do nothing 0070 return false 0071 } 0072 --activeAction 0073 return true 0074 } 0075 0076 function activateLastAction() { 0077 activeAction = actionsRepeater.count - 1 0078 } 0079 0080 onClicked: { 0081 resultDelegate.ListView.view.currentIndex = index 0082 resultDelegate.ListView.view.runCurrentIndex() 0083 } 0084 0085 DragHandler { 0086 id: dragHandler 0087 parent: labelWrapper 0088 target: labelLayout 0089 grabPermissions: PointerHandler.TakeOverForbidden 0090 onActiveChanged: if (active) { 0091 typePixmap.grabToImage((result) => { 0092 const mimeData = resultDelegate.ListView.view.model.getMimeData(resultDelegate.ListView.view.model.index(index, 0)); 0093 if (!mimeData) { 0094 return; 0095 } 0096 dragHelper.Drag.imageSource = result.url; 0097 dragHelper.Drag.mimeData = Milou.MouseHelper.generateMimeDataMap(mimeData); 0098 dragHelper.Drag.active = dragHandler.active; 0099 }); 0100 } else { 0101 dragHelper.Drag.active = false; 0102 } 0103 } 0104 0105 contentItem: Item { 0106 id: labelWrapper 0107 implicitHeight: labelLayout.implicitHeight 0108 0109 readonly property color dimmedTextColor: { 0110 if (resultDelegate.down) { 0111 return Qt.tint(Kirigami.Theme.highlightedTextColor, Qt.alpha(Kirigami.Theme.textColor, 0.2)); 0112 } else if (resultDelegate.isCurrent) { 0113 return Qt.tint(Kirigami.Theme.disabledTextColor, Qt.alpha(Kirigami.Theme.textColor, 0.4)); 0114 } else { 0115 return Kirigami.Theme.disabledTextColor; 0116 } 0117 } 0118 0119 HoverHandler { 0120 enabled: !resultDelegate.isCurrent 0121 onPointChanged: { 0122 // In case we display the history we have a QML ListView which does not have the moved property 0123 if (!resultDelegate.ListView.view.hasOwnProperty("moved") || resultDelegate.ListView.view.moved) { 0124 resultDelegate.ListView.view.currentIndex = index 0125 } else if (resultDelegate.ListView.view.mouseMovedGlobally()) { 0126 resultDelegate.ListView.view.moved = true 0127 resultDelegate.ListView.view.currentIndex = index 0128 } 0129 } 0130 } 0131 0132 // QTBUG-63395: DragHandler blocks ItemDelegate's clicked signal 0133 TapHandler { 0134 id: tapHandler 0135 onTapped: resultDelegate.clicked() 0136 } 0137 0138 KSvg.SvgItem { 0139 width: parent.width 0140 height: 1 0141 anchors.bottom: parent.top 0142 anchors.bottomMargin: Kirigami.Units.smallSpacing 0143 imagePath: "widgets/line" 0144 elementId: "horizontal-line" 0145 visible: resultDelegate.sectionHasChanged 0146 && !resultDelegate.isCurrent 0147 && resultDelegate.index !== 0 0148 && resultDelegate.ListView.view.currentIndex !== (index - indexModifier) 0149 opacity: 0.5 0150 } 0151 0152 PlasmaComponents3.Label { 0153 id: typeText 0154 anchors { 0155 left: parent.left 0156 verticalCenter: labelWrapper.verticalCenter 0157 } 0158 width: resultDelegate.categoryWidth - Kirigami.Units.largeSpacing 0159 color: labelWrapper.dimmedTextColor 0160 elide: Text.ElideRight 0161 text: resultDelegate.typeText 0162 textFormat: Text.PlainText 0163 horizontalAlignment: Text.AlignRight 0164 verticalAlignment: Text.AlignVCenter 0165 } 0166 0167 RowLayout { 0168 id: labelLayout 0169 anchors { 0170 left: parent.left 0171 leftMargin: resultDelegate.categoryWidth 0172 right: actionsRow.visible ? actionsRow.left : parent.right 0173 rightMargin: actionsRow.visible ? Kirigami.Units.smallSpacing : 0 0174 verticalCenter: parent.verticalCenter 0175 } 0176 0177 Kirigami.Icon { 0178 id: typePixmap 0179 Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium 0180 Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium 0181 Layout.rightMargin: Kirigami.Units.smallSpacing 0182 Layout.alignment: Qt.AlignVCenter 0183 source: model.decoration 0184 animated: false 0185 selected: resultDelegate.down 0186 } 0187 0188 PlasmaComponents3.Label { 0189 id: displayLabel 0190 text: String(typeof modelData !== "undefined" ? modelData : model.display) 0191 0192 elide: Text.ElideMiddle 0193 wrapMode: model.multiLine ? Text.WordWrap : Text.NoWrap 0194 maximumLineCount: model.multiLine ? Infinity : 1 0195 verticalAlignment: Text.AlignVCenter 0196 // For multiLine we offer styled text, otherwise we default to plain text 0197 textFormat: model.multiLine ? Text.StyledText : Text.PlainText 0198 color: resultDelegate.down ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.textColor 0199 // The extra spacing accounts for the right margin so the text doesn't overlap the actions 0200 Layout.rightMargin: Kirigami.Units.smallSpacing 0201 Layout.maximumWidth: labelLayout.width - typePixmap.implicitWidth 0202 0203 PlasmaComponents3.ToolTip { 0204 text: displayLabel.text 0205 visible: displayLabelHoverHandler.hovered && displayLabel.truncated 0206 timeout: -1 0207 } 0208 0209 HoverHandler { 0210 id: displayLabelHoverHandler 0211 } 0212 } 0213 0214 PlasmaComponents3.Label { 0215 id: subtextLabel 0216 Layout.fillWidth: true 0217 // HACK If displayLabel is too long it will shift this label outside boundaries 0218 // but still render the text leading to it overlapping the action buttons looking horrible 0219 opacity: width > 0 ? 1 : 0 0220 // SourcesModel returns number of duplicates in this property 0221 // ResultsModel just has it as a boolean as you would expect from the name of the property 0222 text: model.isDuplicate === true || model.isDuplicate > 1 || resultDelegate.isCurrent ? String(model.subtext || "") : "" 0223 0224 color: labelWrapper.dimmedTextColor 0225 elide: Text.ElideMiddle 0226 wrapMode: Text.NoWrap 0227 maximumLineCount: 1 0228 verticalAlignment: Text.AlignVCenter 0229 textFormat: Text.PlainText 0230 0231 PlasmaComponents3.ToolTip { 0232 text: subtextLabel.text 0233 visible: subtextLabelHoverHandler.hovered && subtextLabel.truncated 0234 timeout: -1 0235 } 0236 0237 HoverHandler { 0238 id: subtextLabelHoverHandler 0239 } 0240 } 0241 } 0242 0243 Row { 0244 id: actionsRow 0245 anchors.right: parent.right 0246 anchors.verticalCenter: labelWrapper.verticalCenter 0247 visible: resultDelegate.isCurrent && actionsRepeater.count > 0 0248 0249 Repeater { 0250 id: actionsRepeater 0251 model: resultDelegate.additionalActions 0252 0253 PlasmaComponents3.ToolButton { 0254 width: height 0255 height: Kirigami.Units.iconSizes.medium 0256 visible: modelData.visible || true 0257 enabled: modelData.enabled || true 0258 0259 Accessible.role: Accessible.Button 0260 Accessible.name: modelData.text 0261 checkable: checked 0262 checked: resultDelegate.activeAction === index 0263 focus: resultDelegate.activeAction === index 0264 0265 Kirigami.Icon { 0266 anchors.centerIn: parent 0267 implicitWidth: Kirigami.Units.iconSizes.smallMedium 0268 implicitHeight: Kirigami.Units.iconSizes.smallMedium 0269 // ToolButton cannot cope with QIcon 0270 source: modelData.iconSource || "" 0271 active: parent.hovered || parent.checked 0272 } 0273 0274 PlasmaComponents3.ToolTip { 0275 text: { 0276 var text = modelData.text || "" 0277 if (index === 0) { // Shift+Return will invoke first action 0278 text = i18ndc("milou", "placeholder is action e.g. run in terminal, in parenthesis is shortcut", "%1 (Shift+Return)", text) 0279 } 0280 return text 0281 } 0282 } 0283 0284 onClicked: resultDelegate.ListView.view.runAction(index) 0285 } 0286 } 0287 } 0288 } 0289 }