1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qabstractitemmodel.h"
6#include <private/qabstractitemmodel_p.h>
7#include <qdatastream.h>
8#include <qstringlist.h>
9#include <qsize.h>
10#include <qmimedata.h>
11#include <qdebug.h>
12#include <qlist.h>
13#if QT_CONFIG(regularexpression)
14# include <qregularexpression.h>
15#endif
16#include <qstack.h>
17#include <qmap.h>
18#include <qbitarray.h>
19#include <qdatetime.h>
20#include <qloggingcategory.h>
21
22#include <limits.h>
23
24QT_BEGIN_NAMESPACE
25
26Q_LOGGING_CATEGORY(lcCheckIndex, "qt.core.qabstractitemmodel.checkindex")
27
28QT_IMPL_METATYPE_EXTERN(QModelIndexList)
29
30QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &index)
31{
32 Q_ASSERT(index.isValid()); // we will _never_ insert an invalid index in the list
33 QPersistentModelIndexData *d = nullptr;
34 QAbstractItemModel *model = const_cast<QAbstractItemModel *>(index.model());
35 QMultiHash<QModelIndex, QPersistentModelIndexData *> &indexes = model->d_func()->persistent.indexes;
36 const auto it = indexes.constFind(key: index);
37 if (it != indexes.cend()) {
38 d = (*it);
39 } else {
40 d = new QPersistentModelIndexData(index);
41 indexes.insert(key: index, value: d);
42 }
43 Q_ASSERT(d);
44 return d;
45}
46
47void QPersistentModelIndexData::destroy(QPersistentModelIndexData *data)
48{
49 Q_ASSERT(data);
50 Q_ASSERT(data->ref.loadRelaxed() == 0);
51 QAbstractItemModel *model = const_cast<QAbstractItemModel *>(data->index.model());
52 // a valid persistent model index with a null model pointer can only happen if the model was destroyed
53 if (model) {
54 QAbstractItemModelPrivate *p = model->d_func();
55 Q_ASSERT(p);
56 p->removePersistentIndexData(data);
57 }
58 delete data;
59}
60
61/*!
62 \class QModelRoleData
63 \inmodule QtCore
64 \since 6.0
65 \ingroup model-view
66 \brief The QModelRoleData class holds a role and the data associated to that role.
67
68 QModelRoleData objects store an item role (which is a value from the
69 Qt::ItemDataRole enumeration, or an arbitrary integer for a custom role)
70 as well as the data associated with that role.
71
72 A QModelRoleData object is typically created by views or delegates,
73 setting which role they want to fetch the data for. The object
74 is then passed to models (see QAbstractItemModel::multiData()),
75 which populate the data corresponding to the role stored. Finally,
76 the view visualizes the data retrieved from the model.
77
78 \sa {Model/View Programming}, QModelRoleDataSpan
79*/
80
81/*!
82 \fn QModelRoleData::QModelRoleData(int role) noexcept
83
84 Constructs a QModelRoleData object for the given \a role.
85
86 \sa Qt::ItemDataRole
87*/
88
89/*!
90 \fn int QModelRoleData::role() const noexcept
91
92 Returns the role held by this object.
93
94 \sa Qt::ItemDataRole
95*/
96
97/*!
98 \fn const QVariant &QModelRoleData::data() const noexcept
99
100 Returns the data held by this object.
101
102 \sa setData()
103*/
104
105/*!
106 \fn QVariant &QModelRoleData::data() noexcept
107
108 Returns the data held by this object as a modifiable reference.
109
110 \sa setData()
111*/
112
113/*!
114 \fn template <typename T> void QModelRoleData::setData(T &&value)
115
116 Sets the data held by this object to \a value.
117 \a value must be of a datatype which can be stored in a QVariant.
118
119 \sa data(), clearData(), Q_DECLARE_METATYPE
120*/
121
122/*!
123 \fn void QModelRoleData::clearData() noexcept
124
125 Clears the data held by this object. Note that the role is
126 unchanged; only the data is cleared.
127
128 \sa data()
129*/
130
131/*!
132 \class QModelRoleDataSpan
133 \inmodule QtCore
134 \since 6.0
135 \ingroup model-view
136 \brief The QModelRoleDataSpan class provides a span over QModelRoleData objects.
137
138 A QModelRoleDataSpan is used as an abstraction over an array of
139 QModelRoleData objects.
140
141 Like a view, QModelRoleDataSpan provides a small object (pointer
142 and size) that can be passed to functions that need to examine the
143 contents of the array. A QModelRoleDataSpan can be constructed from
144 any array-like sequence (plain arrays, QVector, std::vector,
145 QVarLengthArray, and so on). Moreover, it does not own the
146 sequence, which must therefore be kept alive longer than any
147 QModelRoleDataSpan objects referencing it.
148
149 Unlike a view, QModelRoleDataSpan is a span, so it allows for
150 modifications to the underlying elements.
151
152 QModelRoleDataSpan's main use case is making it possible
153 for a model to return the data corresponding to different roles
154 in one call.
155
156 In order to draw one element from a model, a view (through its
157 delegates) will generally request multiple roles for the same index
158 by calling \c{data()} as many times as needed:
159
160 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 13
161
162 QModelRoleDataSpan allows a view to request the same data
163 using just one function call.
164
165 This is achieved by having the view prepare a suitable array of
166 QModelRoleData objects, each initialized with the role that should
167 be fetched. The array is then wrapped in a QModelRoleDataSpan
168 object, which is then passed to a model's \c{multiData()} function.
169
170 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 14
171
172 Views are encouraged to store the array of QModelRoleData objects
173 (and, possibly, the corresponding span) and re-use it in subsequent
174 calls to the model. This allows to reduce the memory allocations
175 related with creating and returning QVariant objects.
176
177 Finally, given a QModelRoleDataSpan object, the model's
178 responsibility is to fill in the data corresponding to each role in
179 the span. How this is done depends on the concrete model class.
180 Here's a sketch of a possible implementation that iterates over the
181 span and uses \c{setData()} on each element:
182
183 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 15
184
185 \sa {Model/View Programming}, QAbstractItemModel::multiData()
186*/
187
188/*!
189 \fn QModelRoleDataSpan::QModelRoleDataSpan() noexcept
190
191 Constructs an empty QModelRoleDataSpan. Its data() will be set to
192 \nullptr, and its length to zero.
193*/
194
195/*!
196 \fn QModelRoleDataSpan::QModelRoleDataSpan(QModelRoleData &modelRoleData) noexcept
197
198 Constructs an QModelRoleDataSpan spanning over \a modelRoleData,
199 seen as a 1-element array.
200*/
201
202/*!
203 \fn QModelRoleDataSpan::QModelRoleDataSpan(QModelRoleData *modelRoleData, qsizetype len)
204
205 Constructs an QModelRoleDataSpan spanning over the array beginning
206 at \a modelRoleData and with length \a len.
207
208 \note The array must be kept alive as long as this object has not
209 been destructed.
210*/
211
212/*!
213 \fn template <typename Container> QModelRoleDataSpan::QModelRoleDataSpan(Container &c) noexcept
214
215 Constructs an QModelRoleDataSpan spanning over the container \a c,
216 which can be any contiguous container of QModelRoleData objects.
217 For instance, it can be a \c{QVector<QModelRoleData>},
218 a \c{std::array<QModelRoleData, 10>} and so on.
219
220 \note The container must be kept alive as long as this object has not
221 been destructed.
222*/
223
224/*!
225 \fn qsizetype QModelRoleDataSpan::size() const noexcept
226
227 Returns the length of the span represented by this object.
228*/
229
230/*!
231 \fn qsizetype QModelRoleDataSpan::length() const noexcept
232
233 Returns the length of the span represented by this object.
234*/
235
236/*!
237 \fn QModelRoleData *QModelRoleDataSpan::data() const noexcept
238
239 Returns a pointer to the beginning of the span represented by this
240 object.
241*/
242
243/*!
244 \fn QModelRoleData *QModelRoleDataSpan::begin() const noexcept
245
246 Returns a pointer to the beginning of the span represented by this
247 object.
248*/
249
250/*!
251 \fn QModelRoleData *QModelRoleDataSpan::end() const noexcept
252
253 Returns a pointer to the imaginary element one past the end of the
254 span represented by this object.
255*/
256
257/*!
258 \fn QModelRoleData &QModelRoleDataSpan::operator[](qsizetype index) const
259
260 Returns a modifiable reference to the QModelRoleData at position
261 \a index in the span.
262
263 \note \a index must be a valid index for this span (0 <= \a index < size()).
264*/
265
266/*!
267 \fn const QVariant *QModelRoleDataSpan::dataForRole(int role) const
268
269 Returns the data associated with the first QModelRoleData in the
270 span that has its role equal to \a role. If such a QModelRoleData
271 object does not exist, the behavior is undefined.
272
273 \note Avoid calling this function from the model's side, as a
274 model cannot possibly know in advance which roles are in a given
275 QModelRoleDataSpan. This function is instead suitable for views and
276 delegates, which have control over the roles in the span.
277
278 \sa QModelRoleData::data()
279*/
280
281/*!
282 \class QPersistentModelIndex
283 \inmodule QtCore
284 \ingroup shared
285
286 \brief The QPersistentModelIndex class is used to locate data in a data model.
287
288 \ingroup model-view
289
290 A QPersistentModelIndex is a model index that can be stored by an
291 application, and later used to access information in a model.
292 Unlike the QModelIndex class, it is safe to store a
293 QPersistentModelIndex since the model will ensure that references
294 to items will continue to be valid as long as they can be accessed
295 by the model.
296
297 It is good practice to check that persistent model indexes are valid
298 before using them.
299
300 \note You cannot store a QStandardItemModel's QPersistentModelIndex
301 in one of the model's items.
302
303 \sa {Model/View Programming}, QModelIndex, QAbstractItemModel
304*/
305
306/*!
307 \fn QPersistentModelIndex::QPersistentModelIndex(QPersistentModelIndex &&other)
308
309 Move-constructs a QPersistentModelIndex instance, making it point at the same
310 object that \a other was pointing to.
311
312 \since 5.2
313*/
314
315/*!
316 \fn QPersistentModelIndex &QPersistentModelIndex::operator=(QPersistentModelIndex &&other)
317
318 Move-assigns \a other to this QPersistentModelIndex instance.
319
320 \since 5.2
321*/
322
323
324/*!
325 \fn QPersistentModelIndex::QPersistentModelIndex()
326
327 \internal
328*/
329
330QPersistentModelIndex::QPersistentModelIndex()
331 : d(nullptr)
332{
333}
334
335/*!
336 \fn QPersistentModelIndex::QPersistentModelIndex(const QPersistentModelIndex &other)
337
338 Creates a new QPersistentModelIndex that is a copy of the \a other persistent
339 model index.
340*/
341
342QPersistentModelIndex::QPersistentModelIndex(const QPersistentModelIndex &other)
343 : d(other.d)
344{
345 if (d) d->ref.ref();
346}
347
348/*!
349 Creates a new QPersistentModelIndex that is a copy of the model \a index.
350*/
351
352QPersistentModelIndex::QPersistentModelIndex(const QModelIndex &index)
353 : d(nullptr)
354{
355 if (index.isValid()) {
356 d = QPersistentModelIndexData::create(index);
357 d->ref.ref();
358 }
359}
360
361/*!
362 \fn QPersistentModelIndex::~QPersistentModelIndex()
363
364 \internal
365*/
366
367QPersistentModelIndex::~QPersistentModelIndex()
368{
369 if (d && !d->ref.deref()) {
370 QPersistentModelIndexData::destroy(data: d);
371 d = nullptr;
372 }
373}
374
375/*!
376 Returns \c{true} if this persistent model index is equal to the \a other
377 persistent model index; otherwise returns \c{false}.
378
379 The internal data pointer, row, column, and model values in the persistent
380 model index are used when comparing with another persistent model index.
381*/
382
383bool QPersistentModelIndex::operator==(const QPersistentModelIndex &other) const
384{
385 if (d && other.d)
386 return d->index == other.d->index;
387 return d == other.d;
388}
389
390/*!
391 \since 4.1
392
393 Returns \c{true} if this persistent model index is smaller than the \a other
394 persistent model index; otherwise returns \c{false}.
395
396 The internal data pointer, row, column, and model values in the persistent
397 model index are used when comparing with another persistent model index.
398*/
399
400bool QPersistentModelIndex::operator<(const QPersistentModelIndex &other) const
401{
402 if (d && other.d)
403 return d->index < other.d->index;
404
405 return d < other.d;
406}
407
408/*!
409 \fn bool QPersistentModelIndex::operator!=(const QPersistentModelIndex &other) const
410 \since 4.2
411
412 Returns \c{true} if this persistent model index is not equal to the \a
413 other persistent model index; otherwise returns \c{false}.
414*/
415
416/*!
417 Sets the persistent model index to refer to the same item in a model
418 as the \a other persistent model index.
419*/
420
421QPersistentModelIndex &QPersistentModelIndex::operator=(const QPersistentModelIndex &other)
422{
423 if (d == other.d)
424 return *this;
425 if (d && !d->ref.deref())
426 QPersistentModelIndexData::destroy(data: d);
427 d = other.d;
428 if (d) d->ref.ref();
429 return *this;
430}
431/*!
432 \fn void QPersistentModelIndex::swap(QPersistentModelIndex &other)
433 \since 5.0
434
435 Swaps this persistent modelindex with \a other. This function is
436 very fast and never fails.
437*/
438
439/*!
440 Sets the persistent model index to refer to the same item in a model
441 as the \a other model index.
442*/
443
444QPersistentModelIndex &QPersistentModelIndex::operator=(const QModelIndex &other)
445{
446 if (d && !d->ref.deref())
447 QPersistentModelIndexData::destroy(data: d);
448 if (other.isValid()) {
449 d = QPersistentModelIndexData::create(index: other);
450 if (d) d->ref.ref();
451 } else {
452 d = nullptr;
453 }
454 return *this;
455}
456
457/*!
458 \fn QPersistentModelIndex::operator QModelIndex() const
459
460 Cast operator that returns a QModelIndex.
461*/
462
463QPersistentModelIndex::operator QModelIndex() const
464{
465 if (d)
466 return d->index;
467 return QModelIndex();
468}
469
470/*!
471 Returns \c{true} if this persistent model index refers to the same location as
472 the \a other model index; otherwise returns \c{false}.
473
474 The internal data pointer, row, column, and model values in the persistent
475 model index are used when comparing with another model index.
476*/
477
478bool QPersistentModelIndex::operator==(const QModelIndex &other) const
479{
480 if (d)
481 return d->index == other;
482 return !other.isValid();
483}
484
485/*!
486 \fn bool QPersistentModelIndex::operator!=(const QModelIndex &other) const
487
488 Returns \c{true} if this persistent model index does not refer to the same
489 location as the \a other model index; otherwise returns \c{false}.
490*/
491
492bool QPersistentModelIndex::operator!=(const QModelIndex &other) const
493{
494 if (d)
495 return d->index != other;
496 return other.isValid();
497}
498
499/*!
500 \fn int QPersistentModelIndex::row() const
501
502 Returns the row this persistent model index refers to.
503*/
504
505int QPersistentModelIndex::row() const
506{
507 if (d)
508 return d->index.row();
509 return -1;
510}
511
512/*!
513 \fn int QPersistentModelIndex::column() const
514
515 Returns the column this persistent model index refers to.
516*/
517
518int QPersistentModelIndex::column() const
519{
520 if (d)
521 return d->index.column();
522 return -1;
523}
524
525/*!
526 \fn void *QPersistentModelIndex::internalPointer() const
527
528 \internal
529
530 Returns a \c{void} \c{*} pointer used by the model to associate the index with
531 the internal data structure.
532*/
533
534void *QPersistentModelIndex::internalPointer() const
535{
536 if (d)
537 return d->index.internalPointer();
538 return nullptr;
539}
540
541/*!
542 \fn const void *QPersistentModelIndex::constInternalPointer() const
543 \since 6.0
544 \internal
545
546 Returns a \c{const void} \c{*} pointer used by the model to
547 associate the index with the internal data structure.
548*/
549
550const void *QPersistentModelIndex::constInternalPointer() const
551{
552 if (d)
553 return d->index.constInternalPointer();
554 return nullptr;
555}
556
557/*!
558 \fn quintptr QPersistentModelIndex::internalId() const
559
560 \internal
561
562 Returns a \c{quintptr} used by the model to associate the index with
563 the internal data structure.
564*/
565
566quintptr QPersistentModelIndex::internalId() const
567{
568 if (d)
569 return d->index.internalId();
570 return 0;
571}
572
573/*!
574 Returns the parent QModelIndex for this persistent index, or an invalid
575 QModelIndex if it has no parent.
576
577 \sa sibling(), model()
578*/
579QModelIndex QPersistentModelIndex::parent() const
580{
581 if (d)
582 return d->index.parent();
583 return QModelIndex();
584}
585
586/*!
587 Returns the sibling at \a row and \a column or an invalid QModelIndex if
588 there is no sibling at this position.
589
590 \sa parent()
591*/
592
593QModelIndex QPersistentModelIndex::sibling(int row, int column) const
594{
595 if (d)
596 return d->index.sibling(arow: row, acolumn: column);
597 return QModelIndex();
598}
599
600/*!
601 Returns the data for the given \a role for the item referred to by the
602 index.
603
604 \sa Qt::ItemDataRole, QAbstractItemModel::setData()
605*/
606QVariant QPersistentModelIndex::data(int role) const
607{
608 if (d)
609 return d->index.data(arole: role);
610 return QVariant();
611}
612
613
614/*!
615 Populates the given \a roleDataSpan for the item referred to by the
616 index.
617
618 \since 6.0
619 \sa Qt::ItemDataRole, QAbstractItemModel::setData()
620*/
621void QPersistentModelIndex::multiData(QModelRoleDataSpan roleDataSpan) const
622{
623 if (d)
624 d->index.multiData(roleDataSpan);
625}
626
627/*!
628 \since 4.2
629
630 Returns the flags for the item referred to by the index.
631*/
632Qt::ItemFlags QPersistentModelIndex::flags() const
633{
634 if (d)
635 return d->index.flags();
636 return { };
637}
638
639/*!
640 Returns the model that the index belongs to.
641*/
642const QAbstractItemModel *QPersistentModelIndex::model() const
643{
644 if (d)
645 return d->index.model();
646 return nullptr;
647}
648
649/*!
650 \fn bool QPersistentModelIndex::isValid() const
651
652 Returns \c{true} if this persistent model index is valid; otherwise returns
653 \c{false}.
654
655 A valid index belongs to a model, and has non-negative row and column
656 numbers.
657
658 \sa model(), row(), column()
659*/
660
661bool QPersistentModelIndex::isValid() const
662{
663 return d && d->index.isValid();
664}
665
666#ifndef QT_NO_DEBUG_STREAM
667QDebug operator<<(QDebug dbg, const QModelIndex &idx)
668{
669 QDebugStateSaver saver(dbg);
670 dbg.nospace() << "QModelIndex(" << idx.row() << ',' << idx.column()
671 << ',' << idx.internalPointer() << ',' << idx.model() << ')';
672 return dbg;
673}
674
675QDebug operator<<(QDebug dbg, const QPersistentModelIndex &idx)
676{
677 if (idx.d)
678 dbg << idx.d->index;
679 else
680 dbg << QModelIndex();
681 return dbg;
682}
683#endif
684
685class QEmptyItemModel : public QAbstractItemModel
686{
687public:
688 explicit QEmptyItemModel(QObject *parent = nullptr) : QAbstractItemModel(parent) {}
689 QModelIndex index(int, int, const QModelIndex &) const override { return QModelIndex(); }
690 QModelIndex parent(const QModelIndex &) const override { return QModelIndex(); }
691 int rowCount(const QModelIndex &) const override { return 0; }
692 int columnCount(const QModelIndex &) const override { return 0; }
693 bool hasChildren(const QModelIndex &) const override { return false; }
694 QVariant data(const QModelIndex &, int) const override { return QVariant(); }
695};
696
697Q_GLOBAL_STATIC(QEmptyItemModel, qEmptyModel)
698
699
700QAbstractItemModelPrivate::QAbstractItemModelPrivate()
701 : QObjectPrivate()
702{
703}
704
705QAbstractItemModelPrivate::~QAbstractItemModelPrivate()
706{
707}
708
709QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
710{
711 return qEmptyModel();
712}
713
714void QAbstractItemModelPrivate::invalidatePersistentIndexes()
715{
716 for (QPersistentModelIndexData *data : std::as_const(t&: persistent.indexes))
717 data->index = QModelIndex();
718 persistent.indexes.clear();
719}
720
721/*!
722 \internal
723 Clean the QPersistentModelIndex relative to the index if there is one.
724 To be used before an index is invalided
725*/
726void QAbstractItemModelPrivate::invalidatePersistentIndex(const QModelIndex &index) {
727 const auto it = persistent.indexes.constFind(key: index);
728 if (it != persistent.indexes.cend()) {
729 QPersistentModelIndexData *data = *it;
730 persistent.indexes.erase(it);
731 data->index = QModelIndex();
732 }
733}
734
735using DefaultRoleNames = QHash<int, QByteArray>;
736Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames,
737 {
738 { Qt::DisplayRole, "display" },
739 { Qt::DecorationRole, "decoration" },
740 { Qt::EditRole, "edit" },
741 { Qt::ToolTipRole, "toolTip" },
742 { Qt::StatusTipRole, "statusTip" },
743 { Qt::WhatsThisRole, "whatsThis" },
744 })
745
746const QHash<int,QByteArray> &QAbstractItemModelPrivate::defaultRoleNames()
747{
748 return *qDefaultRoleNames();
749}
750
751bool QAbstractItemModelPrivate::isVariantLessThan(const QVariant &left, const QVariant &right,
752 Qt::CaseSensitivity cs, bool isLocaleAware)
753{
754 if (left.userType() == QMetaType::UnknownType)
755 return false;
756 if (right.userType() == QMetaType::UnknownType)
757 return true;
758 switch (left.userType()) {
759 case QMetaType::Int:
760 return left.toInt() < right.toInt();
761 case QMetaType::UInt:
762 return left.toUInt() < right.toUInt();
763 case QMetaType::LongLong:
764 return left.toLongLong() < right.toLongLong();
765 case QMetaType::ULongLong:
766 return left.toULongLong() < right.toULongLong();
767 case QMetaType::Float:
768 return left.toFloat() < right.toFloat();
769 case QMetaType::Double:
770 return left.toDouble() < right.toDouble();
771 case QMetaType::QChar:
772 return left.toChar() < right.toChar();
773 case QMetaType::QDate:
774 return left.toDate() < right.toDate();
775 case QMetaType::QTime:
776 return left.toTime() < right.toTime();
777 case QMetaType::QDateTime:
778 return left.toDateTime() < right.toDateTime();
779 case QMetaType::QString:
780 default:
781 if (isLocaleAware)
782 return left.toString().localeAwareCompare(s: right.toString()) < 0;
783 else
784 return left.toString().compare(s: right.toString(), cs) < 0;
785 }
786}
787
788
789static uint typeOfVariant(const QVariant &value)
790{
791 //return 0 for integer, 1 for floating point and 2 for other
792 switch (value.userType()) {
793 case QMetaType::Bool:
794 case QMetaType::Int:
795 case QMetaType::UInt:
796 case QMetaType::LongLong:
797 case QMetaType::ULongLong:
798 case QMetaType::QChar:
799 case QMetaType::Short:
800 case QMetaType::UShort:
801 case QMetaType::UChar:
802 case QMetaType::ULong:
803 case QMetaType::Long:
804 return 0;
805 case QMetaType::Double:
806 case QMetaType::Float:
807 return 1;
808 default:
809 return 2;
810 }
811}
812
813/*!
814 \internal
815 Return \c{true} if \a value contains a numerical type.
816
817 This function is used by our Q{Tree,Widget,Table}WidgetModel classes to sort.
818*/
819bool QAbstractItemModelPrivate::variantLessThan(const QVariant &v1, const QVariant &v2)
820{
821 switch(qMax(a: typeOfVariant(value: v1), b: typeOfVariant(value: v2)))
822 {
823 case 0: //integer type
824 return v1.toLongLong() < v2.toLongLong();
825 case 1: //floating point
826 return v1.toReal() < v2.toReal();
827 default:
828 return v1.toString().localeAwareCompare(s: v2.toString()) < 0;
829 }
830}
831
832void QAbstractItemModelPrivate::removePersistentIndexData(QPersistentModelIndexData *data)
833{
834 if (data->index.isValid()) {
835 int removed = persistent.indexes.remove(key: data->index);
836 Q_ASSERT_X(removed == 1, "QPersistentModelIndex::~QPersistentModelIndex",
837 "persistent model indexes corrupted"); //maybe the index was somewhat invalid?
838 // This assert may happen if the model use changePersistentIndex in a way that could result on two
839 // QPersistentModelIndex pointing to the same index.
840 Q_UNUSED(removed);
841 }
842 // make sure our optimization still works
843 for (int i = persistent.moved.size() - 1; i >= 0; --i) {
844 int idx = persistent.moved.at(i).indexOf(t: data);
845 if (idx >= 0)
846 persistent.moved[i].remove(i: idx);
847 }
848 // update the references to invalidated persistent indexes
849 for (int i = persistent.invalidated.size() - 1; i >= 0; --i) {
850 int idx = persistent.invalidated.at(i).indexOf(t: data);
851 if (idx >= 0)
852 persistent.invalidated[i].remove(i: idx);
853 }
854
855}
856
857void QAbstractItemModelPrivate::rowsAboutToBeInserted(const QModelIndex &parent,
858 int first, int last)
859{
860 Q_Q(QAbstractItemModel);
861 Q_UNUSED(last);
862 QList<QPersistentModelIndexData *> persistent_moved;
863 if (first < q->rowCount(parent)) {
864 for (auto *data : std::as_const(t&: persistent.indexes)) {
865 const QModelIndex &index = data->index;
866 if (index.row() >= first && index.isValid() && index.parent() == parent) {
867 persistent_moved.append(t: data);
868 }
869 }
870 }
871 persistent.moved.push(t: persistent_moved);
872}
873
874void QAbstractItemModelPrivate::rowsInserted(const QModelIndex &parent,
875 int first, int last)
876{
877 const QList<QPersistentModelIndexData *> persistent_moved = persistent.moved.pop();
878 const int count = (last - first) + 1; // it is important to only use the delta, because the change could be nested
879 for (auto *data : persistent_moved) {
880 QModelIndex old = data->index;
881 persistent.indexes.erase(it: persistent.indexes.constFind(key: old));
882 data->index = q_func()->index(row: old.row() + count, column: old.column(), parent);
883 if (data->index.isValid()) {
884 persistent.insertMultiAtEnd(key: data->index, data);
885 } else {
886 qWarning() << "QAbstractItemModel::endInsertRows: Invalid index (" << old.row() + count << ',' << old.column() << ") in model" << q_func();
887 }
888 }
889}
890
891void QAbstractItemModelPrivate::itemsAboutToBeMoved(const QModelIndex &srcParent, int srcFirst, int srcLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation)
892{
893 QList<QPersistentModelIndexData *> persistent_moved_explicitly;
894 QList<QPersistentModelIndexData *> persistent_moved_in_source;
895 QList<QPersistentModelIndexData *> persistent_moved_in_destination;
896
897 const bool sameParent = (srcParent == destinationParent);
898 const bool movingUp = (srcFirst > destinationChild);
899
900 for (auto *data : std::as_const(t&: persistent.indexes)) {
901 const QModelIndex &index = data->index;
902 const QModelIndex &parent = index.parent();
903 const bool isSourceIndex = (parent == srcParent);
904 const bool isDestinationIndex = (parent == destinationParent);
905
906 int childPosition;
907 if (orientation == Qt::Vertical)
908 childPosition = index.row();
909 else
910 childPosition = index.column();
911
912 if (!index.isValid() || !(isSourceIndex || isDestinationIndex ) )
913 continue;
914
915 if (!sameParent && isDestinationIndex) {
916 if (childPosition >= destinationChild)
917 persistent_moved_in_destination.append(t: data);
918 continue;
919 }
920
921 if (sameParent && movingUp && childPosition < destinationChild)
922 continue;
923
924 if (sameParent && !movingUp && childPosition < srcFirst )
925 continue;
926
927 if (!sameParent && childPosition < srcFirst)
928 continue;
929
930 if (sameParent && (childPosition > srcLast) && (childPosition >= destinationChild ))
931 continue;
932
933 if ((childPosition <= srcLast) && (childPosition >= srcFirst)) {
934 persistent_moved_explicitly.append(t: data);
935 } else {
936 persistent_moved_in_source.append(t: data);
937 }
938 }
939 persistent.moved.push(t: persistent_moved_explicitly);
940 persistent.moved.push(t: persistent_moved_in_source);
941 persistent.moved.push(t: persistent_moved_in_destination);
942}
943
944/*!
945 \internal
946
947 Moves persistent indexes \a indexes by amount \a change. The change will be either a change in row value or a change in
948 column value depending on the value of \a orientation. The indexes may also be moved to a different parent if \a parent
949 differs from the existing parent for the index.
950*/
951void QAbstractItemModelPrivate::movePersistentIndexes(const QList<QPersistentModelIndexData *> &indexes, int change,
952 const QModelIndex &parent, Qt::Orientation orientation)
953{
954 for (auto *data : indexes) {
955 int row = data->index.row();
956 int column = data->index.column();
957
958 if (Qt::Vertical == orientation)
959 row += change;
960 else
961 column += change;
962
963 persistent.indexes.erase(it: persistent.indexes.constFind(key: data->index));
964 data->index = q_func()->index(row, column, parent);
965 if (data->index.isValid()) {
966 persistent.insertMultiAtEnd(key: data->index, data);
967 } else {
968 qWarning() << "QAbstractItemModel::endMoveRows: Invalid index (" << row << "," << column << ") in model" << q_func();
969 }
970 }
971}
972
973void QAbstractItemModelPrivate::itemsMoved(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild, Qt::Orientation orientation)
974{
975 const QList<QPersistentModelIndexData *> moved_in_destination = persistent.moved.pop();
976 const QList<QPersistentModelIndexData *> moved_in_source = persistent.moved.pop();
977 const QList<QPersistentModelIndexData *> moved_explicitly = persistent.moved.pop();
978
979 const bool sameParent = (sourceParent == destinationParent);
980 const bool movingUp = (sourceFirst > destinationChild);
981
982 const int explicit_change = (!sameParent || movingUp) ? destinationChild - sourceFirst : destinationChild - sourceLast - 1 ;
983 const int source_change = (!sameParent || !movingUp) ? -1*(sourceLast - sourceFirst + 1) : sourceLast - sourceFirst + 1 ;
984 const int destination_change = sourceLast - sourceFirst + 1;
985
986 movePersistentIndexes(indexes: moved_explicitly, change: explicit_change, parent: destinationParent, orientation);
987 movePersistentIndexes(indexes: moved_in_source, change: source_change, parent: sourceParent, orientation);
988 movePersistentIndexes(indexes: moved_in_destination, change: destination_change, parent: destinationParent, orientation);
989}
990
991void QAbstractItemModelPrivate::rowsAboutToBeRemoved(const QModelIndex &parent,
992 int first, int last)
993{
994 QList<QPersistentModelIndexData *> persistent_moved;
995 QList<QPersistentModelIndexData *> persistent_invalidated;
996 // find the persistent indexes that are affected by the change, either by being in the removed subtree
997 // or by being on the same level and below the removed rows
998 for (auto *data : std::as_const(t&: persistent.indexes)) {
999 bool level_changed = false;
1000 QModelIndex current = data->index;
1001 while (current.isValid()) {
1002 QModelIndex current_parent = current.parent();
1003 if (current_parent == parent) { // on the same level as the change
1004 if (!level_changed && current.row() > last) // below the removed rows
1005 persistent_moved.append(t: data);
1006 else if (current.row() <= last && current.row() >= first) // in the removed subtree
1007 persistent_invalidated.append(t: data);
1008 break;
1009 }
1010 current = current_parent;
1011 level_changed = true;
1012 }
1013 }
1014
1015 persistent.moved.push(t: persistent_moved);
1016 persistent.invalidated.push(t: persistent_invalidated);
1017}
1018
1019void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent,
1020 int first, int last)
1021{
1022 const QList<QPersistentModelIndexData *> persistent_moved = persistent.moved.pop();
1023 const int count = (last - first) + 1; // it is important to only use the delta, because the change could be nested
1024 for (auto *data : persistent_moved) {
1025 QModelIndex old = data->index;
1026 persistent.indexes.erase(it: persistent.indexes.constFind(key: old));
1027 data->index = q_func()->index(row: old.row() - count, column: old.column(), parent);
1028 if (data->index.isValid()) {
1029 persistent.insertMultiAtEnd(key: data->index, data);
1030 } else {
1031 qWarning() << "QAbstractItemModel::endRemoveRows: Invalid index (" << old.row() - count << ',' << old.column() << ") in model" << q_func();
1032 }
1033 }
1034 const QList<QPersistentModelIndexData *> persistent_invalidated = persistent.invalidated.pop();
1035 for (auto *data : persistent_invalidated) {
1036 auto pit = persistent.indexes.constFind(key: data->index);
1037 if (pit != persistent.indexes.cend())
1038 persistent.indexes.erase(it: pit);
1039 data->index = QModelIndex();
1040 }
1041}
1042
1043void QAbstractItemModelPrivate::columnsAboutToBeInserted(const QModelIndex &parent,
1044 int first, int last)
1045{
1046 Q_Q(QAbstractItemModel);
1047 Q_UNUSED(last);
1048 QList<QPersistentModelIndexData *> persistent_moved;
1049 if (first < q->columnCount(parent)) {
1050 for (auto *data : std::as_const(t&: persistent.indexes)) {
1051 const QModelIndex &index = data->index;
1052 if (index.column() >= first && index.isValid() && index.parent() == parent)
1053 persistent_moved.append(t: data);
1054 }
1055 }
1056 persistent.moved.push(t: persistent_moved);
1057}
1058
1059void QAbstractItemModelPrivate::columnsInserted(const QModelIndex &parent,
1060 int first, int last)
1061{
1062 const QList<QPersistentModelIndexData *> persistent_moved = persistent.moved.pop();
1063 const int count = (last - first) + 1; // it is important to only use the delta, because the change could be nested
1064 for (auto *data : persistent_moved) {
1065 QModelIndex old = data->index;
1066 persistent.indexes.erase(it: persistent.indexes.constFind(key: old));
1067 data->index = q_func()->index(row: old.row(), column: old.column() + count, parent);
1068 if (data->index.isValid()) {
1069 persistent.insertMultiAtEnd(key: data->index, data);
1070 } else {
1071 qWarning() << "QAbstractItemModel::endInsertColumns: Invalid index (" << old.row() << ',' << old.column() + count << ") in model" << q_func();
1072 }
1073 }
1074}
1075
1076void QAbstractItemModelPrivate::columnsAboutToBeRemoved(const QModelIndex &parent,
1077 int first, int last)
1078{
1079 QList<QPersistentModelIndexData *> persistent_moved;
1080 QList<QPersistentModelIndexData *> persistent_invalidated;
1081 // find the persistent indexes that are affected by the change, either by being in the removed subtree
1082 // or by being on the same level and to the right of the removed columns
1083 for (auto *data : std::as_const(t&: persistent.indexes)) {
1084 bool level_changed = false;
1085 QModelIndex current = data->index;
1086 while (current.isValid()) {
1087 QModelIndex current_parent = current.parent();
1088 if (current_parent == parent) { // on the same level as the change
1089 if (!level_changed && current.column() > last) // right of the removed columns
1090 persistent_moved.append(t: data);
1091 else if (current.column() <= last && current.column() >= first) // in the removed subtree
1092 persistent_invalidated.append(t: data);
1093 break;
1094 }
1095 current = current_parent;
1096 level_changed = true;
1097 }
1098 }
1099
1100 persistent.moved.push(t: persistent_moved);
1101 persistent.invalidated.push(t: persistent_invalidated);
1102
1103}
1104
1105void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
1106 int first, int last)
1107{
1108 const QList<QPersistentModelIndexData *> persistent_moved = persistent.moved.pop();
1109 const int count = (last - first) + 1; // it is important to only use the delta, because the change could be nested
1110 for (auto *data : persistent_moved) {
1111 QModelIndex old = data->index;
1112 persistent.indexes.erase(it: persistent.indexes.constFind(key: old));
1113 data->index = q_func()->index(row: old.row(), column: old.column() - count, parent);
1114 if (data->index.isValid()) {
1115 persistent.insertMultiAtEnd(key: data->index, data);
1116 } else {
1117 qWarning() << "QAbstractItemModel::endRemoveColumns: Invalid index (" << old.row() << ',' << old.column() - count << ") in model" << q_func();
1118 }
1119 }
1120 const QList<QPersistentModelIndexData *> persistent_invalidated = persistent.invalidated.pop();
1121 for (auto *data : persistent_invalidated) {
1122 auto index = persistent.indexes.constFind(key: data->index);
1123 if (index != persistent.indexes.constEnd())
1124 persistent.indexes.erase(it: index);
1125 data->index = QModelIndex();
1126 }
1127}
1128
1129/*!
1130 \since 4.8
1131
1132 This slot is called just after the internal data of a model is cleared
1133 while it is being reset.
1134
1135 This slot is provided the convenience of subclasses of concrete proxy
1136 models, such as subclasses of QSortFilterProxyModel which maintain extra
1137 data.
1138
1139 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 12
1140
1141 \note Due to a mistake, this slot is missing in Qt 5.0.
1142
1143 \sa modelAboutToBeReset(), modelReset()
1144*/
1145void QAbstractItemModel::resetInternalData()
1146{
1147
1148}
1149
1150/*!
1151 \class QModelIndex
1152 \inmodule QtCore
1153
1154 \brief The QModelIndex class is used to locate data in a data model.
1155
1156 \ingroup model-view
1157
1158
1159 This class is used as an index into item models derived from
1160 QAbstractItemModel. The index is used by item views, delegates, and
1161 selection models to locate an item in the model.
1162
1163 New QModelIndex objects are created by the model using the
1164 QAbstractItemModel::createIndex() function. An \e invalid model index can
1165 be constructed with the QModelIndex constructor. Invalid indexes are often
1166 used as parent indexes when referring to top-level items in a model.
1167
1168 Model indexes refer to items in models, and contain all the information
1169 required to specify their locations in those models. Each index is located
1170 in a given row and column, and may have a parent index; use row(),
1171 column(), and parent() to obtain this information. Each top-level item in a
1172 model is represented by a model index that does not have a parent index -
1173 in this case, parent() will return an invalid model index, equivalent to an
1174 index constructed with the zero argument form of the QModelIndex()
1175 constructor.
1176
1177 To obtain a model index that refers to an existing item in a model, call
1178 QAbstractItemModel::index() with the required row and column values, and
1179 the model index of the parent. When referring to top-level items in a
1180 model, supply QModelIndex() as the parent index.
1181
1182 The model() function returns the model that the index references as a
1183 QAbstractItemModel. The child() function is used to examine items held
1184 under the index in the model. The sibling() function allows you to traverse
1185 items in the model on the same level as the index.
1186
1187 \note Model indexes should be used immediately and then discarded. You
1188 should not rely on indexes to remain valid after calling model functions
1189 that change the structure of the model or delete items. If you need to
1190 keep a model index over time use a QPersistentModelIndex.
1191
1192 \sa {Model/View Programming}, QPersistentModelIndex, QAbstractItemModel
1193*/
1194
1195/*!
1196 \fn QModelIndex::QModelIndex()
1197
1198 Creates a new empty model index. This type of model index is used to
1199 indicate that the position in the model is invalid.
1200
1201 \sa isValid(), QAbstractItemModel
1202*/
1203
1204/*!
1205 \fn QModelIndex::QModelIndex(int row, int column, void *data, const QAbstractItemModel *model)
1206
1207 \internal
1208
1209 Creates a new model index at the given \a row and \a column,
1210 pointing to some \a data.
1211*/
1212
1213/*!
1214 \fn int QModelIndex::row() const
1215
1216 Returns the row this model index refers to.
1217*/
1218
1219
1220/*!
1221 \fn int QModelIndex::column() const
1222
1223 Returns the column this model index refers to.
1224*/
1225
1226
1227/*!
1228 \fn void *QModelIndex::internalPointer() const
1229
1230 Returns a \c{void} \c{*} pointer used by the model to associate
1231 the index with the internal data structure.
1232
1233 \sa QAbstractItemModel::createIndex()
1234*/
1235
1236/*!
1237 \fn const void *QModelIndex::constInternalPointer() const
1238
1239 Returns a \c{const void} \c{*} pointer used by the model to associate
1240 the index with the internal data structure.
1241
1242 \sa QAbstractItemModel::createIndex()
1243*/
1244
1245/*!
1246 \fn quintptr QModelIndex::internalId() const
1247
1248 Returns a \c{quintptr} used by the model to associate
1249 the index with the internal data structure.
1250
1251 \sa QAbstractItemModel::createIndex()
1252*/
1253
1254/*!
1255 \fn bool QModelIndex::isValid() const
1256
1257 Returns \c{true} if this model index is valid; otherwise returns \c{false}.
1258
1259 A valid index belongs to a model, and has non-negative row and column
1260 numbers.
1261
1262 \sa model(), row(), column()
1263*/
1264
1265/*!
1266 \fn const QAbstractItemModel *QModelIndex::model() const
1267
1268 Returns a pointer to the model containing the item that this index
1269 refers to.
1270
1271 A const pointer to the model is returned because calls to non-const
1272 functions of the model might invalidate the model index and possibly
1273 crash your application.
1274*/
1275
1276/*!
1277 \fn QModelIndex QModelIndex::sibling(int row, int column) const
1278
1279 Returns the sibling at \a row and \a column. If there is no sibling at this
1280 position, an invalid QModelIndex is returned.
1281
1282 \sa parent(), siblingAtColumn(), siblingAtRow()
1283*/
1284
1285/*!
1286 \fn QModelIndex QModelIndex::siblingAtColumn(int column) const
1287
1288 Returns the sibling at \a column for the current row. If there is no sibling
1289 at this position, an invalid QModelIndex is returned.
1290
1291 \sa sibling(), siblingAtRow()
1292 \since 5.11
1293*/
1294
1295/*!
1296 \fn QModelIndex QModelIndex::siblingAtRow(int row) const
1297
1298 Returns the sibling at \a row for the current column. If there is no sibling
1299 at this position, an invalid QModelIndex is returned.
1300
1301 \sa sibling(), siblingAtColumn()
1302 \since 5.11
1303*/
1304
1305/*!
1306 \fn QVariant QModelIndex::data(int role) const
1307
1308 Returns the data for the given \a role for the item referred to by the
1309 index.
1310*/
1311
1312/*!
1313 \fn void QModelIndex::multiData(QModelRoleDataSpan roleDataSpan) const
1314 \since 6.0
1315
1316 Populates the given \a roleDataSpan for the item referred to by the
1317 index.
1318*/
1319
1320/*!
1321 \fn Qt::ItemFlags QModelIndex::flags() const
1322 \since 4.2
1323
1324 Returns the flags for the item referred to by the index.
1325*/
1326
1327/*!
1328 \fn bool QModelIndex::operator==(const QModelIndex &other) const
1329
1330 Returns \c{true} if this model index refers to the same location as the
1331 \a other model index; otherwise returns \c{false}.
1332
1333 The internal data pointer, row, column, and model values are used when
1334 comparing with another model index.
1335*/
1336
1337
1338/*!
1339 \fn bool QModelIndex::operator!=(const QModelIndex &other) const
1340
1341 Returns \c{true} if this model index does not refer to the same location as
1342 the \a other model index; otherwise returns \c{false}.
1343*/
1344
1345
1346/*!
1347 \fn QModelIndex QModelIndex::parent() const
1348
1349 Returns the parent of the model index, or QModelIndex() if it has no
1350 parent.
1351
1352 \sa sibling(), model()
1353*/
1354
1355/*!
1356 \class QAbstractItemModel
1357 \inmodule QtCore
1358
1359 \brief The QAbstractItemModel class provides the abstract interface for
1360 item model classes.
1361
1362 \ingroup model-view
1363
1364
1365 The QAbstractItemModel class defines the standard interface that item
1366 models must use to be able to interoperate with other components in the
1367 model/view architecture. It is not supposed to be instantiated directly.
1368 Instead, you should subclass it to create new models.
1369
1370 The QAbstractItemModel class is one of the \l{Model/View Classes}
1371 and is part of Qt's \l{Model/View Programming}{model/view framework}. It
1372 can be used as the underlying data model for the item view elements in
1373 QML or the item view classes in the Qt Widgets module.
1374
1375 If you need a model to use with an item view such as QML's List View
1376 element or the C++ widgets QListView or QTableView, you should consider
1377 subclassing QAbstractListModel or QAbstractTableModel instead of this class.
1378
1379 The underlying data model is exposed to views and delegates as a hierarchy
1380 of tables. If you do not make use of the hierarchy, then the model is a
1381 simple table of rows and columns. Each item has a unique index specified by
1382 a QModelIndex.
1383
1384 \image modelindex-no-parent.png
1385
1386 Every item of data that can be accessed via a model has an associated model
1387 index. You can obtain this model index using the index() function. Each
1388 index may have a sibling() index; child items have a parent() index.
1389
1390 Each item has a number of data elements associated with it and they can be
1391 retrieved by specifying a role (see \l Qt::ItemDataRole) to the model's
1392 data() function. Data for all available roles can be obtained at the same
1393 time using the itemData() function.
1394
1395 Data for each role is set using a particular \l Qt::ItemDataRole. Data for
1396 individual roles are set individually with setData(), or they can be set
1397 for all roles with setItemData().
1398
1399 Items can be queried with flags() (see \l Qt::ItemFlag) to see if they can
1400 be selected, dragged, or manipulated in other ways.
1401
1402 If an item has child objects, hasChildren() returns \c{true} for the
1403 corresponding index.
1404
1405 The model has a rowCount() and a columnCount() for each level of the
1406 hierarchy. Rows and columns can be inserted and removed with insertRows(),
1407 insertColumns(), removeRows(), and removeColumns().
1408
1409 The model emits signals to indicate changes. For example, dataChanged() is
1410 emitted whenever items of data made available by the model are changed.
1411 Changes to the headers supplied by the model cause headerDataChanged() to
1412 be emitted. If the structure of the underlying data changes, the model can
1413 emit layoutChanged() to indicate to any attached views that they should
1414 redisplay any items shown, taking the new structure into account.
1415
1416 The items available through the model can be searched for particular data
1417 using the match() function.
1418
1419 To sort the model, you can use sort().
1420
1421
1422 \section1 Subclassing
1423
1424 \note Some general guidelines for subclassing models are available in the
1425 \l{Model Subclassing Reference}.
1426
1427 When subclassing QAbstractItemModel, at the very least you must implement
1428 index(), parent(), rowCount(), columnCount(), and data(). These functions
1429 are used in all read-only models, and form the basis of editable models.
1430
1431 You can also reimplement hasChildren() to provide special behavior for
1432 models where the implementation of rowCount() is expensive. This makes it
1433 possible for models to restrict the amount of data requested by views, and
1434 can be used as a way to implement lazy population of model data.
1435
1436 To enable editing in your model, you must also implement setData(), and
1437 reimplement flags() to ensure that \c ItemIsEditable is returned. You can
1438 also reimplement headerData() and setHeaderData() to control the way the
1439 headers for your model are presented.
1440
1441 The dataChanged() and headerDataChanged() signals must be emitted
1442 explicitly when reimplementing the setData() and setHeaderData() functions,
1443 respectively.
1444
1445 Custom models need to create model indexes for other components to use. To
1446 do this, call createIndex() with suitable row and column numbers for the
1447 item, and an identifier for it, either as a pointer or as an integer value.
1448 The combination of these values must be unique for each item. Custom models
1449 typically use these unique identifiers in other reimplemented functions to
1450 retrieve item data and access information about the item's parents and
1451 children. See the \l{Simple Tree Model Example} for more information about
1452 unique identifiers.
1453
1454 It is not necessary to support every role defined in Qt::ItemDataRole.
1455 Depending on the type of data contained within a model, it may only be
1456 useful to implement the data() function to return valid information for
1457 some of the more common roles. Most models provide at least a textual
1458 representation of item data for the Qt::DisplayRole, and well-behaved
1459 models should also provide valid information for the Qt::ToolTipRole and
1460 Qt::WhatsThisRole. Supporting these roles enables models to be used with
1461 standard Qt views. However, for some models that handle highly-specialized
1462 data, it may be appropriate to provide data only for user-defined roles.
1463
1464 Models that provide interfaces to resizable data structures can provide
1465 implementations of insertRows(), removeRows(), insertColumns(),and
1466 removeColumns(). When implementing these functions, it is important to
1467 notify any connected views about changes to the model's dimensions both
1468 \e before and \e after they occur:
1469
1470 \list
1471 \li An insertRows() implementation must call beginInsertRows() \e before
1472 inserting new rows into the data structure, and endInsertRows()
1473 \e{immediately afterwards}.
1474 \li An insertColumns() implementation must call beginInsertColumns()
1475 \e before inserting new columns into the data structure, and
1476 endInsertColumns() \e{immediately afterwards}.
1477 \li A removeRows() implementation must call beginRemoveRows() \e before
1478 the rows are removed from the data structure, and endRemoveRows()
1479 \e{immediately afterwards}.
1480 \li A removeColumns() implementation must call beginRemoveColumns()
1481 \e before the columns are removed from the data structure, and
1482 endRemoveColumns() \e{immediately afterwards}.
1483 \endlist
1484
1485 The \e private signals that these functions emit give attached components
1486 the chance to take action before any data becomes unavailable. The
1487 encapsulation of the insert and remove operations with these begin and end
1488 functions also enables the model to manage \l{QPersistentModelIndex}
1489 {persistent model indexes} correctly. \b{If you want selections to be
1490 handled properly, you must ensure that you call these functions.} If you
1491 insert or remove an item with children, you do not need to call these
1492 functions for the child items. In other words, the parent item will take
1493 care of its child items.
1494
1495 To create models that populate incrementally, you can reimplement
1496 fetchMore() and canFetchMore(). If the reimplementation of fetchMore() adds
1497 rows to the model, \l{QAbstractItemModel::}{beginInsertRows()} and
1498 \l{QAbstractItemModel::}{endInsertRows()} must be called.
1499
1500 \sa {Model Classes}, {Model Subclassing Reference}, QModelIndex,
1501 QAbstractItemView, {Using drag and drop with item views},
1502 {Simple Tree Model Example}, {Editable Tree Model Example},
1503 {Fetch More Example}
1504*/
1505
1506/*!
1507 \fn QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const = 0
1508
1509 Returns the index of the item in the model specified by the given \a row,
1510 \a column and \a parent index.
1511
1512 When reimplementing this function in a subclass, call createIndex() to
1513 generate model indexes that other components can use to refer to items in
1514 your model.
1515
1516 \sa createIndex()
1517*/
1518
1519/*!
1520 \fn bool QAbstractItemModel::insertColumn(int column, const QModelIndex &parent)
1521
1522 Inserts a single column before the given \a column in the child items of
1523 the \a parent specified.
1524
1525 Returns \c{true} if the column is inserted; otherwise returns \c{false}.
1526
1527 \sa insertColumns(), insertRow(), removeColumn()
1528*/
1529
1530/*!
1531 \fn bool QAbstractItemModel::insertRow(int row, const QModelIndex &parent)
1532
1533 Inserts a single row before the given \a row in the child items of the
1534 \a parent specified.
1535
1536 \note This function calls the virtual method insertRows.
1537
1538 Returns \c{true} if the row is inserted; otherwise returns \c{false}.
1539
1540 \sa insertRows(), insertColumn(), removeRow()
1541*/
1542
1543/*!
1544 \fn QModelIndex QAbstractItemModel::parent(const QModelIndex &index) const = 0
1545
1546 Returns the parent of the model item with the given \a index. If the item
1547 has no parent, an invalid QModelIndex is returned.
1548
1549 A common convention used in models that expose tree data structures is that
1550 only items in the first column have children. For that case, when
1551 reimplementing this function in a subclass the column of the returned
1552 QModelIndex would be 0.
1553
1554 When reimplementing this function in a subclass, be careful to avoid
1555 calling QModelIndex member functions, such as QModelIndex::parent(), since
1556 indexes belonging to your model will simply call your implementation,
1557 leading to infinite recursion.
1558
1559 \sa createIndex()
1560*/
1561
1562/*!
1563 \fn bool QAbstractItemModel::removeColumn(int column, const QModelIndex &parent)
1564
1565 Removes the given \a column from the child items of the \a parent
1566 specified.
1567
1568 Returns \c{true} if the column is removed; otherwise returns \c{false}.
1569
1570 \sa removeColumns(), removeRow(), insertColumn()
1571*/
1572
1573/*!
1574 \fn bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent)
1575
1576 Removes the given \a row from the child items of the \a parent specified.
1577
1578 Returns \c{true} if the row is removed; otherwise returns \c{false}.
1579
1580 This is a convenience function that calls removeRows(). The
1581 QAbstractItemModel implementation of removeRows() does nothing.
1582
1583 \sa removeRows(), removeColumn(), insertRow()
1584*/
1585
1586/*!
1587 \fn bool QAbstractItemModel::moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild)
1588
1589 On models that support this, moves \a sourceRow from \a sourceParent to \a destinationChild under
1590 \a destinationParent.
1591
1592 Returns \c{true} if the rows were successfully moved; otherwise returns
1593 \c{false}.
1594
1595 \sa moveRows(), moveColumn()
1596*/
1597
1598/*!
1599 \fn bool QAbstractItemModel::moveColumn(const QModelIndex &sourceParent, int sourceColumn, const QModelIndex &destinationParent, int destinationChild)
1600
1601 On models that support this, moves \a sourceColumn from \a sourceParent to \a destinationChild under
1602 \a destinationParent.
1603
1604 Returns \c{true} if the columns were successfully moved; otherwise returns
1605 \c{false}.
1606
1607 \sa moveColumns(), moveRow()
1608*/
1609
1610
1611/*!
1612 \fn void QAbstractItemModel::headerDataChanged(Qt::Orientation orientation, int first, int last)
1613
1614 This signal is emitted whenever a header is changed. The \a orientation
1615 indicates whether the horizontal or vertical header has changed. The
1616 sections in the header from the \a first to the \a last need to be updated.
1617
1618 When reimplementing the setHeaderData() function, this signal must be
1619 emitted explicitly.
1620
1621 If you are changing the number of columns or rows you do not need to emit
1622 this signal, but use the begin/end functions (refer to the section on
1623 subclassing in the QAbstractItemModel class description for details).
1624
1625 \sa headerData(), setHeaderData(), dataChanged()
1626*/
1627
1628
1629/*!
1630 \enum QAbstractItemModel::LayoutChangeHint
1631
1632 This enum describes the way the model changes layout.
1633
1634 \value NoLayoutChangeHint No hint is available.
1635 \value VerticalSortHint Rows are being sorted.
1636 \value HorizontalSortHint Columns are being sorted.
1637
1638 Note that VerticalSortHint and HorizontalSortHint carry the meaning that
1639 items are being moved within the same parent, not moved to a different
1640 parent in the model, and not filtered out or in.
1641*/
1642
1643/*!
1644 \fn void QAbstractItemModel::layoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint)
1645 \since 5.0
1646
1647 This signal is emitted just before the layout of a model is changed.
1648 Components connected to this signal use it to adapt to changes in the
1649 model's layout.
1650
1651 Subclasses should update any persistent model indexes after emitting
1652 layoutAboutToBeChanged().
1653
1654 The optional \a parents parameter is used to give a more specific notification
1655 about what parts of the layout of the model are changing. An empty list indicates
1656 a change to the layout of the entire model. The order of elements in the \a parents list is not significant. The optional \a hint parameter is used
1657 to give a hint about what is happening while the model is relayouting.
1658
1659 \sa layoutChanged(), changePersistentIndex()
1660*/
1661
1662/*!
1663 \fn void QAbstractItemModel::layoutChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint)
1664 \since 5.0
1665
1666 This signal is emitted whenever the layout of items exposed by the model
1667 has changed; for example, when the model has been sorted. When this signal
1668 is received by a view, it should update the layout of items to reflect this
1669 change.
1670
1671 When subclassing QAbstractItemModel or QAbstractProxyModel, ensure that you
1672 emit layoutAboutToBeChanged() before changing the order of items or
1673 altering the structure of the data you expose to views, and emit
1674 layoutChanged() after changing the layout.
1675
1676 The optional \a parents parameter is used to give a more specific notification
1677 about what parts of the layout of the model are changing. An empty list indicates
1678 a change to the layout of the entire model. The order of elements in the \a parents list is not significant. The optional \a hint parameter is used
1679 to give a hint about what is happening while the model is relayouting.
1680
1681 Subclasses should update any persistent model indexes before emitting
1682 layoutChanged(). In other words, when the structure changes:
1683
1684 \list
1685 \li emit layoutAboutToBeChanged
1686 \li Remember the QModelIndex that will change
1687 \li Update your internal data
1688 \li Call changePersistentIndex()
1689 \li emit layoutChanged
1690 \endlist
1691
1692 \sa layoutAboutToBeChanged(), dataChanged(), headerDataChanged(), modelReset(),
1693 changePersistentIndex()
1694*/
1695
1696/*!
1697 Constructs an abstract item model with the given \a parent.
1698*/
1699QAbstractItemModel::QAbstractItemModel(QObject *parent)
1700 : QObject(*new QAbstractItemModelPrivate, parent)
1701{
1702}
1703
1704/*!
1705 \internal
1706*/
1707QAbstractItemModel::QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent)
1708 : QObject(dd, parent)
1709{
1710}
1711
1712/*!
1713 Destroys the abstract item model.
1714*/
1715QAbstractItemModel::~QAbstractItemModel()
1716{
1717 d_func()->invalidatePersistentIndexes();
1718}
1719
1720
1721/*!
1722 \fn int QAbstractItemModel::rowCount(const QModelIndex &parent) const
1723
1724 Returns the number of rows under the given \a parent. When the parent is
1725 valid it means that rowCount is returning the number of children of parent.
1726
1727 \note When implementing a table based model, rowCount() should return 0
1728 when the parent is valid.
1729
1730 \sa columnCount()
1731*/
1732
1733/*!
1734 \fn int QAbstractItemModel::columnCount(const QModelIndex &parent) const
1735
1736 Returns the number of columns for the children of the given \a parent.
1737
1738 In most subclasses, the number of columns is independent of the \a parent.
1739
1740 For example:
1741
1742 \snippet ../widgets/itemviews/simpledommodel/dommodel.cpp 2
1743
1744 \note When implementing a table based model, columnCount() should return 0
1745 when the parent is valid.
1746
1747 \sa rowCount()
1748*/
1749
1750/*!
1751 \fn void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles = QList<int>())
1752
1753 This signal is emitted whenever the data in an existing item changes.
1754
1755 If the items are of the same parent, the affected ones are those between
1756 \a topLeft and \a bottomRight inclusive. If the items do not have the same
1757 parent, the behavior is undefined.
1758
1759 When reimplementing the setData() function, this signal must be emitted
1760 explicitly.
1761
1762 The optional \a roles argument can be used to specify which data roles have actually
1763 been modified. An empty vector in the roles argument means that all roles should be
1764 considered modified. The order of elements in the roles argument does not have any
1765 relevance.
1766
1767 \sa headerDataChanged(), setData(), layoutChanged()
1768*/
1769
1770/*!
1771 \fn void QAbstractItemModel::rowsInserted(const QModelIndex &parent, int first, int last)
1772
1773 This signal is emitted after rows have been inserted into the
1774 model. The new items are those between \a first and \a last
1775 inclusive, under the given \a parent item.
1776
1777 \note Components connected to this signal use it to adapt to changes in the
1778 model's dimensions. It can only be emitted by the QAbstractItemModel
1779 implementation, and cannot be explicitly emitted in subclass code.
1780
1781 \sa insertRows(), beginInsertRows()
1782*/
1783
1784/*!
1785 \fn void QAbstractItemModel::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
1786
1787 This signal is emitted just before rows are inserted into the model. The
1788 new items will be positioned between \a start and \a end inclusive, under
1789 the given \a parent item.
1790
1791 \note Components connected to this signal use it to adapt to changes
1792 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1793 implementation, and cannot be explicitly emitted in subclass code.
1794
1795 \sa insertRows(), beginInsertRows()
1796*/
1797
1798/*!
1799 \fn void QAbstractItemModel::rowsRemoved(const QModelIndex &parent, int first, int last)
1800
1801 This signal is emitted after rows have been removed from the model. The
1802 removed items are those between \a first and \a last inclusive, under the
1803 given \a parent item.
1804
1805 \note Components connected to this signal use it to adapt to changes
1806 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1807 implementation, and cannot be explicitly emitted in subclass code.
1808
1809 \sa removeRows(), beginRemoveRows()
1810*/
1811
1812/*!
1813 \fn void QAbstractItemModel::rowsAboutToBeRemoved(const QModelIndex &parent, int first, int last)
1814
1815 This signal is emitted just before rows are removed from the model. The
1816 items that will be removed are those between \a first and \a last inclusive,
1817 under the given \a parent item.
1818
1819 \note Components connected to this signal use it to adapt to changes
1820 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1821 implementation, and cannot be explicitly emitted in subclass code.
1822
1823 \sa removeRows(), beginRemoveRows()
1824*/
1825
1826/*!
1827 \fn void QAbstractItemModel::rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
1828 \since 4.6
1829
1830 This signal is emitted after rows have been moved within the
1831 model. The items between \a sourceStart and \a sourceEnd
1832 inclusive, under the given \a sourceParent item have been moved to \a destinationParent
1833 starting at the row \a destinationRow.
1834
1835 \b{Note:} Components connected to this signal use it to adapt to changes
1836 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1837 implementation, and cannot be explicitly emitted in subclass code.
1838
1839 \sa beginMoveRows()
1840*/
1841
1842/*!
1843 \fn void QAbstractItemModel::rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
1844 \since 4.6
1845
1846 This signal is emitted just before rows are moved within the
1847 model. The items that will be moved are those between \a sourceStart and \a sourceEnd
1848 inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
1849 starting at the row \a destinationRow.
1850
1851 \b{Note:} Components connected to this signal use it to adapt to changes
1852 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1853 implementation, and cannot be explicitly emitted in subclass code.
1854
1855 \sa beginMoveRows()
1856*/
1857
1858/*!
1859 \fn void QAbstractItemModel::columnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
1860 \since 4.6
1861
1862 This signal is emitted after columns have been moved within the
1863 model. The items between \a sourceStart and \a sourceEnd
1864 inclusive, under the given \a sourceParent item have been moved to \a destinationParent
1865 starting at the column \a destinationColumn.
1866
1867 \b{Note:} Components connected to this signal use it to adapt to changes
1868 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1869 implementation, and cannot be explicitly emitted in subclass code.
1870
1871 \sa beginMoveRows()
1872*/
1873
1874/*!
1875 \fn void QAbstractItemModel::columnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
1876 \since 4.6
1877
1878 This signal is emitted just before columns are moved within the
1879 model. The items that will be moved are those between \a sourceStart and \a sourceEnd
1880 inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
1881 starting at the column \a destinationColumn.
1882
1883 \b{Note:} Components connected to this signal use it to adapt to changes
1884 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1885 implementation, and cannot be explicitly emitted in subclass code.
1886
1887 \sa beginMoveRows()
1888*/
1889
1890/*!
1891 \fn void QAbstractItemModel::columnsInserted(const QModelIndex &parent, int first, int last)
1892
1893 This signal is emitted after columns have been inserted into the model. The
1894 new items are those between \a first and \a last inclusive, under the given
1895 \a parent item.
1896
1897 \note Components connected to this signal use it to adapt to changes in the
1898 model's dimensions. It can only be emitted by the QAbstractItemModel
1899 implementation, and cannot be explicitly emitted in subclass code.
1900
1901 \sa insertColumns(), beginInsertColumns()
1902*/
1903
1904/*!
1905 \fn void QAbstractItemModel::columnsAboutToBeInserted(const QModelIndex &parent, int first, int last)
1906
1907 This signal is emitted just before columns are inserted into the model. The
1908 new items will be positioned between \a first and \a last inclusive, under
1909 the given \a parent item.
1910
1911 \note Components connected to this signal use it to adapt to changes in the
1912 model's dimensions. It can only be emitted by the QAbstractItemModel
1913 implementation, and cannot be explicitly emitted in subclass code.
1914
1915 \sa insertColumns(), beginInsertColumns()
1916*/
1917
1918/*!
1919 \fn void QAbstractItemModel::columnsRemoved(const QModelIndex &parent, int first, int last)
1920
1921 This signal is emitted after columns have been removed from the model.
1922 The removed items are those between \a first and \a last inclusive,
1923 under the given \a parent item.
1924
1925 \note Components connected to this signal use it to adapt to changes in
1926 the model's dimensions. It can only be emitted by the QAbstractItemModel
1927 implementation, and cannot be explicitly emitted in subclass code.
1928
1929 \sa removeColumns(), beginRemoveColumns()
1930*/
1931
1932/*!
1933 \fn void QAbstractItemModel::columnsAboutToBeRemoved(const QModelIndex &parent, int first, int last)
1934
1935 This signal is emitted just before columns are removed from the model. The
1936 items to be removed are those between \a first and \a last inclusive, under
1937 the given \a parent item.
1938
1939 \note Components connected to this signal use it to adapt to changes in the
1940 model's dimensions. It can only be emitted by the QAbstractItemModel
1941 implementation, and cannot be explicitly emitted in subclass code.
1942
1943 \sa removeColumns(), beginRemoveColumns()
1944*/
1945
1946/*!
1947 Returns \c{true} if the model returns a valid QModelIndex for \a row and
1948 \a column with \a parent, otherwise returns \c{false}.
1949*/
1950bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const
1951{
1952 if (row < 0 || column < 0)
1953 return false;
1954 return row < rowCount(parent) && column < columnCount(parent);
1955}
1956
1957
1958/*!
1959 Returns \c{true} if \a parent has any children; otherwise returns \c{false}.
1960
1961 Use rowCount() on the parent to find out the number of children.
1962
1963 Note that it is undefined behavior to report that a particular index hasChildren
1964 with this method if the same index has the flag Qt::ItemNeverHasChildren set.
1965
1966 \sa parent(), index()
1967*/
1968bool QAbstractItemModel::hasChildren(const QModelIndex &parent) const
1969{
1970 return (rowCount(parent) > 0) && (columnCount(parent) > 0);
1971}
1972
1973/*!
1974 \fn QModelIndex QAbstractItemModel::sibling(int row, int column, const QModelIndex &index) const
1975
1976 Returns the sibling at \a row and \a column for the item at \a index, or an
1977 invalid QModelIndex if there is no sibling at that location.
1978
1979 sibling() is just a convenience function that finds the item's parent, and
1980 uses it to retrieve the index of the child item in the specified \a row and
1981 \a column.
1982
1983 This method can optionally be overridden for implementation-specific optimization.
1984
1985 \sa index(), QModelIndex::row(), QModelIndex::column()
1986*/
1987QModelIndex QAbstractItemModel::sibling(int row, int column, const QModelIndex &idx) const
1988{
1989 return (row == idx.row() && column == idx.column()) ? idx : index(row, column, parent: parent(child: idx));
1990}
1991
1992
1993/*!
1994 Returns a map with values for all predefined roles in the model for the
1995 item at the given \a index.
1996
1997 Reimplement this function if you want to extend the default behavior of
1998 this function to include custom roles in the map.
1999
2000 \sa Qt::ItemDataRole, data()
2001*/
2002QMap<int, QVariant> QAbstractItemModel::itemData(const QModelIndex &index) const
2003{
2004 QMap<int, QVariant> roles;
2005 for (int i = 0; i < Qt::UserRole; ++i) {
2006 QVariant variantData = data(index, role: i);
2007 if (variantData.isValid())
2008 roles.insert(key: i, value: variantData);
2009 }
2010 return roles;
2011}
2012
2013/*!
2014 Sets the \a role data for the item at \a index to \a value.
2015
2016 Returns \c{true} if successful; otherwise returns \c{false}.
2017
2018 The dataChanged() signal should be emitted if the data was successfully
2019 set.
2020
2021 The base class implementation returns \c{false}. This function and data() must
2022 be reimplemented for editable models.
2023
2024 \sa Qt::ItemDataRole, data(), itemData()
2025*/
2026bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
2027{
2028 Q_UNUSED(index);
2029 Q_UNUSED(value);
2030 Q_UNUSED(role);
2031 return false;
2032}
2033
2034/*!
2035 \since 6.0
2036 Removes the data stored in all the roles for the given \a index.
2037 Returns \c{true} if successful; otherwise returns \c{false}.
2038 The dataChanged() signal should be emitted if the data was successfully
2039 removed.
2040 The base class implementation returns \c{false}
2041 \sa data(), itemData(), setData(), setItemData()
2042*/
2043bool QAbstractItemModel::clearItemData(const QModelIndex &index)
2044{
2045 Q_UNUSED(index);
2046 return false;
2047}
2048
2049/*!
2050 \fn QVariant QAbstractItemModel::data(const QModelIndex &index, int role) const = 0
2051
2052 Returns the data stored under the given \a role for the item referred to
2053 by the \a index.
2054
2055 \note If you do not have a value to return, return an \b invalid
2056 (default-constructed) QVariant.
2057
2058 \sa Qt::ItemDataRole, setData(), headerData()
2059*/
2060
2061/*!
2062 Sets the role data for the item at \a index to the associated value in
2063 \a roles, for every Qt::ItemDataRole.
2064
2065 Returns \c{true} if successful; otherwise returns \c{false}.
2066
2067 Roles that are not in \a roles will not be modified.
2068
2069 \sa setData(), data(), itemData()
2070*/
2071bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
2072{
2073 // ### TODO: Consider change the semantics of this function,
2074 // or deprecating/removing it altogether.
2075 //
2076 // For instance, it should try setting *all* the data
2077 // in \a roles, and not bail out at the first setData that returns
2078 // false. It should also have a transactional approach.
2079 for (auto it = roles.begin(), e = roles.end(); it != e; ++it) {
2080 if (!setData(index, value: it.value(), role: it.key()))
2081 return false;
2082 }
2083 return true;
2084}
2085
2086/*!
2087 Returns the list of allowed MIME types. By default, the built-in
2088 models and views use an internal MIME type:
2089 \c{application/x-qabstractitemmodeldatalist}.
2090
2091 When implementing drag and drop support in a custom model, if you
2092 will return data in formats other than the default internal MIME
2093 type, reimplement this function to return your list of MIME types.
2094
2095 If you reimplement this function in your custom model, you must
2096 also reimplement the member functions that call it: mimeData() and
2097 dropMimeData().
2098
2099 \sa mimeData(), dropMimeData()
2100*/
2101QStringList QAbstractItemModel::mimeTypes() const
2102{
2103 QStringList types;
2104 types << QStringLiteral("application/x-qabstractitemmodeldatalist");
2105 return types;
2106}
2107
2108/*!
2109 Returns an object that contains serialized items of data corresponding to
2110 the list of \a indexes specified. The format used to describe the encoded
2111 data is obtained from the mimeTypes() function. This default implementation
2112 uses the default MIME type returned by the default implementation of
2113 mimeTypes(). If you reimplement mimeTypes() in your custom model to return
2114 more MIME types, reimplement this function to make use of them.
2115
2116 If the list of \a indexes is empty, or there are no supported MIME types,
2117 \nullptr is returned rather than a serialized empty list.
2118
2119 \sa mimeTypes(), dropMimeData()
2120*/
2121QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
2122{
2123 if (indexes.size() <= 0)
2124 return nullptr;
2125 QStringList types = mimeTypes();
2126 if (types.isEmpty())
2127 return nullptr;
2128 QMimeData *data = new QMimeData();
2129 QString format = types.at(i: 0);
2130 QByteArray encoded;
2131 QDataStream stream(&encoded, QDataStream::WriteOnly);
2132 encodeData(indexes, stream);
2133 data->setData(mimetype: format, data: encoded);
2134 return data;
2135}
2136
2137/*!
2138 Returns \c{true} if a model can accept a drop of the \a data. This
2139 default implementation only checks if \a data has at least one format
2140 in the list of mimeTypes() and if \a action is among the
2141 model's supportedDropActions().
2142
2143 Reimplement this function in your custom model, if you want to
2144 test whether the \a data can be dropped at \a row, \a column,
2145 \a parent with \a action. If you don't need that test, it is not
2146 necessary to reimplement this function.
2147
2148 \sa dropMimeData(), {Using drag and drop with item views}
2149 */
2150bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
2151 int row, int column,
2152 const QModelIndex &parent) const
2153{
2154 Q_UNUSED(row);
2155 Q_UNUSED(column);
2156 Q_UNUSED(parent);
2157
2158 if (!(action & supportedDropActions()))
2159 return false;
2160
2161 const QStringList modelTypes = mimeTypes();
2162 for (int i = 0; i < modelTypes.size(); ++i) {
2163 if (data->hasFormat(mimetype: modelTypes.at(i)))
2164 return true;
2165 }
2166 return false;
2167}
2168
2169/*!
2170 Handles the \a data supplied by a drag and drop operation that ended with
2171 the given \a action.
2172
2173 Returns \c{true} if the data and action were handled by the model; otherwise
2174 returns \c{false}.
2175
2176 The specified \a row, \a column and \a parent indicate the location of an
2177 item in the model where the operation ended. It is the responsibility of
2178 the model to complete the action at the correct location.
2179
2180 For instance, a drop action on an item in a QTreeView can result in new
2181 items either being inserted as children of the item specified by \a row,
2182 \a column, and \a parent, or as siblings of the item.
2183
2184 When \a row and \a column are -1 it means that the dropped data should be
2185 considered as dropped directly on \a parent. Usually this will mean
2186 appending the data as child items of \a parent. If \a row and \a column are
2187 greater than or equal zero, it means that the drop occurred just before the
2188 specified \a row and \a column in the specified \a parent.
2189
2190 The mimeTypes() member is called to get the list of acceptable MIME types.
2191 This default implementation assumes the default implementation of mimeTypes(),
2192 which returns a single default MIME type. If you reimplement mimeTypes() in
2193 your custom model to return multiple MIME types, you must reimplement this
2194 function to make use of them.
2195
2196 \sa supportedDropActions(), canDropMimeData(), {Using drag and drop with item views}
2197*/
2198bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
2199 int row, int column, const QModelIndex &parent)
2200{
2201 // check if the action is supported
2202 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
2203 return false;
2204 // check if the format is supported
2205 QStringList types = mimeTypes();
2206 if (types.isEmpty())
2207 return false;
2208 QString format = types.at(i: 0);
2209 if (!data->hasFormat(mimetype: format))
2210 return false;
2211 if (row > rowCount(parent))
2212 row = rowCount(parent);
2213 if (row == -1)
2214 row = rowCount(parent);
2215 if (column == -1)
2216 column = 0;
2217 // decode and insert
2218 QByteArray encoded = data->data(mimetype: format);
2219 QDataStream stream(&encoded, QDataStream::ReadOnly);
2220 return decodeData(row, column, parent, stream);
2221}
2222
2223/*!
2224 \since 4.2
2225
2226 Returns the drop actions supported by this model.
2227
2228 The default implementation returns Qt::CopyAction. Reimplement this
2229 function if you wish to support additional actions. You must also
2230 reimplement the dropMimeData() function to handle the additional
2231 operations.
2232
2233 \sa dropMimeData(), Qt::DropActions, {Using drag and drop with item
2234 views}
2235*/
2236Qt::DropActions QAbstractItemModel::supportedDropActions() const
2237{
2238 return Qt::CopyAction;
2239}
2240
2241/*!
2242 Returns the actions supported by the data in this model.
2243
2244 The default implementation returns supportedDropActions(). Reimplement
2245 this function if you wish to support additional actions.
2246
2247 supportedDragActions() is used by QAbstractItemView::startDrag() as the
2248 default values when a drag occurs.
2249
2250 \sa Qt::DropActions, {Using drag and drop with item views}
2251*/
2252Qt::DropActions QAbstractItemModel::supportedDragActions() const
2253{
2254 return supportedDropActions();
2255}
2256
2257/*!
2258 \note The base class implementation of this function does nothing and
2259 returns \c{false}.
2260
2261 On models that support this, inserts \a count rows into the model before
2262 the given \a row. Items in the new row will be children of the item
2263 represented by the \a parent model index.
2264
2265 If \a row is 0, the rows are prepended to any existing rows in the parent.
2266
2267 If \a row is rowCount(), the rows are appended to any existing rows in the
2268 parent.
2269
2270 If \a parent has no children, a single column with \a count rows is
2271 inserted.
2272
2273 Returns \c{true} if the rows were successfully inserted; otherwise returns
2274 \c{false}.
2275
2276 If you implement your own model, you can reimplement this function if you
2277 want to support insertions. Alternatively, you can provide your own API for
2278 altering the data. In either case, you will need to call
2279 beginInsertRows() and endInsertRows() to notify other components that the
2280 model has changed.
2281
2282 \sa insertColumns(), removeRows(), beginInsertRows(), endInsertRows()
2283*/
2284bool QAbstractItemModel::insertRows(int, int, const QModelIndex &)
2285{
2286 return false;
2287}
2288
2289/*!
2290 On models that support this, inserts \a count new columns into the model
2291 before the given \a column. The items in each new column will be children
2292 of the item represented by the \a parent model index.
2293
2294 If \a column is 0, the columns are prepended to any existing columns.
2295
2296 If \a column is columnCount(), the columns are appended to any existing
2297 columns.
2298
2299 If \a parent has no children, a single row with \a count columns is
2300 inserted.
2301
2302 Returns \c{true} if the columns were successfully inserted; otherwise returns
2303 \c{false}.
2304
2305 The base class implementation does nothing and returns \c{false}.
2306
2307 If you implement your own model, you can reimplement this function if you
2308 want to support insertions. Alternatively, you can provide your own API for
2309 altering the data.
2310
2311 \sa insertRows(), removeColumns(), beginInsertColumns(), endInsertColumns()
2312*/
2313bool QAbstractItemModel::insertColumns(int, int, const QModelIndex &)
2314{
2315 return false;
2316}
2317
2318/*!
2319 On models that support this, removes \a count rows starting with the given
2320 \a row under parent \a parent from the model.
2321
2322 Returns \c{true} if the rows were successfully removed; otherwise returns
2323 \c{false}.
2324
2325 The base class implementation does nothing and returns \c{false}.
2326
2327 If you implement your own model, you can reimplement this function if you
2328 want to support removing. Alternatively, you can provide your own API for
2329 altering the data.
2330
2331 \sa removeRow(), removeColumns(), insertColumns(), beginRemoveRows(),
2332 endRemoveRows()
2333*/
2334bool QAbstractItemModel::removeRows(int, int, const QModelIndex &)
2335{
2336 return false;
2337}
2338
2339/*!
2340 On models that support this, removes \a count columns starting with the
2341 given \a column under parent \a parent from the model.
2342
2343 Returns \c{true} if the columns were successfully removed; otherwise returns
2344 \c{false}.
2345
2346 The base class implementation does nothing and returns \c{false}.
2347
2348 If you implement your own model, you can reimplement this function if you
2349 want to support removing. Alternatively, you can provide your own API for
2350 altering the data.
2351
2352 \sa removeColumn(), removeRows(), insertColumns(), beginRemoveColumns(),
2353 endRemoveColumns()
2354*/
2355bool QAbstractItemModel::removeColumns(int, int, const QModelIndex &)
2356{
2357 return false;
2358}
2359
2360/*!
2361 On models that support this, moves \a count rows starting with the given
2362 \a sourceRow under parent \a sourceParent to row \a destinationChild under
2363 parent \a destinationParent.
2364
2365 Returns \c{true} if the rows were successfully moved; otherwise returns
2366 \c{false}.
2367
2368 The base class implementation does nothing and returns \c{false}.
2369
2370 If you implement your own model, you can reimplement this function if you
2371 want to support moving. Alternatively, you can provide your own API for
2372 altering the data.
2373
2374 \sa beginMoveRows(), endMoveRows()
2375*/
2376bool QAbstractItemModel::moveRows(const QModelIndex &, int , int , const QModelIndex &, int)
2377{
2378 return false;
2379}
2380
2381/*!
2382 On models that support this, moves \a count columns starting with the given
2383 \a sourceColumn under parent \a sourceParent to column \a destinationChild under
2384 parent \a destinationParent.
2385
2386 Returns \c{true} if the columns were successfully moved; otherwise returns
2387 \c{false}.
2388
2389 The base class implementation does nothing and returns \c{false}.
2390
2391 If you implement your own model, you can reimplement this function if you
2392 want to support moving. Alternatively, you can provide your own API for
2393 altering the data.
2394
2395 \sa beginMoveColumns(), endMoveColumns()
2396*/
2397bool QAbstractItemModel::moveColumns(const QModelIndex &, int , int , const QModelIndex &, int)
2398{
2399 return false;
2400}
2401
2402/*!
2403 Fetches any available data for the items with the parent specified by the
2404 \a parent index.
2405
2406 Reimplement this if you are populating your model incrementally.
2407
2408 The default implementation does nothing.
2409
2410 \sa canFetchMore()
2411*/
2412void QAbstractItemModel::fetchMore(const QModelIndex &)
2413{
2414 // do nothing
2415}
2416
2417/*!
2418 Returns \c{true} if there is more data available for \a parent; otherwise
2419 returns \c{false}.
2420
2421 The default implementation always returns \c{false}.
2422
2423 If canFetchMore() returns \c true, the fetchMore() function should
2424 be called. This is the behavior of QAbstractItemView, for example.
2425
2426 \sa fetchMore()
2427*/
2428bool QAbstractItemModel::canFetchMore(const QModelIndex &) const
2429{
2430 return false;
2431}
2432
2433/*!
2434 Returns the item flags for the given \a index.
2435
2436 The base class implementation returns a combination of flags that enables
2437 the item (\c ItemIsEnabled) and allows it to be selected
2438 (\c ItemIsSelectable).
2439
2440 \sa Qt::ItemFlags
2441*/
2442Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const
2443{
2444 Q_D(const QAbstractItemModel);
2445 if (!d->indexValid(index))
2446 return { };
2447
2448 return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
2449}
2450
2451/*!
2452 Sorts the model by \a column in the given \a order.
2453
2454 The base class implementation does nothing.
2455*/
2456void QAbstractItemModel::sort(int column, Qt::SortOrder order)
2457{
2458 Q_UNUSED(column);
2459 Q_UNUSED(order);
2460 // do nothing
2461}
2462
2463/*!
2464 Returns a model index for the buddy of the item represented by \a index.
2465 When the user wants to edit an item, the view will call this function to
2466 check whether another item in the model should be edited instead. Then, the
2467 view will construct a delegate using the model index returned by the buddy
2468 item.
2469
2470 The default implementation of this function has each item as its own buddy.
2471*/
2472QModelIndex QAbstractItemModel::buddy(const QModelIndex &index) const
2473{
2474 return index;
2475}
2476
2477/*!
2478 Returns a list of indexes for the items in the column of the \a start index
2479 where data stored under the given \a role matches the specified \a value.
2480 The way the search is performed is defined by the \a flags given. The list
2481 that is returned may be empty. Note also that the order of results in the
2482 list may not correspond to the order in the model, if for example a proxy
2483 model is used. The order of the results cannot be relied upon.
2484
2485 The search begins from the \a start index, and continues until the number
2486 of matching data items equals \a hits, the search reaches the last row, or
2487 the search reaches \a start again - depending on whether \c MatchWrap is
2488 specified in \a flags. If you want to search for all matching items, use
2489 \a hits = -1.
2490
2491 By default, this function will perform a wrapping, string-based comparison
2492 on all items, searching for items that begin with the search term specified
2493 by \a value.
2494
2495 \note The default implementation of this function only searches columns.
2496 Reimplement this function to include a different search behavior.
2497*/
2498QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
2499 const QVariant &value, int hits,
2500 Qt::MatchFlags flags) const
2501{
2502 QModelIndexList result;
2503 uint matchType = (flags & Qt::MatchTypeMask).toInt();
2504 Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
2505 bool recurse = flags.testAnyFlag(flag: Qt::MatchRecursive);
2506 bool wrap = flags.testAnyFlag(flag: Qt::MatchWrap);
2507 bool allHits = (hits == -1);
2508 QString text; // only convert to a string if it is needed
2509#if QT_CONFIG(regularexpression)
2510 QRegularExpression rx; // only create it if needed
2511#endif
2512 const int column = start.column();
2513 QModelIndex p = parent(child: start);
2514 int from = start.row();
2515 int to = rowCount(parent: p);
2516
2517 // iterates twice if wrapping
2518 for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
2519 for (int r = from; (r < to) && (allHits || result.size() < hits); ++r) {
2520 QModelIndex idx = index(row: r, column, parent: p);
2521 if (!idx.isValid())
2522 continue;
2523 QVariant v = data(index: idx, role);
2524 // QVariant based matching
2525 if (matchType == Qt::MatchExactly) {
2526 if (value == v)
2527 result.append(t: idx);
2528 } else { // QString or regular expression based matching
2529#if QT_CONFIG(regularexpression)
2530 if (matchType == Qt::MatchRegularExpression) {
2531 if (rx.pattern().isEmpty()) {
2532 if (value.userType() == QMetaType::QRegularExpression) {
2533 rx = value.toRegularExpression();
2534 } else {
2535 rx.setPattern(value.toString());
2536 if (cs == Qt::CaseInsensitive)
2537 rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
2538 }
2539 }
2540 } else if (matchType == Qt::MatchWildcard) {
2541 if (rx.pattern().isEmpty()) {
2542 const QString pattern = QRegularExpression::wildcardToRegularExpression(str: value.toString(), options: QRegularExpression::NonPathWildcardConversion);
2543 rx.setPattern(pattern);
2544 }
2545 if (cs == Qt::CaseInsensitive)
2546 rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
2547 } else
2548#endif
2549 {
2550 if (text.isEmpty()) // lazy conversion
2551 text = value.toString();
2552 }
2553
2554 QString t = v.toString();
2555 switch (matchType) {
2556#if QT_CONFIG(regularexpression)
2557 case Qt::MatchRegularExpression:
2558 Q_FALLTHROUGH();
2559 case Qt::MatchWildcard:
2560 if (t.contains(re: rx))
2561 result.append(t: idx);
2562 break;
2563#endif
2564 case Qt::MatchStartsWith:
2565 if (t.startsWith(s: text, cs))
2566 result.append(t: idx);
2567 break;
2568 case Qt::MatchEndsWith:
2569 if (t.endsWith(s: text, cs))
2570 result.append(t: idx);
2571 break;
2572 case Qt::MatchFixedString:
2573 if (t.compare(s: text, cs) == 0)
2574 result.append(t: idx);
2575 break;
2576 case Qt::MatchContains:
2577 default:
2578 if (t.contains(s: text, cs))
2579 result.append(t: idx);
2580 }
2581 }
2582 if (recurse) {
2583 const auto parent = column != 0 ? idx.sibling(arow: idx.row(), acolumn: 0) : idx;
2584 if (hasChildren(parent)) { // search the hierarchy
2585 result += match(start: index(row: 0, column, parent), role,
2586 value: (text.isEmpty() ? value : text),
2587 hits: (allHits ? -1 : hits - result.size()), flags);
2588 }
2589 }
2590 }
2591 // prepare for the next iteration
2592 from = 0;
2593 to = start.row();
2594 }
2595 return result;
2596}
2597
2598/*!
2599 Returns the row and column span of the item represented by \a index.
2600
2601 \note Currently, span is not used.
2602*/
2603
2604QSize QAbstractItemModel::span(const QModelIndex &) const
2605{
2606 return QSize(1, 1);
2607}
2608
2609/*!
2610 \since 4.6
2611
2612 Returns the model's role names.
2613
2614 The default role names set by Qt are:
2615
2616 \table
2617 \header
2618 \li Qt Role
2619 \li QML Role Name
2620 \row
2621 \li Qt::DisplayRole
2622 \li display
2623 \row
2624 \li Qt::DecorationRole
2625 \li decoration
2626 \row
2627 \li Qt::EditRole
2628 \li edit
2629 \row
2630 \li Qt::ToolTipRole
2631 \li toolTip
2632 \row
2633 \li Qt::StatusTipRole
2634 \li statusTip
2635 \row
2636 \li Qt::WhatsThisRole
2637 \li whatsThis
2638 \endtable
2639*/
2640QHash<int,QByteArray> QAbstractItemModel::roleNames() const
2641{
2642 return QAbstractItemModelPrivate::defaultRoleNames();
2643}
2644
2645/*!
2646 Lets the model know that it should submit cached information to permanent
2647 storage. This function is typically used for row editing.
2648
2649 Returns \c{true} if there is no error; otherwise returns \c{false}.
2650
2651 \sa revert()
2652*/
2653
2654bool QAbstractItemModel::submit()
2655{
2656 return true;
2657}
2658
2659/*!
2660 Lets the model know that it should discard cached information. This
2661 function is typically used for row editing.
2662
2663 \sa submit()
2664*/
2665
2666void QAbstractItemModel::revert()
2667{
2668 // do nothing
2669}
2670
2671/*!
2672 Returns the data for the given \a role and \a section in the header with
2673 the specified \a orientation.
2674
2675 For horizontal headers, the section number corresponds to the column
2676 number. Similarly, for vertical headers, the section number corresponds to
2677 the row number.
2678
2679 \sa Qt::ItemDataRole, setHeaderData(), QHeaderView
2680*/
2681
2682QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const
2683{
2684 Q_UNUSED(orientation);
2685 if (role == Qt::DisplayRole)
2686 return section + 1;
2687 return QVariant();
2688}
2689
2690/*!
2691 Sets the data for the given \a role and \a section in the header with the
2692 specified \a orientation to the \a value supplied.
2693
2694 Returns \c{true} if the header's data was updated; otherwise returns \c{false}.
2695
2696 When reimplementing this function, the headerDataChanged() signal must be
2697 emitted explicitly.
2698
2699 \sa Qt::ItemDataRole, headerData()
2700*/
2701
2702bool QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation,
2703 const QVariant &value, int role)
2704{
2705 Q_UNUSED(section);
2706 Q_UNUSED(orientation);
2707 Q_UNUSED(value);
2708 Q_UNUSED(role);
2709 return false;
2710}
2711
2712/*!
2713 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, const void *ptr) const
2714
2715 Creates a model index for the given \a row and \a column with the internal
2716 pointer \a ptr.
2717
2718 When using a QSortFilterProxyModel, its indexes have their own internal
2719 pointer. It is not advisable to access this internal pointer outside of the
2720 model. Use the data() function instead.
2721
2722 This function provides a consistent interface that model subclasses must
2723 use to create model indexes.
2724*/
2725
2726/*!
2727 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, quintptr id) const
2728
2729 Creates a model index for the given \a row and \a column with the internal
2730 identifier, \a id.
2731
2732 This function provides a consistent interface that model subclasses must
2733 use to create model indexes.
2734
2735 \sa QModelIndex::internalId()
2736*/
2737
2738/*!
2739 \internal
2740*/
2741void QAbstractItemModel::encodeData(const QModelIndexList &indexes, QDataStream &stream) const
2742{
2743 for (const auto &index : indexes)
2744 stream << index.row() << index.column() << itemData(index);
2745}
2746
2747/*!
2748 \internal
2749 */
2750bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &parent,
2751 QDataStream &stream)
2752{
2753 int top = INT_MAX;
2754 int left = INT_MAX;
2755 int bottom = 0;
2756 int right = 0;
2757 QList<int> rows, columns;
2758 QList<QMap<int, QVariant>> data;
2759
2760 while (!stream.atEnd()) {
2761 int r, c;
2762 QMap<int, QVariant> v;
2763 stream >> r >> c >> v;
2764 rows.append(t: r);
2765 columns.append(t: c);
2766 data.append(t: v);
2767 top = qMin(a: r, b: top);
2768 left = qMin(a: c, b: left);
2769 bottom = qMax(a: r, b: bottom);
2770 right = qMax(a: c, b: right);
2771 }
2772
2773 // insert the dragged items into the table, use a bit array to avoid overwriting items,
2774 // since items from different tables can have the same row and column
2775 int dragRowCount = 0;
2776 int dragColumnCount = right - left + 1;
2777
2778 // Compute the number of continuous rows upon insertion and modify the rows to match
2779 QList<int> rowsToInsert(bottom + 1);
2780 for (int i = 0; i < rows.size(); ++i)
2781 rowsToInsert[rows.at(i)] = 1;
2782 for (int i = 0; i < rowsToInsert.size(); ++i) {
2783 if (rowsToInsert.at(i) == 1){
2784 rowsToInsert[i] = dragRowCount;
2785 ++dragRowCount;
2786 }
2787 }
2788 for (int i = 0; i < rows.size(); ++i)
2789 rows[i] = top + rowsToInsert.at(i: rows.at(i));
2790
2791 QBitArray isWrittenTo(dragRowCount * dragColumnCount);
2792
2793 // make space in the table for the dropped data
2794 int colCount = columnCount(parent);
2795 if (colCount == 0) {
2796 insertColumns(colCount, dragColumnCount - colCount, parent);
2797 colCount = columnCount(parent);
2798 }
2799 insertRows(row, dragRowCount, parent);
2800
2801 row = qMax(a: 0, b: row);
2802 column = qMax(a: 0, b: column);
2803
2804 QList<QPersistentModelIndex> newIndexes(data.size());
2805 // set the data in the table
2806 for (int j = 0; j < data.size(); ++j) {
2807 int relativeRow = rows.at(i: j) - top;
2808 int relativeColumn = columns.at(i: j) - left;
2809 int destinationRow = relativeRow + row;
2810 int destinationColumn = relativeColumn + column;
2811 int flat = (relativeRow * dragColumnCount) + relativeColumn;
2812 // if the item was already written to, or we just can't fit it in the table, create a new row
2813 if (destinationColumn >= colCount || isWrittenTo.testBit(i: flat)) {
2814 destinationColumn = qBound(min: column, val: destinationColumn, max: colCount - 1);
2815 destinationRow = row + dragRowCount;
2816 insertRows(row + dragRowCount, 1, parent);
2817 flat = (dragRowCount * dragColumnCount) + relativeColumn;
2818 isWrittenTo.resize(size: ++dragRowCount * dragColumnCount);
2819 }
2820 if (!isWrittenTo.testBit(i: flat)) {
2821 newIndexes[j] = index(row: destinationRow, column: destinationColumn, parent);
2822 isWrittenTo.setBit(flat);
2823 }
2824 }
2825
2826 for(int k = 0; k < newIndexes.size(); k++) {
2827 if (newIndexes.at(i: k).isValid())
2828 setItemData(index: newIndexes.at(i: k), roles: data.at(i: k));
2829 }
2830
2831 return true;
2832}
2833
2834/*!
2835 Begins a row insertion operation.
2836
2837 When reimplementing insertRows() in a subclass, you must call this function
2838 \e before inserting data into the model's underlying data store.
2839
2840 The \a parent index corresponds to the parent into which the new rows are
2841 inserted; \a first and \a last are the row numbers that the new rows will
2842 have after they have been inserted.
2843
2844 \table 80%
2845 \row
2846 \li \inlineimage modelview-begin-insert-rows.png Inserting rows
2847 \li Specify the first and last row numbers for the span of rows you
2848 want to insert into an item in a model.
2849
2850 For example, as shown in the diagram, we insert three rows before
2851 row 2, so \a first is 2 and \a last is 4:
2852
2853 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 0
2854
2855 This inserts the three new rows as rows 2, 3, and 4.
2856 \row
2857 \li \inlineimage modelview-begin-append-rows.png Appending rows
2858 \li To append rows, insert them after the last row.
2859
2860 For example, as shown in the diagram, we append two rows to a
2861 collection of 4 existing rows (ending in row 3), so \a first is 4
2862 and \a last is 5:
2863
2864 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 1
2865
2866 This appends the two new rows as rows 4 and 5.
2867 \endtable
2868
2869 \note This function emits the rowsAboutToBeInserted() signal which
2870 connected views (or proxies) must handle before the data is inserted.
2871 Otherwise, the views may end up in an invalid state.
2872 \sa endInsertRows()
2873*/
2874void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
2875{
2876 Q_ASSERT(first >= 0);
2877 Q_ASSERT(first <= rowCount(parent)); // == is allowed, to insert at the end
2878 Q_ASSERT(last >= first);
2879 Q_D(QAbstractItemModel);
2880 d->changes.push(t: QAbstractItemModelPrivate::Change(parent, first, last));
2881 emit rowsAboutToBeInserted(parent, first, last, QPrivateSignal());
2882 d->rowsAboutToBeInserted(parent, first, last);
2883}
2884
2885/*!
2886 Ends a row insertion operation.
2887
2888 When reimplementing insertRows() in a subclass, you must call this function
2889 \e after inserting data into the model's underlying data store.
2890
2891 \sa beginInsertRows()
2892*/
2893void QAbstractItemModel::endInsertRows()
2894{
2895 Q_D(QAbstractItemModel);
2896 QAbstractItemModelPrivate::Change change = d->changes.pop();
2897 d->rowsInserted(parent: change.parent, first: change.first, last: change.last);
2898 emit rowsInserted(parent: change.parent, first: change.first, last: change.last, QPrivateSignal());
2899}
2900
2901/*!
2902 Begins a row removal operation.
2903
2904 When reimplementing removeRows() in a subclass, you must call this
2905 function \e before removing data from the model's underlying data store.
2906
2907 The \a parent index corresponds to the parent from which the new rows are
2908 removed; \a first and \a last are the row numbers of the rows to be
2909 removed.
2910
2911 \table 80%
2912 \row
2913 \li \inlineimage modelview-begin-remove-rows.png Removing rows
2914 \li Specify the first and last row numbers for the span of rows you
2915 want to remove from an item in a model.
2916
2917 For example, as shown in the diagram, we remove the two rows from
2918 row 2 to row 3, so \a first is 2 and \a last is 3:
2919
2920 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 2
2921 \endtable
2922
2923 \note This function emits the rowsAboutToBeRemoved() signal which connected
2924 views (or proxies) must handle before the data is removed. Otherwise, the
2925 views may end up in an invalid state.
2926
2927 \sa endRemoveRows()
2928*/
2929void QAbstractItemModel::beginRemoveRows(const QModelIndex &parent, int first, int last)
2930{
2931 Q_ASSERT(first >= 0);
2932 Q_ASSERT(last >= first);
2933 Q_ASSERT(last < rowCount(parent));
2934 Q_D(QAbstractItemModel);
2935 d->changes.push(t: QAbstractItemModelPrivate::Change(parent, first, last));
2936 emit rowsAboutToBeRemoved(parent, first, last, QPrivateSignal());
2937 d->rowsAboutToBeRemoved(parent, first, last);
2938}
2939
2940/*!
2941 Ends a row removal operation.
2942
2943 When reimplementing removeRows() in a subclass, you must call this function
2944 \e after removing data from the model's underlying data store.
2945
2946 \sa beginRemoveRows()
2947*/
2948void QAbstractItemModel::endRemoveRows()
2949{
2950 Q_D(QAbstractItemModel);
2951 QAbstractItemModelPrivate::Change change = d->changes.pop();
2952 d->rowsRemoved(parent: change.parent, first: change.first, last: change.last);
2953 emit rowsRemoved(parent: change.parent, first: change.first, last: change.last, QPrivateSignal());
2954}
2955
2956/*!
2957 Returns whether a move operation is valid.
2958
2959 A move operation is not allowed if it moves a continuous range of rows to a destination within
2960 itself, or if it attempts to move a row to one of its own descendants.
2961
2962 \internal
2963*/
2964bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int start, int end, const QModelIndex &destinationParent, int destinationStart, Qt::Orientation orientation)
2965{
2966 // Don't move the range within itself.
2967 if (destinationParent == srcParent)
2968 return !(destinationStart >= start && destinationStart <= end + 1);
2969
2970 QModelIndex destinationAncestor = destinationParent;
2971 int pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
2972 forever {
2973 if (destinationAncestor == srcParent) {
2974 if (pos >= start && pos <= end)
2975 return false;
2976 break;
2977 }
2978
2979 if (!destinationAncestor.isValid())
2980 break;
2981
2982 pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
2983 destinationAncestor = destinationAncestor.parent();
2984 }
2985
2986 return true;
2987}
2988
2989/*!
2990 \internal
2991
2992 see QTBUG-94546
2993 */
2994void QAbstractItemModelPrivate::executePendingOperations() const { }
2995
2996/*!
2997 \since 4.6
2998
2999 Begins a row move operation.
3000
3001 When reimplementing a subclass, this method simplifies moving
3002 entities in your model. This method is responsible for moving
3003 persistent indexes in the model, which you would otherwise be
3004 required to do yourself. Using beginMoveRows and endMoveRows
3005 is an alternative to emitting layoutAboutToBeChanged and
3006 layoutChanged directly along with changePersistentIndex.
3007
3008 The \a sourceParent index corresponds to the parent from which the
3009 rows are moved; \a sourceFirst and \a sourceLast are the first and last
3010 row numbers of the rows to be moved. The \a destinationParent index
3011 corresponds to the parent into which those rows are moved. The \a
3012 destinationChild is the row to which the rows will be moved. That
3013 is, the index at row \a sourceFirst in \a sourceParent will become
3014 row \a destinationChild in \a destinationParent, followed by all other
3015 rows up to \a sourceLast.
3016
3017 However, when moving rows down in the same parent (\a sourceParent
3018 and \a destinationParent are equal), the rows will be placed before the
3019 \a destinationChild index. That is, if you wish to move rows 0 and 1 so
3020 they will become rows 1 and 2, \a destinationChild should be 3. In this
3021 case, the new index for the source row \c i (which is between
3022 \a sourceFirst and \a sourceLast) is equal to
3023 \c {(destinationChild-sourceLast-1+i)}.
3024
3025 Note that if \a sourceParent and \a destinationParent are the same,
3026 you must ensure that the \a destinationChild is not within the range
3027 of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
3028 do not attempt to move a row to one of its own children or ancestors.
3029 This method returns \c{false} if either condition is true, in which case you
3030 should abort your move operation.
3031
3032 \table 80%
3033 \row
3034 \li \inlineimage modelview-move-rows-1.png Moving rows to another parent
3035 \li Specify the first and last row numbers for the span of rows in
3036 the source parent you want to move in the model. Also specify
3037 the row in the destination parent to move the span to.
3038
3039 For example, as shown in the diagram, we move three rows from
3040 row 2 to 4 in the source, so \a sourceFirst is 2 and \a sourceLast is 4.
3041 We move those items to above row 2 in the destination, so \a destinationChild is 2.
3042
3043 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 6
3044
3045 This moves the three rows rows 2, 3, and 4 in the source to become 2, 3 and 4 in
3046 the destination. Other affected siblings are displaced accordingly.
3047 \row
3048 \li \inlineimage modelview-move-rows-2.png Moving rows to append to another parent
3049 \li To append rows to another parent, move them to after the last row.
3050
3051 For example, as shown in the diagram, we move three rows to a
3052 collection of 6 existing rows (ending in row 5), so \a destinationChild is 6:
3053
3054 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 7
3055
3056 This moves the target rows to the end of the target parent as 6, 7 and 8.
3057 \row
3058 \li \inlineimage modelview-move-rows-3.png Moving rows in the same parent up
3059 \li To move rows within the same parent, specify the row to move them to.
3060
3061 For example, as shown in the diagram, we move one item from row 2 to row 0,
3062 so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 0.
3063
3064 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 8
3065
3066 Note that other rows may be displaced accordingly. Note also that when moving
3067 items within the same parent you should not attempt invalid or no-op moves. In
3068 the above example, item 2 is at row 2 before the move, so it cannot be moved
3069 to row 2 (where it is already) or row 3 (no-op as row 3 means above row 3, where
3070 it is already)
3071
3072 \row
3073 \li \inlineimage modelview-move-rows-4.png Moving rows in the same parent down
3074 \li To move rows within the same parent, specify the row to move them to.
3075
3076 For example, as shown in the diagram, we move one item from row 2 to row 4,
3077 so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 4.
3078
3079 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 9
3080
3081 Note that other rows may be displaced accordingly.
3082 \endtable
3083
3084 \sa endMoveRows()
3085*/
3086bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
3087{
3088 Q_ASSERT(sourceFirst >= 0);
3089 Q_ASSERT(sourceLast >= sourceFirst);
3090 Q_ASSERT(destinationChild >= 0);
3091 Q_D(QAbstractItemModel);
3092
3093 if (!d->allowMove(srcParent: sourceParent, start: sourceFirst, end: sourceLast, destinationParent, destinationStart: destinationChild, orientation: Qt::Vertical)) {
3094 return false;
3095 }
3096
3097 QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
3098 sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
3099 d->changes.push(t: sourceChange);
3100 int destinationLast = destinationChild + (sourceLast - sourceFirst);
3101 QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
3102 destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
3103 d->changes.push(t: destinationChange);
3104
3105 emit rowsAboutToBeMoved(sourceParent, sourceStart: sourceFirst, sourceEnd: sourceLast, destinationParent, destinationRow: destinationChild, QPrivateSignal());
3106 d->itemsAboutToBeMoved(srcParent: sourceParent, srcFirst: sourceFirst, srcLast: sourceLast, destinationParent, destinationChild, orientation: Qt::Vertical);
3107 return true;
3108}
3109
3110/*!
3111 Ends a row move operation.
3112
3113 When implementing a subclass, you must call this
3114 function \e after moving data within the model's underlying data
3115 store.
3116
3117 \sa beginMoveRows()
3118
3119 \since 4.6
3120*/
3121void QAbstractItemModel::endMoveRows()
3122{
3123 Q_D(QAbstractItemModel);
3124
3125 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
3126 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
3127
3128 QModelIndex adjustedSource = removeChange.parent;
3129 QModelIndex adjustedDestination = insertChange.parent;
3130
3131 const int numMoved = removeChange.last - removeChange.first + 1;
3132 if (insertChange.needsAdjust)
3133 adjustedDestination = createIndex(arow: adjustedDestination.row() - numMoved, acolumn: adjustedDestination.column(), adata: adjustedDestination.internalPointer());
3134
3135 if (removeChange.needsAdjust)
3136 adjustedSource = createIndex(arow: adjustedSource.row() + numMoved, acolumn: adjustedSource.column(), adata: adjustedSource.internalPointer());
3137
3138 d->itemsMoved(sourceParent: adjustedSource, sourceFirst: removeChange.first, sourceLast: removeChange.last, destinationParent: adjustedDestination, destinationChild: insertChange.first, orientation: Qt::Vertical);
3139
3140 emit rowsMoved(sourceParent: adjustedSource, sourceStart: removeChange.first, sourceEnd: removeChange.last, destinationParent: adjustedDestination, destinationRow: insertChange.first, QPrivateSignal());
3141}
3142
3143/*!
3144 Begins a column insertion operation.
3145
3146 When reimplementing insertColumns() in a subclass, you must call this
3147 function \e before inserting data into the model's underlying data store.
3148
3149 The \a parent index corresponds to the parent into which the new columns
3150 are inserted; \a first and \a last are the column numbers of the new
3151 columns will have after they have been inserted.
3152
3153 \table 80%
3154 \row
3155 \li \inlineimage modelview-begin-insert-columns.png Inserting columns
3156 \li Specify the first and last column numbers for the span of columns
3157 you want to insert into an item in a model.
3158
3159 For example, as shown in the diagram, we insert three columns
3160 before column 4, so \a first is 4 and \a last is 6:
3161
3162 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 3
3163
3164 This inserts the three new columns as columns 4, 5, and 6.
3165 \row
3166 \li \inlineimage modelview-begin-append-columns.png Appending columns
3167 \li To append columns, insert them after the last column.
3168
3169 For example, as shown in the diagram, we append three columns to a
3170 collection of six existing columns (ending in column 5), so
3171 \a first is 6 and \a last is 8:
3172
3173 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 4
3174
3175 This appends the two new columns as columns 6, 7, and 8.
3176 \endtable
3177
3178 \note This function emits the columnsAboutToBeInserted() signal which
3179 connected views (or proxies) must handle before the data is inserted.
3180 Otherwise, the views may end up in an invalid state.
3181
3182 \sa endInsertColumns()
3183*/
3184void QAbstractItemModel::beginInsertColumns(const QModelIndex &parent, int first, int last)
3185{
3186 Q_ASSERT(first >= 0);
3187 Q_ASSERT(first <= columnCount(parent)); // == is allowed, to insert at the end
3188 Q_ASSERT(last >= first);
3189 Q_D(QAbstractItemModel);
3190 d->changes.push(t: QAbstractItemModelPrivate::Change(parent, first, last));
3191 emit columnsAboutToBeInserted(parent, first, last, QPrivateSignal());
3192 d->columnsAboutToBeInserted(parent, first, last);
3193}
3194
3195/*!
3196 Ends a column insertion operation.
3197
3198 When reimplementing insertColumns() in a subclass, you must call this
3199 function \e after inserting data into the model's underlying data
3200 store.
3201
3202 \sa beginInsertColumns()
3203*/
3204void QAbstractItemModel::endInsertColumns()
3205{
3206 Q_D(QAbstractItemModel);
3207 QAbstractItemModelPrivate::Change change = d->changes.pop();
3208 d->columnsInserted(parent: change.parent, first: change.first, last: change.last);
3209 emit columnsInserted(parent: change.parent, first: change.first, last: change.last, QPrivateSignal());
3210}
3211
3212/*!
3213 Begins a column removal operation.
3214
3215 When reimplementing removeColumns() in a subclass, you must call this
3216 function \e before removing data from the model's underlying data store.
3217
3218 The \a parent index corresponds to the parent from which the new columns
3219 are removed; \a first and \a last are the column numbers of the first and
3220 last columns to be removed.
3221
3222 \table 80%
3223 \row
3224 \li \inlineimage modelview-begin-remove-columns.png Removing columns
3225 \li Specify the first and last column numbers for the span of columns
3226 you want to remove from an item in a model.
3227
3228 For example, as shown in the diagram, we remove the three columns
3229 from column 4 to column 6, so \a first is 4 and \a last is 6:
3230
3231 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 5
3232 \endtable
3233
3234 \note This function emits the columnsAboutToBeRemoved() signal which
3235 connected views (or proxies) must handle before the data is removed.
3236 Otherwise, the views may end up in an invalid state.
3237
3238 \sa endRemoveColumns()
3239*/
3240void QAbstractItemModel::beginRemoveColumns(const QModelIndex &parent, int first, int last)
3241{
3242 Q_ASSERT(first >= 0);
3243 Q_ASSERT(last >= first);
3244 Q_ASSERT(last < columnCount(parent));
3245 Q_D(QAbstractItemModel);
3246 d->changes.push(t: QAbstractItemModelPrivate::Change(parent, first, last));
3247 emit columnsAboutToBeRemoved(parent, first, last, QPrivateSignal());
3248 d->columnsAboutToBeRemoved(parent, first, last);
3249}
3250
3251/*!
3252 Ends a column removal operation.
3253
3254 When reimplementing removeColumns() in a subclass, you must call this
3255 function \e after removing data from the model's underlying data store.
3256
3257 \sa beginRemoveColumns()
3258*/
3259void QAbstractItemModel::endRemoveColumns()
3260{
3261 Q_D(QAbstractItemModel);
3262 QAbstractItemModelPrivate::Change change = d->changes.pop();
3263 d->columnsRemoved(parent: change.parent, first: change.first, last: change.last);
3264 emit columnsRemoved(parent: change.parent, first: change.first, last: change.last, QPrivateSignal());
3265}
3266
3267/*!
3268 Begins a column move operation.
3269
3270 When reimplementing a subclass, this method simplifies moving
3271 entities in your model. This method is responsible for moving
3272 persistent indexes in the model, which you would otherwise be
3273 required to do yourself. Using beginMoveColumns and endMoveColumns
3274 is an alternative to emitting layoutAboutToBeChanged and
3275 layoutChanged directly along with changePersistentIndex.
3276
3277 The \a sourceParent index corresponds to the parent from which the
3278 columns are moved; \a sourceFirst and \a sourceLast are the first and last
3279 column numbers of the columns to be moved. The \a destinationParent index
3280 corresponds to the parent into which those columns are moved. The \a
3281 destinationChild is the column to which the columns will be moved. That
3282 is, the index at column \a sourceFirst in \a sourceParent will become
3283 column \a destinationChild in \a destinationParent, followed by all other
3284 columns up to \a sourceLast.
3285
3286 However, when moving columns down in the same parent (\a sourceParent
3287 and \a destinationParent are equal), the columns will be placed before the
3288 \a destinationChild index. That is, if you wish to move columns 0 and 1 so
3289 they will become columns 1 and 2, \a destinationChild should be 3. In this
3290 case, the new index for the source column \c i (which is between
3291 \a sourceFirst and \a sourceLast) is equal to
3292 \c {(destinationChild-sourceLast-1+i)}.
3293
3294 Note that if \a sourceParent and \a destinationParent are the same,
3295 you must ensure that the \a destinationChild is not within the range
3296 of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
3297 do not attempt to move a column to one of its own children or ancestors.
3298 This method returns \c{false} if either condition is true, in which case you
3299 should abort your move operation.
3300
3301 \sa endMoveColumns()
3302
3303 \since 4.6
3304*/
3305bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
3306{
3307 Q_ASSERT(sourceFirst >= 0);
3308 Q_ASSERT(sourceLast >= sourceFirst);
3309 Q_ASSERT(destinationChild >= 0);
3310 Q_D(QAbstractItemModel);
3311
3312 if (!d->allowMove(srcParent: sourceParent, start: sourceFirst, end: sourceLast, destinationParent, destinationStart: destinationChild, orientation: Qt::Horizontal)) {
3313 return false;
3314 }
3315
3316 QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
3317 sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
3318 d->changes.push(t: sourceChange);
3319 int destinationLast = destinationChild + (sourceLast - sourceFirst);
3320 QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
3321 destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
3322 d->changes.push(t: destinationChange);
3323
3324 emit columnsAboutToBeMoved(sourceParent, sourceStart: sourceFirst, sourceEnd: sourceLast, destinationParent, destinationColumn: destinationChild, QPrivateSignal());
3325 d->itemsAboutToBeMoved(srcParent: sourceParent, srcFirst: sourceFirst, srcLast: sourceLast, destinationParent, destinationChild, orientation: Qt::Horizontal);
3326 return true;
3327}
3328
3329/*!
3330 Ends a column move operation.
3331
3332 When implementing a subclass, you must call this
3333 function \e after moving data within the model's underlying data
3334 store.
3335
3336 \sa beginMoveColumns()
3337
3338 \since 4.6
3339*/
3340void QAbstractItemModel::endMoveColumns()
3341{
3342 Q_D(QAbstractItemModel);
3343
3344 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
3345 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
3346
3347 QModelIndex adjustedSource = removeChange.parent;
3348 QModelIndex adjustedDestination = insertChange.parent;
3349
3350 const int numMoved = removeChange.last - removeChange.first + 1;
3351 if (insertChange.needsAdjust)
3352 adjustedDestination = createIndex(arow: adjustedDestination.row(), acolumn: adjustedDestination.column() - numMoved, adata: adjustedDestination.internalPointer());
3353
3354 if (removeChange.needsAdjust)
3355 adjustedSource = createIndex(arow: adjustedSource.row(), acolumn: adjustedSource.column() + numMoved, adata: adjustedSource.internalPointer());
3356
3357 d->itemsMoved(sourceParent: adjustedSource, sourceFirst: removeChange.first, sourceLast: removeChange.last, destinationParent: adjustedDestination, destinationChild: insertChange.first, orientation: Qt::Horizontal);
3358 emit columnsMoved(sourceParent: adjustedSource, sourceStart: removeChange.first, sourceEnd: removeChange.last, destinationParent: adjustedDestination, destinationColumn: insertChange.first, QPrivateSignal());
3359}
3360
3361/*!
3362 Begins a model reset operation.
3363
3364 A reset operation resets the model to its current state in any attached views.
3365
3366 \note Any views attached to this model will be reset as well.
3367
3368 When a model is reset it means that any previous data reported from the
3369 model is now invalid and has to be queried for again. This also means that
3370 the current item and any selected items will become invalid.
3371
3372 When a model radically changes its data it can sometimes be easier to just
3373 call this function rather than emit dataChanged() to inform other
3374 components when the underlying data source, or its structure, has changed.
3375
3376 You must call this function before resetting any internal data structures in your model
3377 or proxy model.
3378
3379 This function emits the signal modelAboutToBeReset().
3380
3381 \sa modelAboutToBeReset(), modelReset(), endResetModel()
3382 \since 4.6
3383*/
3384void QAbstractItemModel::beginResetModel()
3385{
3386 emit modelAboutToBeReset(QPrivateSignal());
3387}
3388
3389/*!
3390 Completes a model reset operation.
3391
3392 You must call this function after resetting any internal data structure in your model
3393 or proxy model.
3394
3395 This function emits the signal modelReset().
3396
3397 \sa beginResetModel()
3398 \since 4.6
3399*/
3400void QAbstractItemModel::endResetModel()
3401{
3402 Q_D(QAbstractItemModel);
3403 d->invalidatePersistentIndexes();
3404 resetInternalData();
3405 emit modelReset(QPrivateSignal());
3406}
3407
3408/*!
3409 Changes the QPersistentModelIndex that is equal to the given \a from model
3410 index to the given \a to model index.
3411
3412 If no persistent model index equal to the given \a from model index was
3413 found, nothing is changed.
3414
3415 \sa persistentIndexList(), changePersistentIndexList()
3416*/
3417void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QModelIndex &to)
3418{
3419 Q_D(QAbstractItemModel);
3420 if (d->persistent.indexes.isEmpty())
3421 return;
3422 // find the data and reinsert it sorted
3423 const auto it = d->persistent.indexes.constFind(key: from);
3424 if (it != d->persistent.indexes.cend()) {
3425 QPersistentModelIndexData *data = *it;
3426 d->persistent.indexes.erase(it);
3427 data->index = to;
3428 if (to.isValid())
3429 d->persistent.insertMultiAtEnd(key: to, data);
3430 }
3431}
3432
3433/*!
3434 \since 4.1
3435
3436 Changes the {QPersistentModelIndex}es that are equal to the indexes in the
3437 given \a from model index list to the given \a to model index list.
3438
3439 If no persistent model indexes equal to the indexes in the given \a from
3440 model index list are found, nothing is changed.
3441
3442 \sa persistentIndexList(), changePersistentIndex()
3443*/
3444void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
3445 const QModelIndexList &to)
3446{
3447 Q_D(QAbstractItemModel);
3448 if (d->persistent.indexes.isEmpty())
3449 return;
3450 QList<QPersistentModelIndexData *> toBeReinserted;
3451 toBeReinserted.reserve(size: to.size());
3452 for (int i = 0; i < from.size(); ++i) {
3453 if (from.at(i) == to.at(i))
3454 continue;
3455 const auto it = d->persistent.indexes.constFind(key: from.at(i));
3456 if (it != d->persistent.indexes.cend()) {
3457 QPersistentModelIndexData *data = *it;
3458 d->persistent.indexes.erase(it);
3459 data->index = to.at(i);
3460 if (data->index.isValid())
3461 toBeReinserted << data;
3462 }
3463 }
3464
3465 for (auto *data : std::as_const(t&: toBeReinserted))
3466 d->persistent.insertMultiAtEnd(key: data->index, data);
3467}
3468
3469/*!
3470 \since 4.2
3471
3472 Returns the list of indexes stored as persistent indexes in the model.
3473*/
3474QModelIndexList QAbstractItemModel::persistentIndexList() const
3475{
3476 Q_D(const QAbstractItemModel);
3477 QModelIndexList result;
3478 result.reserve(size: d->persistent.indexes.size());
3479 for (auto *data : std::as_const(t: d->persistent.indexes))
3480 result.append(t: data->index);
3481 return result;
3482}
3483
3484/*!
3485 \enum QAbstractItemModel::CheckIndexOption
3486 \since 5.11
3487
3488 This enum can be used to control the checks performed by
3489 QAbstractItemModel::checkIndex().
3490
3491 \value NoOption No check options are specified.
3492
3493 \value IndexIsValid The model index passed to
3494 QAbstractItemModel::checkIndex() is checked to be a valid model index.
3495
3496 \value DoNotUseParent Does not perform any check
3497 involving the usage of the parent of the index passed to
3498 QAbstractItemModel::checkIndex().
3499
3500 \value ParentIsInvalid The parent of the model index
3501 passed to QAbstractItemModel::checkIndex() is checked to be an invalid
3502 model index. If both this option and DoNotUseParent
3503 are specified, then this option is ignored.
3504*/
3505
3506/*!
3507 \since 5.11
3508
3509 This function checks whether \a index is a legal model index for
3510 this model. A legal model index is either an invalid model index, or a
3511 valid model index for which all the following holds:
3512
3513 \list
3514
3515 \li the index' model is \c{this};
3516 \li the index' row is greater or equal than zero;
3517 \li the index' row is less than the row count for the index' parent;
3518 \li the index' column is greater or equal than zero;
3519 \li the index' column is less than the column count for the index' parent.
3520
3521 \endlist
3522
3523 The \a options argument may change some of these checks. If \a options
3524 contains \c{IndexIsValid}, then \a index must be a valid
3525 index; this is useful when reimplementing functions such as \l{data()} or
3526 \l{setData()}, which expect valid indexes.
3527
3528 If \a options contains \c{DoNotUseParent}, then the
3529 checks that would call \l{parent()} are omitted; this allows calling this
3530 function from a \l{parent()} reimplementation (otherwise, this would result
3531 in endless recursion and a crash).
3532
3533 If \a options does not contain \c{DoNotUseParent}, and it
3534 contains \c{ParentIsInvalid}, then an additional check is
3535 performed: the parent index is checked for not being valid. This is useful
3536 when implementing flat models such as lists or tables, where no model index
3537 should have a valid parent index.
3538
3539 This function returns true if all the checks succeeded, and false otherwise.
3540 This allows to use the function in \l{Q_ASSERT} and similar other debugging
3541 mechanisms. If some check failed, a warning message will be printed in the
3542 \c{qt.core.qabstractitemmodel.checkindex} logging category, containing
3543 some information that may be useful for debugging the failure.
3544
3545 \note This function is a debugging helper for implementing your own item
3546 models. When developing complex models, as well as when building
3547 complicated model hierarchies (e.g. using proxy models), it is useful to
3548 call this function in order to catch bugs relative to illegal model indices
3549 (as defined above) accidentally passed to some QAbstractItemModel API.
3550
3551 \warning Note that it's undefined behavior to pass illegal indices to item
3552 models, so applications must refrain from doing so, and not rely on any
3553 "defensive" programming that item models could employ to handle illegal
3554 indexes gracefully.
3555
3556 \sa QModelIndex
3557*/
3558bool QAbstractItemModel::checkIndex(const QModelIndex &index, CheckIndexOptions options) const
3559{
3560 if (!index.isValid()) {
3561 if (options & CheckIndexOption::IndexIsValid) {
3562 qCWarning(lcCheckIndex) << "Index" << index << "is not valid (expected valid)";
3563 return false;
3564 }
3565 return true;
3566 }
3567
3568 if (index.model() != this) {
3569 qCWarning(lcCheckIndex) << "Index" << index
3570 << "is for model" << index.model()
3571 << "which is different from this model" << this;
3572 return false;
3573 }
3574
3575 if (index.row() < 0) {
3576 qCWarning(lcCheckIndex) << "Index" << index
3577 << "has negative row" << index.row();
3578 return false;
3579 }
3580
3581 if (index.column() < 0) {
3582 qCWarning(lcCheckIndex) << "Index" << index
3583 << "has negative column" << index.column();
3584 return false;
3585 }
3586
3587 if (!(options & CheckIndexOption::DoNotUseParent)) {
3588 const QModelIndex parentIndex = index.parent();
3589 if (options & CheckIndexOption::ParentIsInvalid) {
3590 if (parentIndex.isValid()) {
3591 qCWarning(lcCheckIndex) << "Index" << index
3592 << "has valid parent" << parentIndex
3593 << "(expected an invalid parent)";
3594 return false;
3595 }
3596 }
3597
3598 const int rc = rowCount(parent: parentIndex);
3599 if (index.row() >= rc) {
3600 qCWarning(lcCheckIndex) << "Index" << index
3601 << "has out of range row" << index.row()
3602 << "rowCount() is" << rc;
3603 return false;
3604 }
3605
3606 const int cc = columnCount(parent: parentIndex);
3607 if (index.column() >= cc) {
3608 qCWarning(lcCheckIndex) << "Index" << index
3609 << "has out of range column" << index.column()
3610 << "columnCount() is" << cc;
3611 return false;
3612
3613 }
3614 }
3615
3616 return true;
3617}
3618
3619/*!
3620 \since 6.0
3621
3622 Fills the \a roleDataSpan with the requested data for the given \a index.
3623
3624 The default implementation will call simply data() for each role in
3625 the span. A subclass can reimplement this function to provide data
3626 to views more efficiently:
3627
3628 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 15
3629
3630 In the snippet above, \c{index} is the same for the entire call.
3631 This means that accessing to the necessary data structures in order
3632 to retrieve the information for \c{index} can be done only once
3633 (hoisting the relevant code out of the loop).
3634
3635 The usage of QModelRoleData::setData(), or similarly
3636 QVariant::setValue(), is encouraged over constructing a QVariant
3637 separately and using a plain assignment operator; this is
3638 because the former allow to re-use the memory already allocated for
3639 the QVariant object stored inside a QModelRoleData, while the latter
3640 always allocates the new variant and then destroys the old one.
3641
3642 Note that views may call multiData() with spans that have been used
3643 in previous calls, and therefore may already contain some data.
3644 Therefore, it is imperative that if the model cannot return the
3645 data for a given role, then it must clear the data in the
3646 corresponding QModelRoleData object. This can be done by calling
3647 QModelRoleData::clearData(), or similarly by setting a default
3648 constructed QVariant, and so on. Failure to clear the data will
3649 result in the view believing that the "old" data is meant to be
3650 used for the corresponding role.
3651
3652 Finally, in order to avoid code duplication, a subclass may also
3653 decide to reimplement data() in terms of multiData(), by supplying
3654 a span of just one element:
3655
3656 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 16
3657
3658 \note Models are not allowed to modify the roles in the span, or
3659 to rearrange the span elements. Doing so results in undefined
3660 behavior.
3661
3662 \note It is illegal to pass an invalid model index to this function.
3663
3664 \sa QModelRoleDataSpan, data()
3665*/
3666void QAbstractItemModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const
3667{
3668 Q_ASSERT(checkIndex(index, CheckIndexOption::IndexIsValid));
3669
3670 for (QModelRoleData &d : roleDataSpan)
3671 d.setData(data(index, role: d.role()));
3672}
3673
3674/*!
3675 \class QAbstractTableModel
3676 \inmodule QtCore
3677 \brief The QAbstractTableModel class provides an abstract model that can be
3678 subclassed to create table models.
3679
3680 \ingroup model-view
3681
3682 QAbstractTableModel provides a standard interface for models that represent
3683 their data as a two-dimensional array of items. It is not used directly,
3684 but must be subclassed.
3685
3686 Since the model provides a more specialized interface than
3687 QAbstractItemModel, it is not suitable for use with tree views, although it
3688 can be used to provide data to a QListView. If you need to represent a
3689 simple list of items, and only need a model to contain a single column of
3690 data, subclassing the QAbstractListModel may be more appropriate.
3691
3692 The rowCount() and columnCount() functions return the dimensions of the
3693 table. To retrieve a model index corresponding to an item in the model, use
3694 index() and provide only the row and column numbers.
3695
3696 \section1 Subclassing
3697
3698 When subclassing QAbstractTableModel, you must implement rowCount(),
3699 columnCount(), and data(). Default implementations of the index() and
3700 parent() functions are provided by QAbstractTableModel.
3701 Well behaved models will also implement headerData().
3702
3703 Editable models need to implement setData(), and implement flags() to
3704 return a value containing
3705 \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
3706
3707 Models that provide interfaces to resizable data structures can
3708 provide implementations of insertRows(), removeRows(), insertColumns(),
3709 and removeColumns(). When implementing these functions, it is
3710 important to call the appropriate functions so that all connected views
3711 are aware of any changes:
3712
3713 \list
3714 \li An insertRows() implementation must call beginInsertRows()
3715 \e before inserting new rows into the data structure, and it must
3716 call endInsertRows() \e{immediately afterwards}.
3717 \li An insertColumns() implementation must call beginInsertColumns()
3718 \e before inserting new columns into the data structure, and it must
3719 call endInsertColumns() \e{immediately afterwards}.
3720 \li A removeRows() implementation must call beginRemoveRows()
3721 \e before the rows are removed from the data structure, and it must
3722 call endRemoveRows() \e{immediately afterwards}.
3723 \li A removeColumns() implementation must call beginRemoveColumns()
3724 \e before the columns are removed from the data structure, and it must
3725 call endRemoveColumns() \e{immediately afterwards}.
3726 \endlist
3727
3728 \note Some general guidelines for subclassing models are available in the
3729 \l{Model Subclassing Reference}.
3730
3731 \note
3732
3733 \sa {Model Classes}, QAbstractItemModel, QAbstractListModel
3734*/
3735
3736/*!
3737 Constructs an abstract table model for the given \a parent.
3738*/
3739
3740QAbstractTableModel::QAbstractTableModel(QObject *parent)
3741 : QAbstractItemModel(parent)
3742{
3743
3744}
3745
3746/*!
3747 \internal
3748
3749 Constructs an abstract table model with \a dd and the given \a parent.
3750*/
3751
3752QAbstractTableModel::QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent)
3753 : QAbstractItemModel(dd, parent)
3754{
3755
3756}
3757
3758/*!
3759 Destroys the abstract table model.
3760*/
3761
3762QAbstractTableModel::~QAbstractTableModel()
3763{
3764
3765}
3766
3767/*!
3768 \fn QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
3769
3770 Returns the index of the data in \a row and \a column with \a parent.
3771
3772 \sa parent()
3773*/
3774
3775QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent) const
3776{
3777 return hasIndex(row, column, parent) ? createIndex(arow: row, acolumn: column) : QModelIndex();
3778}
3779
3780/*!
3781 \fn QModelIndex QAbstractTableModel::parent(const QModelIndex &index) const
3782
3783 Returns the parent of the model item with the given \a index.
3784
3785 \sa index(), hasChildren()
3786*/
3787
3788QModelIndex QAbstractTableModel::parent(const QModelIndex &) const
3789{
3790 return QModelIndex();
3791}
3792
3793/*!
3794 \reimp
3795*/
3796QModelIndex QAbstractTableModel::sibling(int row, int column, const QModelIndex &) const
3797{
3798 return index(row, column);
3799}
3800
3801bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
3802{
3803 if (!parent.isValid())
3804 return rowCount(parent) > 0 && columnCount(parent) > 0;
3805 return false;
3806}
3807
3808/*!
3809 \reimp
3810 */
3811Qt::ItemFlags QAbstractTableModel::flags(const QModelIndex &index) const
3812{
3813 Qt::ItemFlags f = QAbstractItemModel::flags(index);
3814 if (index.isValid())
3815 f |= Qt::ItemNeverHasChildren;
3816 return f;
3817}
3818
3819/*!
3820 \class QAbstractListModel
3821 \inmodule QtCore
3822 \brief The QAbstractListModel class provides an abstract model that can be
3823 subclassed to create one-dimensional list models.
3824
3825 \ingroup model-view
3826
3827 QAbstractListModel provides a standard interface for models that represent
3828 their data as a simple non-hierarchical sequence of items. It is not used
3829 directly, but must be subclassed.
3830
3831 Since the model provides a more specialized interface than
3832 QAbstractItemModel, it is not suitable for use with tree views; you will
3833 need to subclass QAbstractItemModel if you want to provide a model for
3834 that purpose. If you need to use a number of list models to manage data,
3835 it may be more appropriate to subclass QAbstractTableModel instead.
3836
3837 Simple models can be created by subclassing this class and implementing
3838 the minimum number of required functions. For example, we could implement
3839 a simple read-only QStringList-based model that provides a list of strings
3840 to a QListView widget. In such a case, we only need to implement the
3841 rowCount() function to return the number of items in the list, and the
3842 data() function to retrieve items from the list.
3843
3844 Since the model represents a one-dimensional structure, the rowCount()
3845 function returns the total number of items in the model. The columnCount()
3846 function is implemented for interoperability with all kinds of views, but
3847 by default informs views that the model contains only one column.
3848
3849 \section1 Subclassing
3850
3851 When subclassing QAbstractListModel, you must provide implementations
3852 of the rowCount() and data() functions. Well behaved models also provide
3853 a headerData() implementation.
3854
3855 If your model is used within QML and requires roles other than the
3856 default ones provided by the roleNames() function, you must override it.
3857
3858 For editable list models, you must also provide an implementation of
3859 setData(), and implement the flags() function so that it returns a value
3860 containing \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
3861
3862 Note that QAbstractListModel provides a default implementation of
3863 columnCount() that informs views that there is only a single column
3864 of items in this model.
3865
3866 Models that provide interfaces to resizable list-like data structures
3867 can provide implementations of insertRows() and removeRows(). When
3868 implementing these functions, it is important to call the appropriate
3869 functions so that all connected views are aware of any changes:
3870
3871 \list
3872 \li An insertRows() implementation must call beginInsertRows()
3873 \e before inserting new rows into the data structure, and it must
3874 call endInsertRows() \e{immediately afterwards}.
3875 \li A removeRows() implementation must call beginRemoveRows()
3876 \e before the rows are removed from the data structure, and it must
3877 call endRemoveRows() \e{immediately afterwards}.
3878 \endlist
3879
3880 \note Some general guidelines for subclassing models are available in the
3881 \l{Model Subclassing Reference}.
3882
3883 \sa {Model Classes}, {Model Subclassing Reference}, QAbstractItemView,
3884 QAbstractTableModel
3885*/
3886
3887/*!
3888 Constructs an abstract list model with the given \a parent.
3889*/
3890
3891QAbstractListModel::QAbstractListModel(QObject *parent)
3892 : QAbstractItemModel(parent)
3893{
3894
3895}
3896
3897/*!
3898 \internal
3899
3900 Constructs an abstract list model with \a dd and the given \a parent.
3901*/
3902
3903QAbstractListModel::QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent)
3904 : QAbstractItemModel(dd, parent)
3905{
3906
3907}
3908
3909/*!
3910 Destroys the abstract list model.
3911*/
3912
3913QAbstractListModel::~QAbstractListModel()
3914{
3915
3916}
3917
3918/*!
3919 \fn QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
3920
3921 Returns the index of the data in \a row and \a column with \a parent.
3922
3923 \sa parent()
3924*/
3925
3926QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent) const
3927{
3928 return hasIndex(row, column, parent) ? createIndex(arow: row, acolumn: column) : QModelIndex();
3929}
3930
3931/*!
3932 Returns the parent of the model item with the given \a index.
3933
3934 \sa index(), hasChildren()
3935*/
3936
3937QModelIndex QAbstractListModel::parent(const QModelIndex & /* index */) const
3938{
3939 return QModelIndex();
3940}
3941
3942/*!
3943 \reimp
3944*/
3945QModelIndex QAbstractListModel::sibling(int row, int column, const QModelIndex &) const
3946{
3947 return index(row, column);
3948}
3949
3950/*!
3951 \reimp
3952 */
3953Qt::ItemFlags QAbstractListModel::flags(const QModelIndex &index) const
3954{
3955 Qt::ItemFlags f = QAbstractItemModel::flags(index);
3956 if (index.isValid())
3957 f |= Qt::ItemNeverHasChildren;
3958 return f;
3959}
3960
3961/*!
3962 \internal
3963
3964 Returns the number of columns in the list with the given \a parent.
3965
3966 \sa rowCount()
3967*/
3968
3969int QAbstractListModel::columnCount(const QModelIndex &parent) const
3970{
3971 return parent.isValid() ? 0 : 1;
3972}
3973
3974bool QAbstractListModel::hasChildren(const QModelIndex &parent) const
3975{
3976 return parent.isValid() ? false : (rowCount() > 0);
3977}
3978
3979/*!
3980 \typedef QModelIndexList
3981 \relates QModelIndex
3982
3983 Synonym for QList<QModelIndex>.
3984*/
3985
3986/*!
3987 \reimp
3988*/
3989bool QAbstractTableModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
3990 int row, int column, const QModelIndex &parent)
3991{
3992 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
3993 return false;
3994
3995 QStringList types = mimeTypes();
3996 if (types.isEmpty())
3997 return false;
3998 QString format = types.at(i: 0);
3999 if (!data->hasFormat(mimetype: format))
4000 return false;
4001
4002 QByteArray encoded = data->data(mimetype: format);
4003 QDataStream stream(&encoded, QDataStream::ReadOnly);
4004
4005 // if the drop is on an item, replace the data in the items
4006 if (parent.isValid() && row == -1 && column == -1) {
4007 int top = INT_MAX;
4008 int left = INT_MAX;
4009 QList<int> rows, columns;
4010 QList<QMap<int, QVariant>> data;
4011
4012 while (!stream.atEnd()) {
4013 int r, c;
4014 QMap<int, QVariant> v;
4015 stream >> r >> c >> v;
4016 rows.append(t: r);
4017 columns.append(t: c);
4018 data.append(t: v);
4019 top = qMin(a: r, b: top);
4020 left = qMin(a: c, b: left);
4021 }
4022
4023 for (int i = 0; i < data.size(); ++i) {
4024 int r = (rows.at(i) - top) + parent.row();
4025 int c = (columns.at(i) - left) + parent.column();
4026 if (hasIndex(row: r, column: c))
4027 setItemData(index: index(row: r, column: c), roles: data.at(i));
4028 }
4029
4030 return true;
4031 }
4032
4033 // otherwise insert new rows for the data
4034 return decodeData(row, column, parent, stream);
4035}
4036
4037/*!
4038 \reimp
4039*/
4040bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
4041 int row, int column, const QModelIndex &parent)
4042{
4043 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
4044 return false;
4045
4046 QStringList types = mimeTypes();
4047 if (types.isEmpty())
4048 return false;
4049 QString format = types.at(i: 0);
4050 if (!data->hasFormat(mimetype: format))
4051 return false;
4052
4053 QByteArray encoded = data->data(mimetype: format);
4054 QDataStream stream(&encoded, QDataStream::ReadOnly);
4055
4056 // if the drop is on an item, replace the data in the items
4057 if (parent.isValid() && row == -1 && column == -1) {
4058 int top = INT_MAX;
4059 int left = INT_MAX;
4060 QList<int> rows, columns;
4061 QList<QMap<int, QVariant>> data;
4062
4063 while (!stream.atEnd()) {
4064 int r, c;
4065 QMap<int, QVariant> v;
4066 stream >> r >> c >> v;
4067 rows.append(t: r);
4068 columns.append(t: c);
4069 data.append(t: v);
4070 top = qMin(a: r, b: top);
4071 left = qMin(a: c, b: left);
4072 }
4073
4074 for (int i = 0; i < data.size(); ++i) {
4075 int r = (rows.at(i) - top) + parent.row();
4076 if (columns.at(i) == left && hasIndex(row: r, column: 0))
4077 setItemData(index: index(row: r), roles: data.at(i));
4078 }
4079
4080 return true;
4081 }
4082
4083 if (row == -1)
4084 row = rowCount(parent);
4085
4086 // otherwise insert new rows for the data
4087 return decodeData(row, column, parent, stream);
4088}
4089
4090/*!
4091 \fn QAbstractItemModel::modelAboutToBeReset()
4092 \since 4.2
4093
4094 This signal is emitted when beginResetModel() is called, before the model's internal
4095 state (e.g. persistent model indexes) has been invalidated.
4096
4097 \sa beginResetModel(), modelReset()
4098*/
4099
4100/*!
4101 \fn QAbstractItemModel::modelReset()
4102 \since 4.1
4103
4104 This signal is emitted when endResetModel() is called, after the
4105 model's internal state (e.g. persistent model indexes) has been invalidated.
4106
4107 Note that if a model is reset it should be considered that all information
4108 previously retrieved from it is invalid. This includes but is not limited
4109 to the rowCount() and columnCount(), flags(), data retrieved through data(),
4110 and roleNames().
4111
4112 \sa endResetModel(), modelAboutToBeReset()
4113*/
4114
4115/*!
4116 \fn bool QModelIndex::operator<(const QModelIndex &other) const
4117 \since 4.1
4118
4119 Returns \c{true} if this model index is smaller than the \a other
4120 model index; otherwise returns \c{false}.
4121
4122 The less than calculation is not directly useful to developers - the way that indexes
4123 with different parents compare is not defined. This operator only exists so that the
4124 class can be used with QMap.
4125*/
4126
4127/*!
4128 \fn size_t qHash(const QPersistentModelIndex &index, size_t seed = 0)
4129 \since 5.0
4130 \relates QPersistentModelIndex
4131
4132 Returns a hash of the QPersistentModelIndex \a index, using \a seed to
4133 seed the calculation.
4134*/
4135
4136
4137/*!
4138 \internal
4139 QMultiHash::insert inserts the value before the old value. and find() return the new value.
4140 We need insertMultiAtEnd because we don't want to overwrite the old one, which should be removed later
4141
4142 There should be only one instance QPersistentModelIndexData per index, but in some intermediate state there may be
4143 severals of PersistantModelIndex pointing to the same index, but one is already updated, and the other one is not.
4144 This make sure than when updating the first one we don't overwrite the second one in the hash, and the second one
4145 will be updated right later.
4146 */
4147void QAbstractItemModelPrivate::Persistent::insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data)
4148{
4149 auto newIt = indexes.insert(key, value: data);
4150 auto it = newIt;
4151 ++it;
4152 while (it != indexes.end() && it.key() == key) {
4153 qSwap(value1&: *newIt,value2&: *it);
4154 newIt = it;
4155 ++it;
4156 }
4157}
4158
4159QT_END_NAMESPACE
4160
4161#include "moc_qabstractitemmodel.cpp"
4162

source code of qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp