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 }