File indexing completed on 2024-05-19 04:49:51
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Nikolaj Hald Nielsen <nhn@kde.org> * 0003 * Copyright (c) 2009 Téo Mrnjavac <teo@kde.org> * 0004 * Copyright (c) 2010 Nanno Langstraat <langstr@gmail.com> * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify it under * 0007 * the terms of the GNU General Public License as published by the Free Software * 0008 * Foundation; either version 2 of the License, or (at your option) any later * 0009 * version. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0013 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License along with * 0016 * this program. If not, see <http://www.gnu.org/licenses/>. * 0017 ****************************************************************************************/ 0018 0019 #include "SortFilterProxy.h" 0020 0021 #include "SortAlgorithms.h" 0022 #include "SortScheme.h" 0023 0024 #include "core/support/Amarok.h" 0025 #include "amarokconfig.h" 0026 0027 0028 // Note: the 'sort' mode of QSortFilterProxyModel can Q_EMIT QAbstractItemModel::layoutChanged signals. 0029 0030 // Note: the QSortFilterProxyModel sorting is always on, even with an empty SortScheme. 0031 // - That case does not seem worth special-casing 0032 // - Cleanly "disabling" QSortFilterProxyModel sort mode is "under-documented" 0033 // and non-trivial (in Qt 4.6 at least). 0034 0035 // Note: the sort and filter functions have been combined into 1 QSFPM because that gives 0036 // optimal performance. If you have a reason to split sorting and filtering up into 0037 // separate QSFPMs again: be sure to put the SortProxy closer to the bottom than 0038 // the FilterProxy. Otherwise the FilterProxy's nicely-grouped 'rowsRemoved' 0039 // signals (when changing the filter) get fragmented into thousands of pieces by 0040 // the SortProxy, causing lousy performance on large playlists. 0041 0042 0043 namespace Playlist { 0044 0045 SortFilterProxy::SortFilterProxy( AbstractModel *belowModel, QObject *parent ) 0046 : ProxyBase( belowModel, parent ) 0047 { 0048 // Tell QSortFilterProxyModel: keep the filter correct when the underlying source model changes. 0049 // Qt will do this by receiving the standard QAbstractItemModel signals: dataChanged, rowsInserted, etc. 0050 setDynamicSortFilter( true ); 0051 0052 // Tell QSortFilterProxyModel: activate sorting. 0053 sort( 0 ); // 0 is a dummy column. 0054 0055 KConfigGroup config = Amarok::config(QStringLiteral("Playlist Search")); 0056 m_showOnlyMatches = config.readEntry( "ShowOnlyMatches", true ); 0057 } 0058 0059 SortFilterProxy::~SortFilterProxy() 0060 { 0061 } 0062 0063 0064 //! Sort-related functions 0065 0066 bool 0067 SortFilterProxy::lessThan( const QModelIndex & sourceModelIndexA, const QModelIndex & sourceModelIndexB ) const 0068 { 0069 int rowA = sourceModelIndexA.row(); 0070 int rowB = sourceModelIndexB.row(); 0071 return m_mlt( sourceModel(), rowA, rowB ); 0072 } 0073 0074 bool 0075 SortFilterProxy::isSorted() 0076 { 0077 return m_scheme.length() > 0; 0078 } 0079 0080 void 0081 SortFilterProxy::updateSortMap( const SortScheme &scheme ) 0082 { 0083 m_scheme = scheme; 0084 m_mlt.setSortScheme( m_scheme ); 0085 0086 invalidate(); // Tell QSortFilterProxyModel: re-sort 0087 } 0088 0089 0090 //! Filter-related functions 0091 0092 void 0093 SortFilterProxy::clearSearchTerm() 0094 { 0095 find( QString(), 0 ); 0096 ProxyBase::clearSearchTerm(); 0097 } 0098 0099 void 0100 SortFilterProxy::filterUpdated() 0101 { 0102 if ( m_showOnlyMatches ) 0103 invalidateFilter(); // Tell QSortFilterProxyModel: re-filter 0104 //else 0105 // Search criteria are not being used for filtering, so we can ignore the update 0106 } 0107 0108 int 0109 SortFilterProxy::find( const QString &searchTerm, int searchFields ) 0110 { 0111 m_currentSearchTerm = searchTerm; 0112 m_currentSearchFields = searchFields; 0113 0114 // Don't call 'filterUpdated()': our client must do that as part of the API. 0115 // This allows client 'PrettyListView' to give the user the time to type a few 0116 // characters before we do a filter run that might block for a few seconds. 0117 0118 return -1; 0119 } 0120 0121 void 0122 SortFilterProxy::showOnlyMatches( bool onlyMatches ) 0123 { 0124 m_showOnlyMatches = onlyMatches; 0125 0126 //make sure to update model when mode changes ( as we might have ignored any 0127 //number of changes to the search term ) 0128 invalidateFilter(); // Tell QSortFilterProxyModel: re-filter. 0129 } 0130 0131 bool 0132 SortFilterProxy::filterAcceptsRow( int sourceModelRow, const QModelIndex &sourceModelParent ) const 0133 { 0134 Q_UNUSED( sourceModelParent ); 0135 0136 if ( m_showOnlyMatches ) 0137 { 0138 if ( m_currentSearchTerm.isEmpty() ) 0139 return true; 0140 else 0141 return rowMatch( sourceModelRow, m_currentSearchTerm, m_currentSearchFields ); 0142 } else 0143 return true; 0144 } 0145 0146 0147 } //namespace Playlist 0148