File indexing completed on 2024-05-12 15:42:59

0001 /*
0002     SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KRECURSIVEFILTERPROXYMODEL_H
0008 #define KRECURSIVEFILTERPROXYMODEL_H
0009 
0010 #include "kitemmodels_export.h"
0011 
0012 #if KITEMMODELS_ENABLE_DEPRECATED_SINCE(5, 65)
0013 #include <QSortFilterProxyModel>
0014 
0015 #include <memory>
0016 
0017 class KRecursiveFilterProxyModelPrivate;
0018 
0019 /**
0020   @class KRecursiveFilterProxyModel krecursivefilterproxymodel.h KRecursiveFilterProxyModel
0021 
0022   @brief Implements recursive filtering of models
0023 
0024   Until Qt 5.10, QSortFilterProxyModel did not recurse when invoking a filtering stage, so that
0025   if a particular row is filtered out, its children are not even checked to see if they match the filter.
0026 
0027   If you can depend on Qt >= 5.10, then just use QSortFilterProxyModel::setRecursiveFilteringEnabled(true),
0028   and you don't need to use KRecursiveFilterProxyModel.
0029 
0030   For example, given a source model:
0031 
0032   @verbatim
0033     - A
0034     - B
0035     - - C
0036     - - - D
0037     - - - - E
0038     - - - F
0039     - - G
0040     - - H
0041     - I
0042   @endverbatim
0043 
0044   If a QSortFilterProxyModel is used with a filter matching A, D, G and I, the QSortFilterProxyModel will contain
0045 
0046   @verbatim
0047     - A
0048     - I
0049   @endverbatim
0050 
0051   That is, even though D and G match the filter, they are not represented in the proxy model because B does not
0052   match the filter and is filtered out.
0053 
0054   The KRecursiveFilterProxyModel checks child indexes for filter matching and ensures that all matching indexes
0055   are represented in the model.
0056 
0057   In the above example, the KRecursiveFilterProxyModel will contain
0058 
0059   @verbatim
0060     - A
0061     - B
0062     - - C
0063     - - - D
0064     - - G
0065     - I
0066   @endverbatim
0067 
0068   That is, the leaves in the model match the filter, but not necessarily the inner branches.
0069 
0070   QSortFilterProxyModel provides the virtual method filterAcceptsRow to allow custom filter implementations.
0071   Custom filter implementations can be written for KRecuriveFilterProxyModel using the acceptRow virtual method.
0072 
0073   Note that using this proxy model is additional overhead compared to QSortFilterProxyModel as every index in the
0074   model must be visited and queried.
0075 
0076   @author Stephen Kelly <steveire@gmail.com>
0077 
0078   @since 4.5
0079 
0080   @deprecated since 5.65, use QSortFilterProxyModel::setRecursiveFilteringEnabled(true) instead. See detailed description.
0081 */
0082 class KITEMMODELS_EXPORT KRecursiveFilterProxyModel : public QSortFilterProxyModel
0083 {
0084     Q_OBJECT
0085 public:
0086     /**
0087       Constructor
0088     */
0089     KITEMMODELS_DEPRECATED_VERSION(5, 65, "Use QSortFilterProxyModel directly and QSortFilterProxyModel::setRecursiveFilteringEnabled(true)")
0090     explicit KRecursiveFilterProxyModel(QObject *parent = nullptr);
0091 
0092     /**
0093       Destructor
0094     */
0095     ~KRecursiveFilterProxyModel() override;
0096 
0097     /** @reimp */
0098     void setSourceModel(QAbstractItemModel *model) override;
0099 
0100     /**
0101      * @reimplemented
0102      */
0103     QModelIndexList match(const QModelIndex &start,
0104                           int role,
0105                           const QVariant &value,
0106                           int hits = 1,
0107                           Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const override;
0108 
0109 protected:
0110     /**
0111       Reimplement this method for custom filtering strategies.
0112     */
0113     virtual bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const;
0114 
0115     /** @reimp */
0116     bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
0117 
0118     std::unique_ptr<KRecursiveFilterProxyModelPrivate> const d_ptr;
0119 
0120 private:
0121     //@cond PRIVATE
0122     Q_DECLARE_PRIVATE(KRecursiveFilterProxyModel)
0123 
0124     Q_PRIVATE_SLOT(d_func(),
0125                    void sourceDataChanged(const QModelIndex &source_top_left,
0126                                           const QModelIndex &source_bottom_right,
0127                                           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
0136 
0137 #endif