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 }