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