source: trunk/src/gui/itemviews/qproxymodel.cpp@ 138

Last change on this file since 138 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 17.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qproxymodel.h"
43
44#ifndef QT_NO_PROXYMODEL
45#include <private/qproxymodel_p.h>
46#include <qsize.h>
47#include <qstringlist.h>
48
49QT_BEGIN_NAMESPACE
50
51/*!
52 \class QProxyModel
53 \obsolete
54 \brief The QProxyModel class provides support for processing data
55 passed between another model and a view.
56
57 \ingroup model-view
58
59 If you want to do filtering and sorting, see QSortFilterProxyModel.
60
61 Proxy models provide a standard model interface that can be used to
62 manipulate the data retrieved through an underlying model. They can be used to
63 perform operations such as sorting and filtering on the data obtained without
64 changing the contents of the model.
65
66 Just as with subclasses of QAbstractItemView, QProxyModel provides the setModel()
67 function that is used to specify the model to be acted on by the proxy.
68 Views can be connected to either the underlying model or the proxy model with
69 \l QAbstractItemView::setModel().
70
71 Since views rely on the information provided in model indexes to identify
72 items of data from models, and to position these items in some visual
73 representation, proxy models must create their own model indexes instead of
74 supplying model indexes from their underlying models.
75
76 \sa \link model-view-programming.html Model/View Programming\endlink QAbstractItemModel
77
78*/
79
80/*!
81 Constructs a proxy model with the given \a parent.
82*/
83
84QProxyModel::QProxyModel(QObject *parent)
85 : QAbstractItemModel(*new QProxyModelPrivate, parent)
86{
87 Q_D(QProxyModel);
88 setModel(&d->empty);
89}
90
91/*!
92 \internal
93*/
94QProxyModel::QProxyModel(QProxyModelPrivate &dd, QObject *parent)
95 : QAbstractItemModel(dd, parent)
96{
97 Q_D(QProxyModel);
98 setModel(&d->empty);
99}
100
101/*!
102 Destroys the proxy model.
103*/
104QProxyModel::~QProxyModel()
105{
106}
107
108/*!
109 Sets the given \a model to be processed by the proxy model.
110*/
111void QProxyModel::setModel(QAbstractItemModel *model)
112{
113 Q_D(QProxyModel);
114 if (d->model && d->model != &d->empty)
115 disconnectFromModel(d->model);
116 if (model) {
117 d->model = model;
118 connectToModel(model);
119 } else {
120 d->model = &d->empty;
121 }
122}
123
124/*!
125 Returns the model that contains the data that is available through the
126 proxy model.
127*/
128QAbstractItemModel *QProxyModel::model() const
129{
130 Q_D(const QProxyModel);
131 return d->model;
132}
133
134/*!
135 Returns the model index with the given \a row, \a column, and \a parent.
136
137 \sa QAbstractItemModel::index()
138*/
139QModelIndex QProxyModel::index(int row, int column, const QModelIndex &parent) const
140{
141 Q_D(const QProxyModel);
142 return setProxyModel(d->model->index(row, column, setSourceModel(parent)));
143}
144
145/*!
146 Returns the model index that corresponds to the parent of the given \a child
147 index.
148*/
149QModelIndex QProxyModel::parent(const QModelIndex &child) const
150{
151 Q_D(const QProxyModel);
152 return setProxyModel(d->model->parent(setSourceModel(child)));
153}
154
155/*!
156 Returns the number of rows for the given \a parent.
157
158 \sa QAbstractItemModel::rowCount()
159*/
160int QProxyModel::rowCount(const QModelIndex &parent) const
161{
162 Q_D(const QProxyModel);
163 return d->model->rowCount(setSourceModel(parent));
164}
165
166/*!
167 Returns the number of columns for the given \a parent.
168
169 \sa QAbstractItemModel::columnCount()
170*/
171int QProxyModel::columnCount(const QModelIndex &parent) const
172{
173 Q_D(const QProxyModel);
174 return d->model->columnCount(setSourceModel(parent));
175}
176
177/*!
178 Returns true if the item corresponding to the \a parent index has child
179 items; otherwise returns false.
180
181 \sa QAbstractItemModel::hasChildren()
182*/
183bool QProxyModel::hasChildren(const QModelIndex &parent) const
184{
185 Q_D(const QProxyModel);
186 return d->model->hasChildren(setSourceModel(parent));
187}
188
189/*!
190 Returns the data stored in the item with the given \a index under the
191 specified \a role.
192*/
193QVariant QProxyModel::data(const QModelIndex &index, int role) const
194{
195 Q_D(const QProxyModel);
196 return d->model->data(setSourceModel(index), role);
197}
198
199/*!
200 Sets the \a role data for the item at \a index to \a value.
201 Returns true if successful; otherwise returns false.
202
203 The base class implementation returns false. This function and
204 data() must be reimplemented for editable models.
205
206 \sa data() itemData() QAbstractItemModel::setData()
207*/
208bool QProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
209{
210 Q_D(const QProxyModel);
211 return d->model->setData(setSourceModel(index), value, role);
212}
213
214/*!
215 Returns the data stored in the \a section of the header with specified
216 \a orientation under the given \a role.
217*/
218QVariant QProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
219{
220 Q_D(const QProxyModel);
221 return d->model->headerData(section, orientation, role);
222}
223
224/*!
225 Sets the \a role data in the \a section of the header with the specified
226 \a orientation to the \a value given.
227
228 \sa QAbstractItemModel::setHeaderData()
229*/
230bool QProxyModel::setHeaderData(int section, Qt::Orientation orientation,
231 const QVariant &value, int role)
232{
233 Q_D(const QProxyModel);
234 return d->model->setHeaderData(section, orientation, value, role);
235}
236
237/*!
238 Returns a list of MIME types that are supported by the model.
239*/
240QStringList QProxyModel::mimeTypes() const
241{
242 Q_D(const QProxyModel);
243 return d->model->mimeTypes();
244}
245
246/*!
247 Returns MIME data for the specified \a indexes in the model.
248*/
249QMimeData *QProxyModel::mimeData(const QModelIndexList &indexes) const
250{
251 Q_D(const QProxyModel);
252 QModelIndexList lst;
253 for (int i = 0; i < indexes.count(); ++i)
254 lst.append(setSourceModel(indexes.at(i)));
255 return d->model->mimeData(lst);
256}
257
258/*!
259 Returns true if the model accepts the \a data dropped onto an attached
260 view for the specified \a action; otherwise returns false.
261
262 The \a parent, \a row, and \a column details can be used to control
263 which MIME types are acceptable to different parts of a model when
264 received via the drag and drop system.
265*/
266bool QProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
267 int row, int column, const QModelIndex &parent)
268{
269 Q_D(const QProxyModel);
270 return d->model->dropMimeData(data, action, row, column, setSourceModel(parent));
271}
272
273/*!
274 Returns the drop actions that are supported by the model; this is
275 a combination of the individual actions defined in \l Qt::DropActions.
276
277 The selection of drop actions provided by the model will influence the
278 behavior of the component that started the drag and drop operation.
279
280 \sa \link dnd.html Drag and Drop\endlink
281*/
282Qt::DropActions QProxyModel::supportedDropActions() const
283{
284 Q_D(const QProxyModel);
285 return d->model->supportedDropActions();
286}
287
288/*!
289 Inserts \a count rows into the model, creating new items as children of
290 the given \a parent. The new rows are inserted before the \a row
291 specified. If the \a parent item has no children, a single column is
292 created to contain the required number of rows.
293
294 Returns true if the rows were successfully inserted; otherwise
295 returns false.
296
297 \sa QAbstractItemModel::insertRows()*/
298bool QProxyModel::insertRows(int row, int count, const QModelIndex &parent)
299{
300 Q_D(const QProxyModel);
301 return d->model->insertRows(row, count, setSourceModel(parent));
302}
303
304/*!
305 Inserts \a count columns into the model, creating new items as children of
306 the given \a parent. The new columns are inserted before the \a column
307 specified. If the \a parent item has no children, a single row is created
308 to contain the required number of columns.
309
310 Returns true if the columns were successfully inserted; otherwise
311 returns false.
312
313 \sa QAbstractItemModel::insertColumns()
314*/
315bool QProxyModel::insertColumns(int column, int count, const QModelIndex &parent)
316{
317 Q_D(const QProxyModel);
318 return d->model->insertColumns(column, count, setSourceModel(parent));
319}
320
321/*!
322 Fetches more child items of the given \a parent. This function is used by views
323 to tell the model that they can display more data than the model has provided.
324
325 \sa QAbstractItemModel::fetchMore()
326*/
327void QProxyModel::fetchMore(const QModelIndex &parent)
328{
329 Q_D(const QProxyModel);
330 d->model->fetchMore(parent);
331}
332
333/*!
334 Returns the item flags for the given \a index.
335*/
336Qt::ItemFlags QProxyModel::flags(const QModelIndex &index) const
337{
338 Q_D(const QProxyModel);
339 return d->model->flags(setSourceModel(index));
340}
341
342/*!
343 Sorts the child items in the specified \a column according to the sort
344 order defined by \a order.
345
346 \sa QAbstractItemModel::sort()
347*/
348void QProxyModel::sort(int column, Qt::SortOrder order)
349{
350 Q_D(QProxyModel);
351 d->model->sort(column, order);
352}
353
354/*!
355 Returns a list of model indexes that each contain the given \a value for
356 the \a role specified. The search begins at the \a start index and is
357 performed according to the specified \a flags. The search continues until
358 the number of matching data items equals \a hits, the last row is reached,
359 or the search reaches \a start again, depending on whether \c MatchWrap is
360 specified in \a flags.
361
362 \sa QAbstractItemModel::match()
363*/
364QModelIndexList QProxyModel::match(const QModelIndex &start,
365 int role, const QVariant &value,
366 int hits, Qt::MatchFlags flags) const
367{
368 Q_D(const QProxyModel);
369 return d->model->match(start, role, value, hits, flags);
370}
371
372/*!
373 Returns the size of the item that corresponds to the specified \a index.
374*/
375QSize QProxyModel::span(const QModelIndex &index) const
376{
377 Q_D(const QProxyModel);
378 return d->model->span(setSourceModel(index));
379}
380
381/*!
382 */
383bool QProxyModel::submit()
384{
385 Q_D(QProxyModel);
386 return d->model->submit();
387}
388
389/*!
390 */
391void QProxyModel::revert()
392{
393 Q_D(QProxyModel);
394 d->model->revert();
395}
396
397/*!
398 \internal
399 Change the model pointer in the given \a source_index to point to the proxy model.
400 */
401QModelIndex QProxyModel::setProxyModel(const QModelIndex &source_index) const
402{
403 QModelIndex proxy_index = source_index;
404 if (proxy_index.isValid())
405 proxy_index.m = this;
406 return proxy_index;
407}
408
409/*!
410 \internal
411 Change the model pointer in the given \a proxy_index to point to the source model.
412 */
413QModelIndex QProxyModel::setSourceModel(const QModelIndex &proxy_index) const
414{
415 Q_D(const QProxyModel);
416 QModelIndex source_index = proxy_index;
417 source_index.m = d->model;
418 return source_index;
419}
420
421/*!
422 \internal
423 Connect to all the signals emitted by given \a model.
424*/
425void QProxyModel::connectToModel(const QAbstractItemModel *model) const
426{
427 connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
428 this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex)));
429 connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
430 this, SIGNAL(headerDataChanged(Qt::Orientation,int,int))); // signal to signal
431 connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
432 this, SLOT(_q_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
433 connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
434 this, SLOT(_q_sourceRowsInserted(QModelIndex,int,int)));
435 connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
436 this, SLOT(_q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
437 connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
438 this, SLOT(_q_sourceRowsRemoved(QModelIndex,int,int)));
439 connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
440 this, SLOT(_q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
441 connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
442 this, SLOT(_q_sourceColumnsInserted(QModelIndex,int,int)));
443 connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
444 this, SLOT(_q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
445 connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
446 this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int)));
447 connect(model, SIGNAL(modelReset()), this, SIGNAL(modelReset())); // signal to signal
448 connect(model, SIGNAL(layoutAboutToBeChanged()), this, SIGNAL(layoutAboutToBeChanged())); // signal to signal
449 connect(model, SIGNAL(layoutChanged()), this, SIGNAL(layoutChanged())); // signal to signal
450}
451
452/*!
453 \internal
454 Disconnect from all the signals emitted by the given \a model.
455 */
456void QProxyModel::disconnectFromModel(const QAbstractItemModel *model) const
457{
458 disconnect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
459 this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex)));
460 disconnect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
461 this, SIGNAL(headerDataChanged(Qt::Orientation,int,int))); // signal to signal
462 disconnect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
463 this, SLOT(_q_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
464 disconnect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
465 this, SLOT(rowsInserted(QModelIndex,int,int)));
466 disconnect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
467 this, SLOT(_q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
468 disconnect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
469 this, SLOT(_q_sourceRowsRemoved(QModelIndex,int,int)));
470 disconnect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
471 this, SLOT(_q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
472 disconnect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
473 this, SLOT(_q_sourceColumnsInserted(QModelIndex,int,int)));
474 disconnect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
475 this, SLOT(_q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
476 disconnect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
477 this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int)));
478 disconnect(model, SIGNAL(modelReset()), this, SIGNAL(modelReset())); // signal to signal
479 disconnect(model, SIGNAL(layoutAboutToBeChanged()), this, SIGNAL(layoutAboutToBeChanged())); // signal to signal
480 disconnect(model, SIGNAL(layoutChanged()), this, SIGNAL(layoutChanged())); // signal to signal
481}
482
483/*!
484 \fn QObject *QProxyModel::parent() const
485 \internal
486*/
487
488void QProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &tl,const QModelIndex &br)
489{
490 Q_Q(QProxyModel);
491 emit q->dataChanged(q->setProxyModel(tl), q->setProxyModel(br));
492}
493
494void QProxyModelPrivate::_q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int first ,int last)
495{
496 Q_Q(QProxyModel);
497 q->beginInsertRows(q->setProxyModel(parent), first, last);
498}
499
500void QProxyModelPrivate::_q_sourceRowsInserted(const QModelIndex &, int, int)
501{
502 Q_Q(QProxyModel);
503 q->endInsertRows();
504}
505
506void QProxyModelPrivate::_q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last)
507{
508 Q_Q(QProxyModel);
509 q->beginRemoveRows(q->setProxyModel(parent), first, last);
510}
511
512void QProxyModelPrivate::_q_sourceRowsRemoved(const QModelIndex &, int, int)
513{
514 Q_Q(QProxyModel);
515 q->endRemoveRows();
516}
517
518void QProxyModelPrivate::_q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last)
519{
520 Q_Q(QProxyModel);
521 q->beginInsertColumns(q->setProxyModel(parent), first, last);
522}
523
524void QProxyModelPrivate::_q_sourceColumnsInserted(const QModelIndex &, int, int)
525{
526 Q_Q(QProxyModel);
527 q->endInsertColumns();
528}
529
530void QProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int first, int last)
531{
532 Q_Q(QProxyModel);
533 q->beginRemoveColumns(q->setProxyModel(parent), first, last);
534}
535
536
537void QProxyModelPrivate::_q_sourceColumnsRemoved(const QModelIndex &, int, int)
538{
539 Q_Q(QProxyModel);
540 q->endRemoveColumns();
541}
542
543QT_END_NAMESPACE
544
545#include "moc_qproxymodel.cpp"
546
547#endif // QT_NO_PROXYMODEL
Note: See TracBrowser for help on using the repository browser.