1/****************************************************************************
2**
3** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qidentityproxymodel.h"
41#include "qitemselectionmodel.h"
42#include <private/qabstractproxymodel_p.h>
43
44QT_BEGIN_NAMESPACE
45
46class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate
47{
48 QIdentityProxyModelPrivate()
49 {
50
51 }
52
53 Q_DECLARE_PUBLIC(QIdentityProxyModel)
54
55 QList<QPersistentModelIndex> layoutChangePersistentIndexes;
56 QModelIndexList proxyIndexes;
57
58 void _q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
59 void _q_sourceRowsInserted(const QModelIndex &parent, int start, int end);
60 void _q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
61 void _q_sourceRowsRemoved(const QModelIndex &parent, int start, int end);
62 void _q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
63 void _q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
64
65 void _q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
66 void _q_sourceColumnsInserted(const QModelIndex &parent, int start, int end);
67 void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
68 void _q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end);
69 void _q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
70 void _q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
71
72 void _q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles);
73 void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last);
74
75 void _q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
76 void _q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint);
77 void _q_sourceModelAboutToBeReset();
78 void _q_sourceModelReset();
79
80};
81
82/*!
83 \since 4.8
84 \class QIdentityProxyModel
85 \inmodule QtCore
86 \brief The QIdentityProxyModel class proxies its source model unmodified.
87
88 \ingroup model-view
89
90 QIdentityProxyModel can be used to forward the structure of a source model exactly, with no sorting, filtering or other transformation.
91 This is similar in concept to an identity matrix where A.I = A.
92
93 Because it does no sorting or filtering, this class is most suitable to proxy models which transform the data() of the source model.
94 For example, a proxy model could be created to define the font used, or the background colour, or the tooltip etc. This removes the
95 need to implement all data handling in the same class that creates the structure of the model, and can also be used to create
96 re-usable components.
97
98 This also provides a way to change the data in the case where a source model is supplied by a third party which cannot be modified.
99
100 \snippet code/src_gui_itemviews_qidentityproxymodel.cpp 0
101
102 \sa QAbstractProxyModel, {Model/View Programming}, QAbstractItemModel
103
104*/
105
106/*!
107 Constructs an identity model with the given \a parent.
108*/
109QIdentityProxyModel::QIdentityProxyModel(QObject* parent)
110 : QAbstractProxyModel(*new QIdentityProxyModelPrivate, parent)
111{
112
113}
114
115/*!
116 \internal
117 */
118QIdentityProxyModel::QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent)
119 : QAbstractProxyModel(dd, parent)
120{
121
122}
123
124/*!
125 Destroys this identity model.
126*/
127QIdentityProxyModel::~QIdentityProxyModel()
128{
129}
130
131/*!
132 \reimp
133 */
134int QIdentityProxyModel::columnCount(const QModelIndex& parent) const
135{
136 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
137 Q_D(const QIdentityProxyModel);
138 return d->model->columnCount(mapToSource(parent));
139}
140
141/*!
142 \reimp
143 */
144bool QIdentityProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
145{
146 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
147 Q_D(QIdentityProxyModel);
148 return d->model->dropMimeData(data, action, row, column, mapToSource(parent));
149}
150
151/*!
152 \reimp
153 */
154QModelIndex QIdentityProxyModel::index(int row, int column, const QModelIndex& parent) const
155{
156 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
157 Q_D(const QIdentityProxyModel);
158 const QModelIndex sourceParent = mapToSource(parent);
159 const QModelIndex sourceIndex = d->model->index(row, column, sourceParent);
160 return mapFromSource(sourceIndex);
161}
162
163/*!
164 \reimp
165 */
166QModelIndex QIdentityProxyModel::sibling(int row, int column, const QModelIndex &idx) const
167{
168 Q_D(const QIdentityProxyModel);
169 return mapFromSource(d->model->sibling(row, column, mapToSource(idx)));
170}
171
172/*!
173 \reimp
174 */
175bool QIdentityProxyModel::insertColumns(int column, int count, const QModelIndex& parent)
176{
177 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
178 Q_D(QIdentityProxyModel);
179 return d->model->insertColumns(column, count, mapToSource(parent));
180}
181
182/*!
183 \reimp
184 */
185bool QIdentityProxyModel::insertRows(int row, int count, const QModelIndex& parent)
186{
187 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
188 Q_D(QIdentityProxyModel);
189 return d->model->insertRows(row, count, mapToSource(parent));
190}
191
192/*!
193 \reimp
194 */
195QModelIndex QIdentityProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
196{
197 Q_D(const QIdentityProxyModel);
198 if (!d->model || !sourceIndex.isValid())
199 return QModelIndex();
200
201 Q_ASSERT(sourceIndex.model() == d->model);
202 return createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer());
203}
204
205/*!
206 \reimp
207 */
208QItemSelection QIdentityProxyModel::mapSelectionFromSource(const QItemSelection& selection) const
209{
210 Q_D(const QIdentityProxyModel);
211 QItemSelection proxySelection;
212
213 if (!d->model)
214 return proxySelection;
215
216 QItemSelection::const_iterator it = selection.constBegin();
217 const QItemSelection::const_iterator end = selection.constEnd();
218 proxySelection.reserve(selection.count());
219 for ( ; it != end; ++it) {
220 Q_ASSERT(it->model() == d->model);
221 const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight()));
222 proxySelection.append(range);
223 }
224
225 return proxySelection;
226}
227
228/*!
229 \reimp
230 */
231QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& selection) const
232{
233 Q_D(const QIdentityProxyModel);
234 QItemSelection sourceSelection;
235
236 if (!d->model)
237 return sourceSelection;
238
239 QItemSelection::const_iterator it = selection.constBegin();
240 const QItemSelection::const_iterator end = selection.constEnd();
241 sourceSelection.reserve(selection.count());
242 for ( ; it != end; ++it) {
243 Q_ASSERT(it->model() == this);
244 const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight()));
245 sourceSelection.append(range);
246 }
247
248 return sourceSelection;
249}
250
251/*!
252 \reimp
253 */
254QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) const
255{
256 Q_D(const QIdentityProxyModel);
257 if (!d->model || !proxyIndex.isValid())
258 return QModelIndex();
259 Q_ASSERT(proxyIndex.model() == this);
260 return d->model->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer());
261}
262
263/*!
264 \reimp
265 */
266QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const
267{
268 Q_D(const QIdentityProxyModel);
269 Q_ASSERT(start.isValid() ? start.model() == this : true);
270 if (!d->model)
271 return QModelIndexList();
272
273 const QModelIndexList sourceList = d->model->match(mapToSource(start), role, value, hits, flags);
274 QModelIndexList::const_iterator it = sourceList.constBegin();
275 const QModelIndexList::const_iterator end = sourceList.constEnd();
276 QModelIndexList proxyList;
277 proxyList.reserve(sourceList.count());
278 for ( ; it != end; ++it)
279 proxyList.append(mapFromSource(*it));
280 return proxyList;
281}
282
283/*!
284 \reimp
285 */
286QModelIndex QIdentityProxyModel::parent(const QModelIndex& child) const
287{
288 Q_ASSERT(child.isValid() ? child.model() == this : true);
289 const QModelIndex sourceIndex = mapToSource(child);
290 const QModelIndex sourceParent = sourceIndex.parent();
291 return mapFromSource(sourceParent);
292}
293
294/*!
295 \reimp
296 */
297bool QIdentityProxyModel::removeColumns(int column, int count, const QModelIndex& parent)
298{
299 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
300 Q_D(QIdentityProxyModel);
301 return d->model->removeColumns(column, count, mapToSource(parent));
302}
303
304/*!
305 \reimp
306 */
307bool QIdentityProxyModel::removeRows(int row, int count, const QModelIndex& parent)
308{
309 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
310 Q_D(QIdentityProxyModel);
311 return d->model->removeRows(row, count, mapToSource(parent));
312}
313
314/*!
315 \reimp
316 \since 5.15
317 */
318bool QIdentityProxyModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
319{
320 Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == this : true);
321 Q_ASSERT(destinationParent.isValid() ? destinationParent.model() == this : true);
322 Q_D(QIdentityProxyModel);
323 return d->model->moveRows(mapToSource(sourceParent), sourceRow, count, mapToSource(destinationParent), destinationChild);
324}
325
326/*!
327 \reimp
328 \since 5.15
329 */
330bool QIdentityProxyModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild)
331{
332 Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == this : true);
333 Q_ASSERT(destinationParent.isValid() ? destinationParent.model() == this : true);
334 Q_D(QIdentityProxyModel);
335 return d->model->moveColumns(mapToSource(sourceParent), sourceColumn, count, mapToSource(destinationParent), destinationChild);
336}
337
338/*!
339 \reimp
340 */
341int QIdentityProxyModel::rowCount(const QModelIndex& parent) const
342{
343 Q_ASSERT(parent.isValid() ? parent.model() == this : true);
344 Q_D(const QIdentityProxyModel);
345 return d->model->rowCount(mapToSource(parent));
346}
347
348/*!
349 \reimp
350 */
351QVariant QIdentityProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
352{
353 Q_D(const QIdentityProxyModel);
354 return d->model->headerData(section, orientation, role);
355}
356
357/*!
358 \reimp
359 */
360void QIdentityProxyModel::setSourceModel(QAbstractItemModel* newSourceModel)
361{
362 beginResetModel();
363
364 if (sourceModel()) {
365 disconnect(sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
366 this, SLOT(_q_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
367 disconnect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
368 this, SLOT(_q_sourceRowsInserted(QModelIndex,int,int)));
369 disconnect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
370 this, SLOT(_q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
371 disconnect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
372 this, SLOT(_q_sourceRowsRemoved(QModelIndex,int,int)));
373 disconnect(sourceModel(), SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
374 this, SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
375 disconnect(sourceModel(), SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
376 this, SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)));
377 disconnect(sourceModel(), SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
378 this, SLOT(_q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
379 disconnect(sourceModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
380 this, SLOT(_q_sourceColumnsInserted(QModelIndex,int,int)));
381 disconnect(sourceModel(), SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
382 this, SLOT(_q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
383 disconnect(sourceModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
384 this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int)));
385 disconnect(sourceModel(), SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
386 this, SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
387 disconnect(sourceModel(), SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
388 this, SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)));
389 disconnect(sourceModel(), SIGNAL(modelAboutToBeReset()),
390 this, SLOT(_q_sourceModelAboutToBeReset()));
391 disconnect(sourceModel(), SIGNAL(modelReset()),
392 this, SLOT(_q_sourceModelReset()));
393 disconnect(sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex,QList<int>)),
394 this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex,QList<int>)));
395 disconnect(sourceModel(), SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
396 this, SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
397 disconnect(sourceModel(), SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
398 this, SLOT(_q_sourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
399 disconnect(sourceModel(), SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
400 this, SLOT(_q_sourceLayoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
401 }
402
403 QAbstractProxyModel::setSourceModel(newSourceModel);
404
405 if (sourceModel()) {
406 connect(sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
407 SLOT(_q_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
408 connect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
409 SLOT(_q_sourceRowsInserted(QModelIndex,int,int)));
410 connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
411 SLOT(_q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
412 connect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
413 SLOT(_q_sourceRowsRemoved(QModelIndex,int,int)));
414 connect(sourceModel(), SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
415 SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
416 connect(sourceModel(), SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
417 SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)));
418 connect(sourceModel(), SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
419 SLOT(_q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
420 connect(sourceModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
421 SLOT(_q_sourceColumnsInserted(QModelIndex,int,int)));
422 connect(sourceModel(), SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
423 SLOT(_q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
424 connect(sourceModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
425 SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int)));
426 connect(sourceModel(), SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
427 SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
428 connect(sourceModel(), SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
429 SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)));
430 connect(sourceModel(), SIGNAL(modelAboutToBeReset()),
431 SLOT(_q_sourceModelAboutToBeReset()));
432 connect(sourceModel(), SIGNAL(modelReset()),
433 SLOT(_q_sourceModelReset()));
434 connect(sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex,QList<int>)),
435 SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex,QList<int>)));
436 connect(sourceModel(), SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
437 SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
438 connect(sourceModel(), SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
439 SLOT(_q_sourceLayoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
440 connect(sourceModel(), SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
441 SLOT(_q_sourceLayoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
442 }
443
444 endResetModel();
445}
446
447void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
448{
449 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
450 Q_Q(QIdentityProxyModel);
451 q->beginInsertColumns(q->mapFromSource(parent), start, end);
452}
453
454void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
455{
456 Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
457 Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
458 Q_Q(QIdentityProxyModel);
459 q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
460}
461
462void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
463{
464 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
465 Q_Q(QIdentityProxyModel);
466 q->beginRemoveColumns(q->mapFromSource(parent), start, end);
467}
468
469void QIdentityProxyModelPrivate::_q_sourceColumnsInserted(const QModelIndex &parent, int start, int end)
470{
471 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
472 Q_Q(QIdentityProxyModel);
473 Q_UNUSED(parent);
474 Q_UNUSED(start);
475 Q_UNUSED(end);
476 q->endInsertColumns();
477}
478
479void QIdentityProxyModelPrivate::_q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
480{
481 Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
482 Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
483 Q_Q(QIdentityProxyModel);
484 Q_UNUSED(sourceParent);
485 Q_UNUSED(sourceStart);
486 Q_UNUSED(sourceEnd);
487 Q_UNUSED(destParent);
488 Q_UNUSED(dest);
489 q->endMoveColumns();
490}
491
492void QIdentityProxyModelPrivate::_q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end)
493{
494 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
495 Q_Q(QIdentityProxyModel);
496 Q_UNUSED(parent);
497 Q_UNUSED(start);
498 Q_UNUSED(end);
499 q->endRemoveColumns();
500}
501
502void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles)
503{
504 Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true);
505 Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true);
506 Q_Q(QIdentityProxyModel);
507 emit q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles);
508}
509
510void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)
511{
512 Q_Q(QIdentityProxyModel);
513 emit q->headerDataChanged(orientation, first, last);
514}
515
516void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
517{
518 Q_Q(QIdentityProxyModel);
519
520 QList<QPersistentModelIndex> parents;
521 parents.reserve(sourceParents.size());
522 for (const QPersistentModelIndex &parent : sourceParents) {
523 if (!parent.isValid()) {
524 parents << QPersistentModelIndex();
525 continue;
526 }
527 const QModelIndex mappedParent = q->mapFromSource(parent);
528 Q_ASSERT(mappedParent.isValid());
529 parents << mappedParent;
530 }
531
532 emit q->layoutAboutToBeChanged(parents, hint);
533
534 const auto proxyPersistentIndexes = q->persistentIndexList();
535 for (const QModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
536 proxyIndexes << proxyPersistentIndex;
537 Q_ASSERT(proxyPersistentIndex.isValid());
538 const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
539 Q_ASSERT(srcPersistentIndex.isValid());
540 layoutChangePersistentIndexes << srcPersistentIndex;
541 }
542}
543
544void QIdentityProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
545{
546 Q_Q(QIdentityProxyModel);
547
548 for (int i = 0; i < proxyIndexes.size(); ++i) {
549 q->changePersistentIndex(proxyIndexes.at(i), q->mapFromSource(layoutChangePersistentIndexes.at(i)));
550 }
551
552 layoutChangePersistentIndexes.clear();
553 proxyIndexes.clear();
554
555 QList<QPersistentModelIndex> parents;
556 parents.reserve(sourceParents.size());
557 for (const QPersistentModelIndex &parent : sourceParents) {
558 if (!parent.isValid()) {
559 parents << QPersistentModelIndex();
560 continue;
561 }
562 const QModelIndex mappedParent = q->mapFromSource(parent);
563 Q_ASSERT(mappedParent.isValid());
564 parents << mappedParent;
565 }
566
567 emit q->layoutChanged(parents, hint);
568}
569
570void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset()
571{
572 Q_Q(QIdentityProxyModel);
573 q->beginResetModel();
574}
575
576void QIdentityProxyModelPrivate::_q_sourceModelReset()
577{
578 Q_Q(QIdentityProxyModel);
579 q->endResetModel();
580}
581
582void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
583{
584 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
585 Q_Q(QIdentityProxyModel);
586 q->beginInsertRows(q->mapFromSource(parent), start, end);
587}
588
589void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
590{
591 Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
592 Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
593 Q_Q(QIdentityProxyModel);
594 q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
595}
596
597void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
598{
599 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
600 Q_Q(QIdentityProxyModel);
601 q->beginRemoveRows(q->mapFromSource(parent), start, end);
602}
603
604void QIdentityProxyModelPrivate::_q_sourceRowsInserted(const QModelIndex &parent, int start, int end)
605{
606 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
607 Q_Q(QIdentityProxyModel);
608 Q_UNUSED(parent);
609 Q_UNUSED(start);
610 Q_UNUSED(end);
611 q->endInsertRows();
612}
613
614void QIdentityProxyModelPrivate::_q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
615{
616 Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
617 Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
618 Q_Q(QIdentityProxyModel);
619 Q_UNUSED(sourceParent);
620 Q_UNUSED(sourceStart);
621 Q_UNUSED(sourceEnd);
622 Q_UNUSED(destParent);
623 Q_UNUSED(dest);
624 q->endMoveRows();
625}
626
627void QIdentityProxyModelPrivate::_q_sourceRowsRemoved(const QModelIndex &parent, int start, int end)
628{
629 Q_ASSERT(parent.isValid() ? parent.model() == model : true);
630 Q_Q(QIdentityProxyModel);
631 Q_UNUSED(parent);
632 Q_UNUSED(start);
633 Q_UNUSED(end);
634 q->endRemoveRows();
635}
636
637QT_END_NAMESPACE
638
639#include "moc_qidentityproxymodel.cpp"
640