source: trunk/src/gui/itemviews/qabstractproxymodel.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 8.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qabstractproxymodel.h"
43
44#ifndef QT_NO_PROXYMODEL
45
46#include "qitemselectionmodel.h"
47#include <private/qabstractproxymodel_p.h>
48
49QT_BEGIN_NAMESPACE
50
51/*!
52 \since 4.1
53 \class QAbstractProxyModel
54 \brief The QAbstractProxyModel class provides a base class for proxy item
55 models that can do sorting, filtering or other data processing tasks.
56 \ingroup model-view
57
58 This class defines the standard interface that proxy models must use to be
59 able to interoperate correctly with other model/view components. It is not
60 supposed to be instantiated directly.
61
62 All standard proxy models are derived from the QAbstractProxyModel class.
63 If you need to create a new proxy model class, it is usually better to
64 subclass an existing class that provides the closest behavior to the one
65 you want to provide.
66
67 Proxy models that filter or sort items of data from a source model should
68 be created by using or subclassing QSortFilterProxyModel.
69
70 To subclass QAbstractProxyModel, you need to implement mapFromSource() and
71 mapToSource(). The mapSelectionFromSource() and mapSelectionToSource()
72 functions only need to be reimplemented if you need a behavior different
73 from the default behavior.
74
75 \note If the source model is deleted or no source model is specified, the
76 proxy model operates on a empty placeholder model.
77
78 \sa QSortFilterProxyModel, QAbstractItemModel, {Model/View Programming}
79*/
80
81//detects the deletion of the source model
82void QAbstractProxyModelPrivate::_q_sourceModelDestroyed()
83{
84 model = QAbstractItemModelPrivate::staticEmptyModel();
85}
86
87/*!
88 Constructs a proxy model with the given \a parent.
89*/
90
91QAbstractProxyModel::QAbstractProxyModel(QObject *parent)
92 :QAbstractItemModel(*new QAbstractProxyModelPrivate, parent)
93{
94 setSourceModel(QAbstractItemModelPrivate::staticEmptyModel());
95}
96
97/*!
98 \internal
99*/
100
101QAbstractProxyModel::QAbstractProxyModel(QAbstractProxyModelPrivate &dd, QObject *parent)
102 : QAbstractItemModel(dd, parent)
103{
104 setSourceModel(QAbstractItemModelPrivate::staticEmptyModel());
105}
106
107/*!
108 Destroys the proxy model.
109*/
110QAbstractProxyModel::~QAbstractProxyModel()
111{
112
113}
114
115/*!
116 Sets the given \a sourceModel to be processed by the proxy model.
117*/
118void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
119{
120 Q_D(QAbstractProxyModel);
121 if (d->model)
122 disconnect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed()));
123
124 if (sourceModel) {
125 d->model = sourceModel;
126 connect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed()));
127 } else {
128 d->model = QAbstractItemModelPrivate::staticEmptyModel();
129 }
130 d->roleNames = d->model->roleNames();
131}
132
133/*!
134 Returns the model that contains the data that is available through the proxy model.
135*/
136QAbstractItemModel *QAbstractProxyModel::sourceModel() const
137{
138 Q_D(const QAbstractProxyModel);
139 if (d->model == QAbstractItemModelPrivate::staticEmptyModel())
140 return 0;
141 return d->model;
142}
143
144/*!
145 \reimp
146 */
147bool QAbstractProxyModel::submit()
148{
149 Q_D(QAbstractProxyModel);
150 return d->model->submit();
151}
152
153/*!
154 \reimp
155 */
156void QAbstractProxyModel::revert()
157{
158 Q_D(QAbstractProxyModel);
159 d->model->revert();
160}
161
162
163/*!
164 \fn QModelIndex QAbstractProxyModel::mapToSource(const QModelIndex &proxyIndex) const
165
166 Reimplement this function to return the model index in the source model that
167 corresponds to the \a proxyIndex in the proxy model.
168
169 \sa mapFromSource()
170*/
171
172/*!
173 \fn QModelIndex QAbstractProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
174
175 Reimplement this function to return the model index in the proxy model that
176 corresponds to the \a sourceIndex from the source model.
177
178 \sa mapToSource()
179*/
180
181/*!
182 Returns a source selection mapped from the specified \a proxySelection.
183
184 Reimplement this method to map proxy selections to source selections.
185 */
186QItemSelection QAbstractProxyModel::mapSelectionToSource(const QItemSelection &proxySelection) const
187{
188 QModelIndexList proxyIndexes = proxySelection.indexes();
189 QItemSelection sourceSelection;
190 for (int i = 0; i < proxyIndexes.size(); ++i) {
191 const QModelIndex proxyIdx = mapToSource(proxyIndexes.at(i));
192 if (!proxyIdx.isValid())
193 continue;
194 sourceSelection << QItemSelectionRange(proxyIdx);
195 }
196 return sourceSelection;
197}
198
199/*!
200 Returns a proxy selection mapped from the specified \a sourceSelection.
201
202 Reimplement this method to map source selections to proxy selections.
203*/
204QItemSelection QAbstractProxyModel::mapSelectionFromSource(const QItemSelection &sourceSelection) const
205{
206 QModelIndexList sourceIndexes = sourceSelection.indexes();
207 QItemSelection proxySelection;
208 for (int i = 0; i < sourceIndexes.size(); ++i) {
209 const QModelIndex srcIdx = mapFromSource(sourceIndexes.at(i));
210 if (!srcIdx.isValid())
211 continue;
212 proxySelection << QItemSelectionRange(srcIdx);
213 }
214 return proxySelection;
215}
216
217/*!
218 \reimp
219 */
220QVariant QAbstractProxyModel::data(const QModelIndex &proxyIndex, int role) const
221{
222 Q_D(const QAbstractProxyModel);
223 return d->model->data(mapToSource(proxyIndex), role);
224}
225
226/*!
227 \reimp
228 */
229QVariant QAbstractProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
230{
231 Q_D(const QAbstractProxyModel);
232 int sourceSection;
233 if (orientation == Qt::Horizontal) {
234 const QModelIndex proxyIndex = index(0, section);
235 sourceSection = mapToSource(proxyIndex).column();
236 } else {
237 const QModelIndex proxyIndex = index(section, 0);
238 sourceSection = mapToSource(proxyIndex).row();
239 }
240 return d->model->headerData(sourceSection, orientation, role);
241}
242
243/*!
244 \reimp
245 */
246QMap<int, QVariant> QAbstractProxyModel::itemData(const QModelIndex &proxyIndex) const
247{
248 Q_D(const QAbstractProxyModel);
249 return d->model->itemData(mapToSource(proxyIndex));
250}
251
252/*!
253 \reimp
254 */
255Qt::ItemFlags QAbstractProxyModel::flags(const QModelIndex &index) const
256{
257 Q_D(const QAbstractProxyModel);
258 return d->model->flags(mapToSource(index));
259}
260
261/*!
262 \reimp
263 */
264bool QAbstractProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
265{
266 Q_D(QAbstractProxyModel);
267 return d->model->setData(mapToSource(index), value, role);
268}
269
270/*!
271 \reimp
272 */
273bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
274{
275 Q_D(QAbstractProxyModel);
276 int sourceSection;
277 if (orientation == Qt::Horizontal) {
278 const QModelIndex proxyIndex = index(0, section);
279 sourceSection = mapToSource(proxyIndex).column();
280 } else {
281 const QModelIndex proxyIndex = index(section, 0);
282 sourceSection = mapToSource(proxyIndex).row();
283 }
284 return d->model->setHeaderData(sourceSection, orientation, value, role);
285}
286
287QT_END_NAMESPACE
288
289#include "moc_qabstractproxymodel.cpp"
290
291#endif // QT_NO_PROXYMODEL
Note: See TracBrowser for help on using the repository browser.