File indexing completed on 2025-01-05 04:55:04
0001 /* 0002 Copyright (c) 2009 Stephen Kelly <steveire@gmail.com> 0003 0004 This library is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to the 0016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA. 0018 */ 0019 0020 #ifndef KRECURSIVEFILTERPROXYMODEL_H 0021 #define KRECURSIVEFILTERPROXYMODEL_H 0022 0023 #include <QtCore/QSortFilterProxyModel> 0024 0025 class KRecursiveFilterProxyModelPrivate; 0026 0027 /** 0028 @class KRecursiveFilterProxyModel krecursivefilterproxymodel.h KRecursiveFilterProxyModel 0029 0030 @brief Implements recursive filtering of models 0031 0032 Until Qt 5.10, QSortFilterProxyModel did not recurse when invoking a filtering stage, so that 0033 if a particular row is filtered out, its children are not even checked to see if they match the filter. 0034 0035 If you can depend on Qt >= 5.10, then just use QSortFilterProxyModel::setRecursiveFiltering(true), 0036 and you don't need to use KRecursiveFilterProxyModel. 0037 0038 For example, given a source model: 0039 0040 @verbatim 0041 - A 0042 - B 0043 - - C 0044 - - - D 0045 - - - - E 0046 - - - F 0047 - - G 0048 - - H 0049 - I 0050 @endverbatim 0051 0052 If a QSortFilterProxyModel is used with a filter matching A, D, G and I, the QSortFilterProxyModel will contain 0053 0054 @verbatim 0055 - A 0056 - I 0057 @endverbatim 0058 0059 That is, even though D and E match the filter, they are not represented in the proxy model because B does not 0060 match the filter and is filtered out. 0061 0062 The KRecursiveFilterProxyModel checks child indexes for filter matching and ensures that all matching indexes 0063 are represented in the model. 0064 0065 In the above example, the KRecursiveFilterProxyModel will contain 0066 0067 @verbatim 0068 - A 0069 - B 0070 - - C 0071 - - - D 0072 - - G 0073 - I 0074 @endverbatim 0075 0076 That is, the leaves in the model match the filter, but not necessarily the inner branches. 0077 0078 QSortFilterProxyModel provides the virtual method filterAcceptsRow to allow custom filter implementations. 0079 Custom filter implementations can be written for KRecuriveFilterProxyModel using the acceptRow virtual method. 0080 0081 Note that using this proxy model is additional overhead compared to QSortFilterProxyModel as every index in the 0082 model must be visited and queried. 0083 0084 @author Stephen Kelly <steveire@gmail.com> 0085 0086 @since 4.5 0087 0088 */ 0089 class KRecursiveFilterProxyModel : public QSortFilterProxyModel 0090 { 0091 Q_OBJECT 0092 public: 0093 /** 0094 Constructor 0095 */ 0096 explicit KRecursiveFilterProxyModel(QObject *parent = nullptr); 0097 0098 /** 0099 Destructor 0100 */ 0101 virtual ~KRecursiveFilterProxyModel(); 0102 0103 /** @reimp */ 0104 void setSourceModel(QAbstractItemModel *model) Q_DECL_OVERRIDE; 0105 0106 /** 0107 * @reimplemented 0108 */ 0109 QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits = 1, 0110 Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const Q_DECL_OVERRIDE; 0111 0112 protected: 0113 /** 0114 Reimplement this method for custom filtering strategies. 0115 */ 0116 virtual bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const; 0117 0118 /** @reimp */ 0119 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const Q_DECL_OVERRIDE; 0120 0121 KRecursiveFilterProxyModelPrivate *const d_ptr; 0122 0123 private: 0124 //@cond PRIVATE 0125 Q_DECLARE_PRIVATE(KRecursiveFilterProxyModel) 0126 0127 Q_PRIVATE_SLOT(d_func(), void sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right, const QVector<int> &roles = QVector<int>())) 0128 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeInserted(const QModelIndex &source_parent, int start, int end)) 0129 Q_PRIVATE_SLOT(d_func(), void sourceRowsInserted(const QModelIndex &source_parent, int start, int end)) 0130 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end)) 0131 Q_PRIVATE_SLOT(d_func(), void sourceRowsRemoved(const QModelIndex &source_parent, int start, int end)) 0132 //@endcond 0133 }; 0134 0135 #endif