diff --git a/language/interfaces/quickopenfilter.h b/language/interfaces/quickopenfilter.h index a04707851f..6b319f4ebc 100644 --- a/language/interfaces/quickopenfilter.h +++ b/language/interfaces/quickopenfilter.h @@ -1,200 +1,200 @@ /* * This file is part of KDevelop * * Copyright 2007 David Nolden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef QUICKOPEN_FILTER_H #define QUICKOPEN_FILTER_H #include #include #include /** * This is a simple filter-implementation that helps you implementing own quickopen data-providers. * You should use it when possible, because that way additional features(like regexp filtering) can * be implemented in a central place. * * This implementation does incremental filtering while * typing text, so it quite efficient for the most common case. * * The simplest way of using this is by reimplementing your data-provider * based on QuickOpenDataProviderBase and KDevelop::Filter. * * YourType should be the type that holds all the information you need. * The filter will hold the data, and you can access it through "items()". * * What you need to do to use it: * * Reimplement itemText(..) to provide the text filtering * should be performend on(This must be efficient). * * Call setItems(..) when starting a new quickopen session, or when the content * changes, to initialize the filter with your data. * * Call setFilter(..) with the text that should be filtered for on user-input. * * Use filteredItems() to provide data to quickopen. * */ namespace KDevelop { template class Filter { public: virtual ~Filter() { } ///Clears the filter, but not the data. void clearFilter() { m_filtered = m_items; m_oldFilterText.clear(); } ///Clears the filter and sets new data. The filter-text will be lost. void setItems( const QList& data ) { m_items = data; clearFilter(); } const QList& items() const { return m_items; } ///Returns the data that is left after the filtering const QList& filteredItems() const { return m_filtered; } ///Changes the filter-text and refilters the data void setFilter( const QString& text ) { QList filterBase = m_filtered; if( !text.startsWith( m_oldFilterText ) ) filterBase = m_items; //Start filtering based on the whole data //QRegExp exp(text, Qt::CaseInsensitive, QRegExp::Wildcard); m_filtered.clear(); foreach( const Item& data, filterBase ) if( itemText( data ).contains(text, Qt::CaseInsensitive) ) m_filtered << data; m_oldFilterText = text; } protected: ///Should return the text an item should be filtered by. virtual QString itemText( const Item& data ) const = 0; private: QString m_oldFilterText; QList m_filtered; QList m_items; }; } namespace KDevelop { template class FilterWithSeparator { public: virtual ~FilterWithSeparator() { } ///Clears the filter, but not the data. void clearFilter() { m_filtered = m_items; m_oldFilterText.clear(); } ///Clears the filter and sets new data. The filter-text will be lost. void setItems( const QList& data ) { m_items = data; clearFilter(); } const QList& items() const { return m_items; } ///Returns the data that is left after the filtering const QList& filteredItems() const { return m_filtered; } ///Changes the filter-text and refilters the data ///@param separator Should be a QChar, or if needed a QString template void setFilter( const QStringList& text, const SeparatorType& separator ) { QList filterBase = m_filtered; if(text.isEmpty() || m_oldFilterText.isEmpty()) { filterBase = m_items; - } else if(m_oldFilterText.mid(0, m_oldFilterText.length()-1) == text.mid(0, text.length()-1) && text.last().startsWith(m_oldFilterText.last())) { + } else if(m_oldFilterText.mid(0, m_oldFilterText.count()-1) == text.mid(0, text.count()-1) && text.last().startsWith(m_oldFilterText.last())) { //Good, the prefix is the same, and the last item has been extended }else if(m_oldFilterText.size() == text.size()-1 && m_oldFilterText == text.mid(0, text.size()-1)) { //Good, an item has been added }else{ //Start filtering based on the whole data, there was a big change to the filter filterBase = m_items; } //QRegExp exp(text, Qt::CaseInsensitive, QRegExp::Wildcard); m_filtered.clear(); foreach( const Item& data, filterBase ) { QString toFilter = itemText(data); int searchStart = 0; for(QStringList::const_iterator it = text.constBegin(); it != text.constEnd(); ++it) { if(searchStart != 0) { searchStart = toFilter.indexOf(separator, searchStart); if(searchStart == -1) break; ++searchStart; } searchStart = toFilter.indexOf(*it, searchStart, Qt::CaseInsensitive); if(searchStart == -1) break; ++searchStart; } if(searchStart == -1) continue; m_filtered << data; } m_oldFilterText = text; } protected: ///Should return the text an item should be filtered by. virtual QString itemText( const Item& data ) const = 0; private: QStringList m_oldFilterText; QList m_filtered; QList m_items; }; } #endif