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 | |
28 | class 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 | */ |
87 | class KDEUI_EXPORT KRecursiveFilterProxyModel : public QSortFilterProxyModel |
88 | { |
89 | Q_OBJECT |
90 | public: |
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 | |
110 | protected: |
111 | /** |
112 | Reimplement this method for custom filtering strategies. |
113 | */ |
114 | virtual bool acceptRow(int sourceRow, const QModelIndex &sourceParent) const; |
115 | |
116 | private: |
117 | /** @reimp */ |
118 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; |
119 | |
120 | protected: |
121 | KRecursiveFilterProxyModelPrivate * const d_ptr; |
122 | |
123 | private: |
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 | |