Warning, /plasma/milou/lib/qml/ResultsView.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 *
0005 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 *
0007 */
0008
0009 import QtQuick
0010 import QtQuick.Templates as T
0011
0012 import org.kde.plasma.extras 2.0 as PlasmaExtras
0013 import org.kde.kirigami 2.20 as Kirigami
0014 import org.kde.milou 0.3 as Milou
0015
0016 ListView {
0017 id: listView
0018 property alias queryString: resultModel.queryString
0019 property alias singleRunner: resultModel.singleRunner
0020 property alias runnerManager: resultModel.runnerManager
0021
0022 property alias singleRunnerMetaData: resultModel.singleRunnerMetaData
0023 property alias querying: resultModel.querying
0024 property alias limit: resultModel.limit
0025 property bool reversed
0026 signal activated
0027 signal updateQueryString(string text, int cursorPosition)
0028
0029 // NOTE this also flips increment/decrementCurrentIndex (Bug 360789)
0030 verticalLayoutDirection: reversed ? ListView.BottomToTop : ListView.TopToBottom
0031 keyNavigationWraps: true
0032 highlight: PlasmaExtras.Highlight {
0033 pressed: (listView.currentItem as T.AbstractButton)?.down ?? false
0034 }
0035 highlightMoveDuration: 0
0036 activeFocusOnTab: true
0037 Accessible.role: Accessible.List
0038
0039 section {
0040 criteria: ViewSection.FullString
0041 property: "category"
0042 }
0043
0044 // This is used to keep track if the user has pressed enter before
0045 // the first result has been shown, in the case the first result should
0046 // be run when the model is populated
0047 property bool runAutomatically
0048
0049 // This is used to disable mouse selection if the user interacts only with keyboard
0050 property bool moved: false
0051 property point savedMousePosition: Milou.MouseHelper.globalMousePosition()
0052 function mouseMovedGlobally() {
0053 return savedMousePosition != Milou.MouseHelper.globalMousePosition();
0054 }
0055
0056 model: Milou.ResultsModel {
0057 id: resultModel
0058 limit: 15
0059 onQueryStringChangeRequested: {
0060 listView.updateQueryString(queryString, pos)
0061 }
0062 onQueryStringChanged: () => {
0063 resetView();
0064 // Do not run the results automatically, if the query changed since we pressed enter
0065 // BUG: 459859
0066 runAutomatically = false;
0067 }
0068 onModelReset: resetView()
0069
0070 onRowsInserted: {
0071 // Keep the selection at the top as items inserted to the beginning will shift it downwards
0072 // ListView will update its view after this signal is processed and then our callLater will set it back
0073 if (listView.currentIndex === 0) {
0074 Qt.callLater(function() {
0075 listView.currentIndex = 0;
0076 });
0077 }
0078
0079 if (runAutomatically) {
0080 // This needs to be delayed as running a result may close the window and clear the query
0081 // having us reset the model whilst in the middle of processing the insertion.
0082 // The proxy model chain that comes after us really doesn't like this.
0083 Qt.callLater(function() {
0084 resultModel.run(resultModel.index(0, 0));
0085 listView.activated();
0086 });
0087
0088 runAutomatically = false;
0089 }
0090 }
0091
0092 function resetView() {
0093 listView.currentIndex = 0;
0094 listView.moved = false;
0095 listView.savedMousePosition = Milou.MouseHelper.globalMousePosition();
0096 }
0097 }
0098
0099 delegate: ResultDelegate {
0100 id: resultDelegate
0101 width: listView.width
0102 reversed: listView.reversed
0103 }
0104
0105 //
0106 // vHanda: Ideally this should have gotten handled in the delagte's onReturnPressed
0107 // code, but the ListView doesn't seem forward keyboard events to the delgate when
0108 // it is not in activeFocus. Even manually adding Keys.forwardTo: resultDelegate
0109 // doesn't make any difference!
0110 Keys.onReturnPressed: event => runCurrentIndex(event);
0111 Keys.onEnterPressed: event => runCurrentIndex(event);
0112
0113 function runCurrentIndex(event) {
0114 if (!currentItem) {
0115 runAutomatically = true
0116 return;
0117 } else {
0118 // If user presses Shift+Return to invoke an action, invoke the first runner action
0119 if (event && event.modifiers === Qt.ShiftModifier
0120 && currentItem.additionalActions && currentItem.additionalActions.length > 0) {
0121 runAction(0)
0122 return
0123 }
0124
0125 if (currentItem.activeAction > -1) {
0126 runAction(currentItem.activeAction)
0127 return
0128 }
0129
0130 if (resultModel.run(resultModel.index(currentIndex, 0))) {
0131 activated()
0132 }
0133 runAutomatically = false
0134 }
0135 }
0136
0137 function runAction(index) {
0138 if (resultModel.runAction(resultModel.index(currentIndex, 0), index)) {
0139 activated()
0140 }
0141 }
0142
0143 onActiveFocusChanged: {
0144 if (!activeFocus && currentIndex == listView.count-1) {
0145 currentIndex = 0;
0146 }
0147 }
0148
0149 Keys.onTabPressed: {
0150 if (!currentItem || !currentItem.activateNextAction()) {
0151 if (reversed) {
0152 if (currentIndex == 0) {
0153 listView.nextItemInFocusChain(false).forceActiveFocus();
0154 return;
0155 }
0156 decrementCurrentIndex()
0157 } else {
0158 if (currentIndex == listView.count-1) {
0159 listView.nextItemInFocusChain(true).forceActiveFocus();
0160 return;
0161 }
0162 incrementCurrentIndex()
0163 }
0164 }
0165 }
0166 Keys.onBacktabPressed: {
0167 if (!currentItem || !currentItem.activatePreviousAction()) {
0168 if (reversed) {
0169 if (currentIndex == listView.count-1) {
0170 listView.nextItemInFocusChain(true).forceActiveFocus();
0171 return;
0172 }
0173 incrementCurrentIndex()
0174 } else {
0175 if (currentIndex == 0) {
0176 listView.nextItemInFocusChain(false).forceActiveFocus();
0177 return;
0178 }
0179 decrementCurrentIndex()
0180 }
0181
0182 // activate previous action cannot know whether we want to back tab from an action
0183 // to the main result or back tab from another search result, so we explicitly highlight
0184 // the last action here to provide a consistent navigation experience
0185 if (currentItem) {
0186 currentItem.activateLastAction()
0187 }
0188 }
0189 }
0190 Keys.onUpPressed: reversed ? incrementCurrentIndex() : decrementCurrentIndex();
0191 Keys.onDownPressed: reversed ? decrementCurrentIndex() : incrementCurrentIndex();
0192
0193 boundsBehavior: Flickable.StopAtBounds
0194
0195 function loadSettings() {
0196 resultModel.loadSettings()
0197 }
0198
0199 function setQueryString(queryString) {
0200 resultModel.queryString = queryString
0201 runAutomatically = false
0202 }
0203
0204 // Save drag data
0205 Item {
0206 id: dragHelper
0207 Drag.dragType: Drag.Automatic
0208 Drag.supportedActions: Qt.CopyAction | Qt.LinkAction
0209 Drag.onDragFinished: {
0210 Drag.mimeData = {};
0211 Drag.imageSource = "";
0212 }
0213 }
0214 }