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 
44 QT_BEGIN_NAMESPACE
45 
46 class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate
47 {
QIdentityProxyModelPrivate()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 QVector<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 */
QIdentityProxyModel(QObject * parent)109 QIdentityProxyModel::QIdentityProxyModel(QObject* parent)
110   : QAbstractProxyModel(*new QIdentityProxyModelPrivate, parent)
111 {
112 
113 }
114 
115 /*!
116     \internal
117  */
QIdentityProxyModel(QIdentityProxyModelPrivate & dd,QObject * parent)118 QIdentityProxyModel::QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent)
119   : QAbstractProxyModel(dd, parent)
120 {
121 
122 }
123 
124 /*!
125     Destroys this identity model.
126 */
~QIdentityProxyModel()127 QIdentityProxyModel::~QIdentityProxyModel()
128 {
129 }
130 
131 /*!
132     \reimp
133  */
columnCount(const QModelIndex & parent) const134 int 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  */
dropMimeData(const QMimeData * data,Qt::DropAction action,int row,int column,const QModelIndex & parent)144 bool 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  */
index(int row,int column,const QModelIndex & parent) const154 QModelIndex 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  */
sibling(int row,int column,const QModelIndex & idx) const166 QModelIndex 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  */
insertColumns(int column,int count,const QModelIndex & parent)175 bool 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  */
insertRows(int row,int count,const QModelIndex & parent)185 bool 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  */
mapFromSource(const QModelIndex & sourceIndex) const195 QModelIndex 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  */
mapSelectionFromSource(const QItemSelection & selection) const208 QItemSelection 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  */
mapSelectionToSource(const QItemSelection & selection) const231 QItemSelection 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  */
mapToSource(const QModelIndex & proxyIndex) const254 QModelIndex 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  */
match(const QModelIndex & start,int role,const QVariant & value,int hits,Qt::MatchFlags flags) const266 QModelIndexList 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  */
parent(const QModelIndex & child) const286 QModelIndex 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  */
removeColumns(int column,int count,const QModelIndex & parent)297 bool 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  */
removeRows(int row,int count,const QModelIndex & parent)307 bool 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  */
moveRows(const QModelIndex & sourceParent,int sourceRow,int count,const QModelIndex & destinationParent,int destinationChild)318 bool 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  */
moveColumns(const QModelIndex & sourceParent,int sourceColumn,int count,const QModelIndex & destinationParent,int destinationChild)330 bool 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  */
rowCount(const QModelIndex & parent) const341 int 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  */
headerData(int section,Qt::Orientation orientation,int role) const351 QVariant 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  */
setSourceModel(QAbstractItemModel * newSourceModel)360 void 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,QVector<int>)),
394                    this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex,QVector<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,QVector<int>)),
435                 SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex,QVector<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 
_q_sourceColumnsAboutToBeInserted(const QModelIndex & parent,int start,int end)447 void 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 
_q_sourceColumnsAboutToBeMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)454 void 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 
_q_sourceColumnsAboutToBeRemoved(const QModelIndex & parent,int start,int end)462 void 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 
_q_sourceColumnsInserted(const QModelIndex & parent,int start,int end)469 void 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 
_q_sourceColumnsMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)479 void 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 
_q_sourceColumnsRemoved(const QModelIndex & parent,int start,int end)492 void 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 
_q_sourceDataChanged(const QModelIndex & topLeft,const QModelIndex & bottomRight,const QVector<int> & roles)502 void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<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 
_q_sourceHeaderDataChanged(Qt::Orientation orientation,int first,int last)510 void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)
511 {
512     Q_Q(QIdentityProxyModel);
513     emit q->headerDataChanged(orientation, first, last);
514 }
515 
_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> & sourceParents,QAbstractItemModel::LayoutChangeHint hint)516 void 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 
_q_sourceLayoutChanged(const QList<QPersistentModelIndex> & sourceParents,QAbstractItemModel::LayoutChangeHint hint)544 void 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 
_q_sourceModelAboutToBeReset()570 void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset()
571 {
572     Q_Q(QIdentityProxyModel);
573     q->beginResetModel();
574 }
575 
_q_sourceModelReset()576 void QIdentityProxyModelPrivate::_q_sourceModelReset()
577 {
578     Q_Q(QIdentityProxyModel);
579     q->endResetModel();
580 }
581 
_q_sourceRowsAboutToBeInserted(const QModelIndex & parent,int start,int end)582 void 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 
_q_sourceRowsAboutToBeMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)589 void 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 
_q_sourceRowsAboutToBeRemoved(const QModelIndex & parent,int start,int end)597 void 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 
_q_sourceRowsInserted(const QModelIndex & parent,int start,int end)604 void 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 
_q_sourceRowsMoved(const QModelIndex & sourceParent,int sourceStart,int sourceEnd,const QModelIndex & destParent,int dest)614 void 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 
_q_sourceRowsRemoved(const QModelIndex & parent,int start,int end)627 void 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 
637 QT_END_NAMESPACE
638 
639 #include "moc_qidentityproxymodel.cpp"
640