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

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