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 2.15 0011 import QtQuick.Layouts 1.1 0012 0013 import org.kde.plasma.core 2.0 as PlasmaCore 0014 import org.kde.plasma.components 2.0 as PlasmaComponents // for ListItem 0015 import org.kde.plasma.components 3.0 as PlasmaComponents3 0016 0017 MouseArea { 0018 id: resultDelegate 0019 0020 property variant theModel: model 0021 property bool reversed: false 0022 0023 readonly property bool isCurrent: ListView.isCurrentItem // cannot properly Connect {} to this 0024 readonly property bool sectionHasChanged: (reversed && ListView.section != ListView.nextSection) 0025 || (!reversed && ListView.section != ListView.previousSection) 0026 0027 property int activeAction: -1 0028 0029 property string typeText: sectionHasChanged ? ListView.section : "" 0030 property var additionalActions: typeof actions !== "undefined" ? actions : [] 0031 property int categoryWidth: units.gridUnit * 10 0032 0033 Accessible.role: Accessible.ListItem 0034 Accessible.name: displayLabel.text 0035 Accessible.description: { 0036 var section = ListView.section; 0037 if (!section) { 0038 return ""; 0039 } 0040 var subtext = subtextLabel.text; 0041 if (subtext.length > 0) { 0042 return i18nd("milou", "%1, in category %2", subtext, section); 0043 } else { 0044 return i18nd("milou", "in category %1", section); 0045 } 0046 } 0047 0048 property bool __pressed: false 0049 property int __pressX: -1 0050 property int __pressY: -1 0051 0052 onIsCurrentChanged: { 0053 if (!isCurrent) { 0054 activeAction = -1 0055 } 0056 } 0057 0058 function activateNextAction() { 0059 if (activeAction === actionsRepeater.count - 1) { // last action, do nothing 0060 return false 0061 } 0062 ++activeAction 0063 return true 0064 } 0065 0066 function activatePreviousAction() { 0067 if (activeAction < 0) { // no action, do nothing 0068 return false 0069 } 0070 --activeAction 0071 return true 0072 } 0073 0074 function activateLastAction() { 0075 activeAction = actionsRepeater.count - 1 0076 } 0077 0078 width: listItem.implicitWidth 0079 height: listItem.implicitHeight 0080 0081 acceptedButtons: Qt.LeftButton 0082 hoverEnabled: true 0083 onPressed: { 0084 __pressed = true; 0085 __pressX = mouse.x; 0086 __pressY = mouse.y; 0087 } 0088 0089 onReleased: { 0090 if (__pressed) { 0091 listView.currentIndex = model.index 0092 listView.runCurrentIndex() 0093 } 0094 0095 __pressed = false; 0096 __pressX = -1; 0097 __pressY = -1; 0098 } 0099 0100 onPositionChanged: { 0101 if (__pressX != -1 && typeof dragHelper !== "undefined" && dragHelper.isDrag(__pressX, __pressY, mouse.x, mouse.y)) { 0102 var resultsModel = ListView.view.model; 0103 var mimeData = resultsModel.getMimeData(resultsModel.index(index, 0)); 0104 if (mimeData) { 0105 dragHelper.startDrag(resultDelegate, mimeData, model.decoration); 0106 __pressed = false; 0107 __pressX = -1; 0108 __pressY = -1; 0109 } 0110 } 0111 0112 if (!listView.moved && listView.mouseMovedGlobally()) { 0113 listView.moved = true 0114 listView.currentIndex = index 0115 } 0116 } 0117 0118 onContainsMouseChanged: { 0119 if (!containsMouse) { 0120 __pressed = false; 0121 __pressX = -1; 0122 __pressY = -1; 0123 } else { 0124 // In case we display the history we have a QML ListView which does not have the moved property 0125 if (!listView.hasOwnProperty("moved") || listView.moved) { 0126 listView.currentIndex = index 0127 } else if (listView.mouseMovedGlobally()) { 0128 listView.moved = true 0129 listView.currentIndex = index 0130 } 0131 } 0132 } 0133 0134 PlasmaComponents3.Label { 0135 id: typeText 0136 text: resultDelegate.typeText 0137 color: isCurrent ? Qt.tint(theme.disabledTextColor, Qt.rgba(theme.textColor.r, theme.textColor.g, theme.textColor.b, 0.4)) : theme.disabledTextColor 0138 0139 horizontalAlignment: Text.AlignRight 0140 verticalAlignment: Text.AlignVCenter 0141 elide: Text.ElideRight 0142 textFormat: Text.PlainText 0143 0144 width: resultDelegate.categoryWidth - units.largeSpacing 0145 anchors { 0146 left: parent.left 0147 verticalCenter: listItem.verticalCenter 0148 } 0149 } 0150 0151 PlasmaComponents.ListItem { 0152 id: listItem 0153 0154 readonly property int indexModifier: reversed ? 0 : 1 0155 0156 // fake pressed look 0157 checked: resultDelegate.pressed 0158 separatorVisible: resultDelegate.sectionHasChanged 0159 && !resultDelegate.isCurrent 0160 && (index === 0 || resultDelegate.ListView.view.currentIndex !== (index - indexModifier)) 0161 0162 Item { 0163 id: labelWrapper 0164 anchors { 0165 left: parent.left 0166 right: parent.right 0167 leftMargin: resultDelegate.categoryWidth 0168 } 0169 implicitHeight: labelLayout.implicitHeight 0170 0171 RowLayout { 0172 id: labelLayout 0173 0174 anchors { 0175 left: parent.left 0176 right: actionsRow.left 0177 rightMargin: units.smallSpacing 0178 verticalCenter: parent.verticalCenter 0179 } 0180 0181 PlasmaCore.IconItem { 0182 id: typePixmap 0183 Layout.preferredWidth: units.iconSizes.smallMedium 0184 Layout.preferredHeight: units.iconSizes.smallMedium 0185 Layout.fillHeight: true 0186 source: model.decoration 0187 usesPlasmaTheme: false 0188 animated: false 0189 } 0190 0191 PlasmaComponents3.Label { 0192 id: displayLabel 0193 text: String(typeof modelData !== "undefined" ? modelData : model.display) 0194 0195 elide: Text.ElideMiddle 0196 wrapMode: model.multiLine ? Text.WordWrap : Text.NoWrap 0197 maximumLineCount: model.multiLine ? Infinity : 1 0198 verticalAlignment: Text.AlignVCenter 0199 // For multiLine we offer styled text, otherwise we default to plain text 0200 textFormat: model.multiLine ? Text.StyledText : Text.PlainText 0201 // The extra spacing accounts for the right margin so the text doesn't overlap the actions 0202 Layout.maximumWidth: labelWrapper.width - typePixmap.width - actionsRow.width - 2 * PlasmaCore.Units.smallSpacing 0203 0204 PlasmaComponents3.ToolTip { 0205 text: displayLabel.text 0206 visible: displayLabelHoverHandler.hovered && displayLabel.truncated 0207 timeout: -1 0208 } 0209 0210 HoverHandler { 0211 id: displayLabelHoverHandler 0212 } 0213 } 0214 0215 PlasmaComponents3.Label { 0216 id: subtextLabel 0217 0218 // SourcesModel returns number of duplicates in this property 0219 // ResultsModel just has it as a boolean as you would expect from the name of the property 0220 text: model.isDuplicate === true || model.isDuplicate > 1 || resultDelegate.isCurrent ? String(model.subtext || "") : "" 0221 0222 // HACK If displayLabel is too long it will shift this label outside boundaries 0223 // but still render the text leading to it overlapping the action buttons looking horrible 0224 opacity: width > 0 ? 1 : 0 0225 0226 color: isCurrent ? Qt.tint(theme.disabledTextColor, Qt.rgba(theme.textColor.r, theme.textColor.g, theme.textColor.b, 0.4)) : theme.disabledTextColor 0227 0228 elide: Text.ElideMiddle 0229 wrapMode: Text.NoWrap 0230 maximumLineCount: 1 0231 verticalAlignment: Text.AlignVCenter 0232 textFormat: Text.PlainText 0233 0234 Layout.fillWidth: true 0235 PlasmaComponents3.ToolTip { 0236 text: subtextLabel.text 0237 visible: subtextLabelHoverHandler.hovered && subtextLabel.truncated 0238 timeout: -1 0239 } 0240 0241 HoverHandler { 0242 id: subtextLabelHoverHandler 0243 } 0244 } 0245 } 0246 0247 Row { 0248 id: actionsRow 0249 anchors.right: parent.right 0250 anchors.verticalCenter: parent.verticalCenter 0251 visible: resultDelegate.isCurrent 0252 0253 Repeater { 0254 id: actionsRepeater 0255 model: resultDelegate.additionalActions 0256 0257 PlasmaComponents3.ToolButton { 0258 width: height 0259 height: PlasmaCore.Units.iconSizes.medium 0260 visible: modelData.visible || true 0261 enabled: modelData.enabled || true 0262 0263 Accessible.role: Accessible.Button 0264 Accessible.name: modelData.text 0265 checkable: checked 0266 checked: resultDelegate.activeAction === index 0267 focus: resultDelegate.activeAction === index 0268 0269 PlasmaCore.IconItem { 0270 anchors.centerIn: parent 0271 implicitWidth: units.iconSizes.smallMedium 0272 implicitHeight: units.iconSizes.smallMedium 0273 // ToolButton cannot cope with QIcon 0274 source: modelData.icon || "" 0275 active: parent.hovered || parent.checked 0276 } 0277 0278 PlasmaComponents3.ToolTip { 0279 text: { 0280 var text = modelData.text || "" 0281 if (index === 0) { // Shift+Return will invoke first action 0282 text = i18ndc("milou", "placeholder is action e.g. run in terminal, in parenthesis is shortcut", "%1 (Shift+Return)", text) 0283 } 0284 return text 0285 } 0286 } 0287 0288 onClicked: resultDelegate.ListView.view.runAction(index) 0289 } 0290 } 0291 } 0292 } 0293 } 0294 }