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