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