1/*
2 Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20
21#ifndef KRECURSIVEFILTERPROXYMODEL_H
22#define KRECURSIVEFILTERPROXYMODEL_H
23
24#include <QtGui/QSortFilterProxyModel>
25
26#include "kdeui_export.h"
27
28class KRecursiveFilterProxyModelPrivate;
29
30/**
31 @brief Implements recursive filtering of models
32
33 QSortFilterProxyModel does not recurse when invoking a filtering stage, so that
34 if a particular row is filtered out, its children are not even checked to see if they match the filter.
35
36 For example, given a source model:
37
38 @verbatim
39 - A
40 - B
41 - - C
42 - - - D
43 - - - - E
44 - - - F
45 - - G
46 - - H
47 - I
48 @endverbatim
49
50 If a QSortFilterProxyModel is used with a filter matching A, D, G and I, the QSortFilterProxyModel will contain
51
52 @verbatim
53 - A
54 - I
55 @endverbatim
56
57 That is, even though D and E match the filter, they are not represented in the proxy model because B does not
58 match the filter and is filtered out.
59
60 The KRecursiveFilterProxyModel checks child indexes for filter matching and ensures that all matching indexes
61 are represented in the model.
62
63 In the above example, the KRecursiveFilterProxyModel will contain
64
65 @verbatim
66 - A
67 - B
68 - - C
69 - - - D
70 - - G
71 - I
72 @endverbatim
73
74 That is, the leaves in the model match the filter, but not necessarily the inner branches.
75
76 QSortFilterProxyModel provides the virtual method filterAcceptsRow to allow custom filter implementations.
77 Custom filter implementations can be written for KRecuriveFilterProxyModel using the acceptRow virtual method.
78
79 Note that using this proxy model is additional overhead compared to QSortFilterProxyModel as every index in the
80 model must be visited and queried.
81
82 @author Stephen Kelly <steveire@gmail.com>
83
84 @since 4.5
85
86*/
87class KDEUI_EXPORT KRecursiveFilterProxyModel : public QSortFilterProxyModel
88{
89 Q_OBJECT
90public:
91 /**
92 Constructor
93 */
94 explicit KRecursiveFilterProxyModel(QObject* parent = 0);
95
96 /**
97 Destructor
98 */
99 virtual ~KRecursiveFilterProxyModel();
100
101 /** @reimp */
102 void setSourceModel( QAbstractItemModel *model );
103
104 /**
105 * @reimplemented
106 */
107 virtual QModelIndexList match( const QModelIndex& start, int role, const QVariant& value, int hits = 1,
108 Qt::MatchFlags flags = Qt::MatchFlags( Qt::MatchStartsWith | Qt::MatchWrap ) ) const;
109
110protected:
111 /**
112 Reimplement this method for custom filtering strategies.
113 */
114 virtual bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const;
115
116private:
117 /** @reimp */
118 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
119
120protected:
121 KRecursiveFilterProxyModelPrivate * const d_ptr;
122
123private:
124 //@cond PRIVATE
125 Q_DECLARE_PRIVATE(KRecursiveFilterProxyModel)
126
127 Q_PRIVATE_SLOT(d_func(), void sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right))
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