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

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