File indexing completed on 2024-05-19 05:48:09
0001 /* 0002 * SPDX-FileCopyrightText: 2011 Tirtha Chatterjee <tirtha.p.chatterjee@gmail.com> 0003 * 0004 * Based on the Itemviews NG project from Trolltech Labs 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "kitemlistkeyboardsearchmanager.h" 0010 0011 KItemListKeyboardSearchManager::KItemListKeyboardSearchManager(QObject *parent) 0012 : QObject(parent) 0013 , m_isSearchRestarted(false) 0014 , m_timeout(1000) 0015 { 0016 m_keyboardInputTime.invalidate(); 0017 } 0018 0019 KItemListKeyboardSearchManager::~KItemListKeyboardSearchManager() 0020 { 0021 } 0022 0023 bool KItemListKeyboardSearchManager::shouldClearSearchIfInputTimeReached() 0024 { 0025 const bool keyboardTimeWasValid = m_keyboardInputTime.isValid(); 0026 const qint64 keyboardInputTimeElapsed = m_keyboardInputTime.restart(); 0027 return (keyboardInputTimeElapsed > m_timeout) || !keyboardTimeWasValid; 0028 } 0029 0030 bool KItemListKeyboardSearchManager::isSearchAsYouTypeActive() const 0031 { 0032 return !m_searchedString.isEmpty() && !m_keyboardInputTime.hasExpired(m_timeout); 0033 } 0034 0035 void KItemListKeyboardSearchManager::addKeys(const QString &keys) 0036 { 0037 if (shouldClearSearchIfInputTimeReached()) { 0038 m_searchedString.clear(); 0039 } 0040 0041 const bool newSearch = m_searchedString.isEmpty(); 0042 0043 // Do not start a new search if the user pressed Space. Only add 0044 // it to the search string if a search is in progress already. 0045 if (newSearch && keys == QLatin1Char(' ')) { 0046 return; 0047 } 0048 0049 if (!keys.isEmpty()) { 0050 m_searchedString.append(keys); 0051 0052 // Special case: 0053 // If the same key is pressed repeatedly, the next item matching that key should be highlighted 0054 const QChar firstKey = m_searchedString.length() > 0 ? m_searchedString.at(0) : QChar(); 0055 const bool sameKey = m_searchedString.length() > 1 && m_searchedString.count(firstKey) == m_searchedString.length(); 0056 0057 // Searching for a matching item should start from the next item if either 0058 // 1. a new search is started and a search has not been restarted or 0059 // 2. a 'repeated key' search is done. 0060 const bool searchFromNextItem = (!m_isSearchRestarted && newSearch) || sameKey; 0061 0062 // to remember not to searchFromNextItem if selection was deselected 0063 // losing keyboard search context basically 0064 m_isSearchRestarted = false; 0065 0066 Q_EMIT changeCurrentItem(sameKey ? firstKey : m_searchedString, searchFromNextItem); 0067 } 0068 m_keyboardInputTime.start(); 0069 } 0070 0071 void KItemListKeyboardSearchManager::setTimeout(qint64 milliseconds) 0072 { 0073 m_timeout = milliseconds; 0074 } 0075 0076 qint64 KItemListKeyboardSearchManager::timeout() const 0077 { 0078 return m_timeout; 0079 } 0080 0081 void KItemListKeyboardSearchManager::cancelSearch() 0082 { 0083 m_isSearchRestarted = true; 0084 m_searchedString.clear(); 0085 } 0086 0087 void KItemListKeyboardSearchManager::slotCurrentChanged(int current, int previous) 0088 { 0089 Q_UNUSED(previous) 0090 0091 if (current < 0) { 0092 // The current item has been removed. We should cancel the search. 0093 cancelSearch(); 0094 } 0095 } 0096 0097 void KItemListKeyboardSearchManager::slotSelectionChanged(const KItemSet ¤t, const KItemSet &previous) 0098 { 0099 if (!previous.isEmpty() && current.isEmpty() && previous.count() > 0 && current.count() == 0) { 0100 // The selection has been emptied. We should cancel the search. 0101 cancelSearch(); 0102 } 0103 } 0104 0105 #include "moc_kitemlistkeyboardsearchmanager.cpp"