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