1 /* 2 SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com> 3 4 SPDX-License-Identifier: LGPL-2.0-or-later 5 */ 6 7 #ifndef KRECURSIVEFILTERPROXYMODEL_H 8 #define KRECURSIVEFILTERPROXYMODEL_H 9 10 #include "kitemmodels_export.h" 11 12 #if KITEMMODELS_ENABLE_DEPRECATED_SINCE(5, 65) 13 #include <QSortFilterProxyModel> 14 15 #include <memory> 16 17 class KRecursiveFilterProxyModelPrivate; 18 19 /** 20 @class KRecursiveFilterProxyModel krecursivefilterproxymodel.h KRecursiveFilterProxyModel 21 22 @brief Implements recursive filtering of models 23 24 Until Qt 5.10, QSortFilterProxyModel did not recurse when invoking a filtering stage, so that 25 if a particular row is filtered out, its children are not even checked to see if they match the filter. 26 27 If you can depend on Qt >= 5.10, then just use QSortFilterProxyModel::setRecursiveFilteringEnabled(true), 28 and you don't need to use KRecursiveFilterProxyModel. 29 30 For example, given a source model: 31 32 @verbatim 33 - A 34 - B 35 - - C 36 - - - D 37 - - - - E 38 - - - F 39 - - G 40 - - H 41 - I 42 @endverbatim 43 44 If a QSortFilterProxyModel is used with a filter matching A, D, G and I, the QSortFilterProxyModel will contain 45 46 @verbatim 47 - A 48 - I 49 @endverbatim 50 51 That is, even though D and G match the filter, they are not represented in the proxy model because B does not 52 match the filter and is filtered out. 53 54 The KRecursiveFilterProxyModel checks child indexes for filter matching and ensures that all matching indexes 55 are represented in the model. 56 57 In the above example, the KRecursiveFilterProxyModel will contain 58 59 @verbatim 60 - A 61 - B 62 - - C 63 - - - D 64 - - G 65 - I 66 @endverbatim 67 68 That is, the leaves in the model match the filter, but not necessarily the inner branches. 69 70 QSortFilterProxyModel provides the virtual method filterAcceptsRow to allow custom filter implementations. 71 Custom filter implementations can be written for KRecuriveFilterProxyModel using the acceptRow virtual method. 72 73 Note that using this proxy model is additional overhead compared to QSortFilterProxyModel as every index in the 74 model must be visited and queried. 75 76 @author Stephen Kelly <steveire@gmail.com> 77 78 @since 4.5 79 80 @deprecated since 5.65, use QSortFilterProxyModel::setRecursiveFilteringEnabled(true) instead. See detailed description. 81 */ 82 class KITEMMODELS_EXPORT KRecursiveFilterProxyModel : public QSortFilterProxyModel 83 { 84 Q_OBJECT 85 public: 86 /** 87 Constructor 88 */ 89 KITEMMODELS_DEPRECATED_VERSION(5, 65, "Use QSortFilterProxyModel directly and QSortFilterProxyModel::setRecursiveFilteringEnabled(true)") 90 explicit KRecursiveFilterProxyModel(QObject *parent = nullptr); 91 92 /** 93 Destructor 94 */ 95 ~KRecursiveFilterProxyModel() override; 96 97 /** @reimp */ 98 void setSourceModel(QAbstractItemModel *model) override; 99 100 /** 101 * @reimplemented 102 */ 103 QModelIndexList match(const QModelIndex &start, 104 int role, 105 const QVariant &value, 106 int hits = 1, 107 Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const override; 108 109 protected: 110 /** 111 Reimplement this method for custom filtering strategies. 112 */ 113 virtual bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const; 114 115 /** @reimp */ 116 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; 117 118 std::unique_ptr<KRecursiveFilterProxyModelPrivate> const d_ptr; 119 120 private: 121 //@cond PRIVATE 122 Q_DECLARE_PRIVATE(KRecursiveFilterProxyModel) 123 124 Q_PRIVATE_SLOT(d_func(), 125 void sourceDataChanged(const QModelIndex &source_top_left, 126 const QModelIndex &source_bottom_right, 127 const QVector<int> &roles = QVector<int>())) 128 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeInserted(const QModelIndex &source_parent, int start, int end)) 129 Q_PRIVATE_SLOT(d_func(), void sourceRowsInserted(const QModelIndex &source_parent, int start, int end)) 130 Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end)) 131 Q_PRIVATE_SLOT(d_func(), void sourceRowsRemoved(const QModelIndex &source_parent, int start, int end)) 132 //@endcond 133 }; 134 135 #endif 136 137 #endif 138