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 QStringList types;
2177 types << QStringLiteral("application/x-qabstractitemmodeldatalist");
2178 return types;
2179}
2180
2181/*!
2182 Returns an object that contains serialized items of data corresponding to
2183 the list of \a indexes specified. The format used to describe the encoded
2184 data is obtained from the mimeTypes() function. This default implementation
2185 uses the default MIME type returned by the default implementation of
2186 mimeTypes(). If you reimplement mimeTypes() in your custom model to return
2187 more MIME types, reimplement this function to make use of them.
2188
2189 If the list of \a indexes is empty, or there are no supported MIME types,
2190 \nullptr is returned rather than a serialized empty list.
2191
2192 \sa mimeTypes(), dropMimeData()
2193*/
2194QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
2195{
2196 if (indexes.size() <= 0)
2197 return nullptr;
2198 QStringList types = mimeTypes();
2199 if (types.isEmpty())
2200 return nullptr;
2201 QMimeData *data = new QMimeData();
2202 QString format = types.at(0);
2203 QByteArray encoded;
2204 QDataStream stream(&encoded, QDataStream::WriteOnly);
2205 encodeData(indexes, stream);
2206 data->setData(format, encoded);
2207 return data;
2208}
2209
2210/*!
2211 Returns \c{true} if a model can accept a drop of the \a data. This
2212 default implementation only checks if \a data has at least one format
2213 in the list of mimeTypes() and if \a action is among the
2214 model's supportedDropActions().
2215
2216 Reimplement this function in your custom model, if you want to
2217 test whether the \a data can be dropped at \a row, \a column,
2218 \a parent with \a action. If you don't need that test, it is not
2219 necessary to reimplement this function.
2220
2221 \sa dropMimeData(), {Using drag and drop with item views}
2222 */
2223bool QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
2224 int row, int column,
2225 const QModelIndex &parent) const
2226{
2227 Q_UNUSED(row);
2228 Q_UNUSED(column);
2229 Q_UNUSED(parent);
2230
2231 if (!(action & supportedDropActions()))
2232 return false;
2233
2234 const QStringList modelTypes = mimeTypes();
2235 for (int i = 0; i < modelTypes.size(); ++i) {
2236 if (data->hasFormat(modelTypes.at(i)))
2237 return true;
2238 }
2239 return false;
2240}
2241
2242/*!
2243 Handles the \a data supplied by a drag and drop operation that ended with
2244 the given \a action.
2245
2246 Returns \c{true} if the data and action were handled by the model; otherwise
2247 returns \c{false}.
2248
2249 The specified \a row, \a column and \a parent indicate the location of an
2250 item in the model where the operation ended. It is the responsibility of
2251 the model to complete the action at the correct location.
2252
2253 For instance, a drop action on an item in a QTreeView can result in new
2254 items either being inserted as children of the item specified by \a row,
2255 \a column, and \a parent, or as siblings of the item.
2256
2257 When \a row and \a column are -1 it means that the dropped data should be
2258 considered as dropped directly on \a parent. Usually this will mean
2259 appending the data as child items of \a parent. If \a row and \a column are
2260 greater than or equal zero, it means that the drop occurred just before the
2261 specified \a row and \a column in the specified \a parent.
2262
2263 The mimeTypes() member is called to get the list of acceptable MIME types.
2264 This default implementation assumes the default implementation of mimeTypes(),
2265 which returns a single default MIME type. If you reimplement mimeTypes() in
2266 your custom model to return multiple MIME types, you must reimplement this
2267 function to make use of them.
2268
2269 \sa supportedDropActions(), canDropMimeData(), {Using drag and drop with item views}
2270*/
2271bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
2272 int row, int column, const QModelIndex &parent)
2273{
2274 // check if the action is supported
2275 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
2276 return false;
2277 // check if the format is supported
2278 const QStringList types = mimeTypes();
2279 if (types.isEmpty())
2280 return false;
2281 const QString format = types.at(0);
2282 if (!data->hasFormat(format))
2283 return false;
2284 const bool dropOnItem = row == -1 && column == -1 && parent.isValid();
2285 if (!dropOnItem || !parent.flags().testFlag(Qt::ItemNeverHasChildren)) {
2286 // drop in between items, or on an item that cannot have children
2287 // -> insert new item
2288 if (row > rowCount(parent))
2289 row = rowCount(parent);
2290 if (row == -1)
2291 row = rowCount(parent);
2292 if (column == -1)
2293 column = 0;
2294 }
2295 // decode and insert
2296 QByteArray encoded = data->data(format);
2297 QDataStream stream(&encoded, QDataStream::ReadOnly);
2298 return decodeData(row, column, parent, stream);
2299}
2300
2301/*!
2302 \since 4.2
2303
2304 Returns the drop actions supported by this model.
2305
2306 The default implementation returns Qt::CopyAction. Reimplement this
2307 function if you wish to support additional actions. You must also
2308 reimplement the dropMimeData() function to handle the additional
2309 operations.
2310
2311 \sa dropMimeData(), Qt::DropActions, {Using drag and drop with item
2312 views}
2313*/
2314Qt::DropActions QAbstractItemModel::supportedDropActions() const
2315{
2316 return Qt::CopyAction;
2317}
2318
2319/*!
2320 Returns the actions supported by the data in this model.
2321
2322 The default implementation returns supportedDropActions(). Reimplement
2323 this function if you wish to support additional actions.
2324
2325 supportedDragActions() is used by QAbstractItemView::startDrag() as the
2326 default values when a drag occurs.
2327
2328 \sa Qt::DropActions, {Using drag and drop with item views}
2329*/
2330Qt::DropActions QAbstractItemModel::supportedDragActions() const
2331{
2332 return supportedDropActions();
2333}
2334
2335/*!
2336 \note The base class implementation of this function does nothing and
2337 returns \c{false}.
2338
2339 On models that support this, inserts \a count rows into the model before
2340 the given \a row. Items in the new row will be children of the item
2341 represented by the \a parent model index.
2342
2343 If \a row is 0, the rows are prepended to any existing rows in the parent.
2344
2345 If \a row is rowCount(), the rows are appended to any existing rows in the
2346 parent.
2347
2348 If \a parent has no children, a single column with \a count rows is
2349 inserted.
2350
2351 Returns \c{true} if the rows were successfully inserted; otherwise returns
2352 \c{false}.
2353
2354 If you implement your own model, you can reimplement this function if you
2355 want to support insertions. Alternatively, you can provide your own API for
2356 altering the data. In either case, you will need to call
2357 beginInsertRows() and endInsertRows() to notify other components that the
2358 model has changed.
2359
2360 \sa insertColumns(), removeRows(), beginInsertRows(), endInsertRows()
2361*/
2362bool QAbstractItemModel::insertRows(int, int, const QModelIndex &)
2363{
2364 return false;
2365}
2366
2367/*!
2368 On models that support this, inserts \a count new columns into the model
2369 before the given \a column. The items in each new column will be children
2370 of the item represented by the \a parent model index.
2371
2372 If \a column is 0, the columns are prepended to any existing columns.
2373
2374 If \a column is columnCount(), the columns are appended to any existing
2375 columns.
2376
2377 If \a parent has no children, a single row with \a count columns is
2378 inserted.
2379
2380 Returns \c{true} if the columns were successfully inserted; otherwise returns
2381 \c{false}.
2382
2383 The base class implementation does nothing and returns \c{false}.
2384
2385 If you implement your own model, you can reimplement this function if you
2386 want to support insertions. Alternatively, you can provide your own API for
2387 altering the data.
2388
2389 \sa insertRows(), removeColumns(), beginInsertColumns(), endInsertColumns()
2390*/
2391bool QAbstractItemModel::insertColumns(int, int, const QModelIndex &)
2392{
2393 return false;
2394}
2395
2396/*!
2397 On models that support this, removes \a count rows starting with the given
2398 \a row under parent \a parent from the model.
2399
2400 Returns \c{true} if the rows were successfully removed; otherwise returns
2401 \c{false}.
2402
2403 The base class implementation does nothing and returns \c{false}.
2404
2405 If you implement your own model, you can reimplement this function if you
2406 want to support removing. Alternatively, you can provide your own API for
2407 altering the data.
2408
2409 \sa removeRow(), removeColumns(), insertColumns(), beginRemoveRows(),
2410 endRemoveRows()
2411*/
2412bool QAbstractItemModel::removeRows(int, int, const QModelIndex &)
2413{
2414 return false;
2415}
2416
2417/*!
2418 On models that support this, removes \a count columns starting with the
2419 given \a column under parent \a parent from the model.
2420
2421 Returns \c{true} if the columns were successfully removed; otherwise returns
2422 \c{false}.
2423
2424 The base class implementation does nothing and returns \c{false}.
2425
2426 If you implement your own model, you can reimplement this function if you
2427 want to support removing. Alternatively, you can provide your own API for
2428 altering the data.
2429
2430 \sa removeColumn(), removeRows(), insertColumns(), beginRemoveColumns(),
2431 endRemoveColumns()
2432*/
2433bool QAbstractItemModel::removeColumns(int, int, const QModelIndex &)
2434{
2435 return false;
2436}
2437
2438/*!
2439 On models that support this, moves \a count rows starting with the given
2440 \a sourceRow under parent \a sourceParent to row \a destinationChild under
2441 parent \a destinationParent.
2442
2443 Returns \c{true} if the rows were successfully moved; otherwise returns
2444 \c{false}.
2445
2446 The base class implementation does nothing and returns \c{false}.
2447
2448 If you implement your own model, you can reimplement this function if you
2449 want to support moving. Alternatively, you can provide your own API for
2450 altering the data.
2451
2452 \sa beginMoveRows(), endMoveRows()
2453*/
2454bool QAbstractItemModel::moveRows(const QModelIndex &, int , int , const QModelIndex &, int)
2455{
2456 return false;
2457}
2458
2459/*!
2460 On models that support this, moves \a count columns starting with the given
2461 \a sourceColumn under parent \a sourceParent to column \a destinationChild under
2462 parent \a destinationParent.
2463
2464 Returns \c{true} if the columns were successfully moved; otherwise returns
2465 \c{false}.
2466
2467 The base class implementation does nothing and returns \c{false}.
2468
2469 If you implement your own model, you can reimplement this function if you
2470 want to support moving. Alternatively, you can provide your own API for
2471 altering the data.
2472
2473 \sa beginMoveColumns(), endMoveColumns()
2474*/
2475bool QAbstractItemModel::moveColumns(const QModelIndex &, int , int , const QModelIndex &, int)
2476{
2477 return false;
2478}
2479
2480/*!
2481 Fetches any available data for the items with the parent specified by the
2482 \a parent index.
2483
2484 Reimplement this if you are populating your model incrementally.
2485
2486 The default implementation does nothing.
2487
2488 \sa canFetchMore()
2489*/
2490void QAbstractItemModel::fetchMore(const QModelIndex &)
2491{
2492 // do nothing
2493}
2494
2495/*!
2496 Returns \c{true} if there is more data available for \a parent; otherwise
2497 returns \c{false}.
2498
2499 The default implementation always returns \c{false}.
2500
2501 If canFetchMore() returns \c true, the fetchMore() function should
2502 be called. This is the behavior of QAbstractItemView, for example.
2503
2504 \sa fetchMore()
2505*/
2506bool QAbstractItemModel::canFetchMore(const QModelIndex &) const
2507{
2508 return false;
2509}
2510
2511/*!
2512 Returns the item flags for the given \a index.
2513
2514 The base class implementation returns a combination of flags that enables
2515 the item (\c ItemIsEnabled) and allows it to be selected
2516 (\c ItemIsSelectable).
2517
2518 \sa Qt::ItemFlags
2519*/
2520Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const
2521{
2522 Q_D(const QAbstractItemModel);
2523 if (!d->indexValid(index))
2524 return { };
2525
2526 return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
2527}
2528
2529/*!
2530 Sorts the model by \a column in the given \a order.
2531
2532 The base class implementation does nothing.
2533*/
2534void QAbstractItemModel::sort(int column, Qt::SortOrder order)
2535{
2536 Q_UNUSED(column);
2537 Q_UNUSED(order);
2538 // do nothing
2539}
2540
2541/*!
2542 Returns a model index for the buddy of the item represented by \a index.
2543 When the user wants to edit an item, the view will call this function to
2544 check whether another item in the model should be edited instead. Then, the
2545 view will construct a delegate using the model index returned by the buddy
2546 item.
2547
2548 The default implementation of this function has each item as its own buddy.
2549*/
2550QModelIndex QAbstractItemModel::buddy(const QModelIndex &index) const
2551{
2552 return index;
2553}
2554
2555/*!
2556 Returns a list of indexes for the items in the column of the \a start index
2557 where data stored under the given \a role matches the specified \a value.
2558 The way the search is performed is defined by the \a flags given. The list
2559 that is returned may be empty. Note also that the order of results in the
2560 list may not correspond to the order in the model, if for example a proxy
2561 model is used. The order of the results cannot be relied upon.
2562
2563 The search begins from the \a start index, and continues until the number
2564 of matching data items equals \a hits, the search reaches the last row, or
2565 the search reaches \a start again - depending on whether \c MatchWrap is
2566 specified in \a flags. If you want to search for all matching items, use
2567 \a hits = -1.
2568
2569 By default, this function will perform a wrapping, string-based comparison
2570 on all items, searching for items that begin with the search term specified
2571 by \a value.
2572
2573 \note The default implementation of this function only searches columns.
2574 Reimplement this function to include a different search behavior.
2575*/
2576QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
2577 const QVariant &value, int hits,
2578 Qt::MatchFlags flags) const
2579{
2580 QModelIndexList result;
2581 uint matchType = (flags & Qt::MatchTypeMask).toInt();
2582 Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
2583 bool recurse = flags.testAnyFlag(Qt::MatchRecursive);
2584 bool wrap = flags.testAnyFlag(Qt::MatchWrap);
2585 bool allHits = (hits == -1);
2586 QString text; // only convert to a string if it is needed
2587#if QT_CONFIG(regularexpression)
2588 QRegularExpression rx; // only create it if needed
2589#endif
2590 const int column = start.column();
2591 QModelIndex p = parent(start);
2592 int from = start.row();
2593 int to = rowCount(p);
2594
2595 // iterates twice if wrapping
2596 for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
2597 for (int r = from; (r < to) && (allHits || result.size() < hits); ++r) {
2598 QModelIndex idx = index(r, column, p);
2599 if (!idx.isValid())
2600 continue;
2601 QVariant v = data(idx, role);
2602 // QVariant based matching
2603 if (matchType == Qt::MatchExactly) {
2604 if (value == v)
2605 result.append(idx);
2606 } else { // QString or regular expression based matching
2607#if QT_CONFIG(regularexpression)
2608 if (matchType == Qt::MatchRegularExpression) {
2609 if (rx.pattern().isEmpty()) {
2610 if (value.userType() == QMetaType::QRegularExpression) {
2611 rx = value.toRegularExpression();
2612 } else {
2613 rx.setPattern(value.toString());
2614 if (cs == Qt::CaseInsensitive)
2615 rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
2616 }
2617 }
2618 } else if (matchType == Qt::MatchWildcard) {
2619 if (rx.pattern().isEmpty()) {
2620 const QString pattern = QRegularExpression::wildcardToRegularExpression(value.toString(), QRegularExpression::NonPathWildcardConversion);
2621 rx.setPattern(pattern);
2622 }
2623 if (cs == Qt::CaseInsensitive)
2624 rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
2625 } else
2626#endif
2627 {
2628 if (text.isEmpty()) // lazy conversion
2629 text = value.toString();
2630 }
2631
2632 QString t = v.toString();
2633 switch (matchType) {
2634#if QT_CONFIG(regularexpression)
2635 case Qt::MatchRegularExpression:
2636 Q_FALLTHROUGH();
2637 case Qt::MatchWildcard:
2638 if (t.contains(rx))
2639 result.append(idx);
2640 break;
2641#endif
2642 case Qt::MatchStartsWith:
2643 if (t.startsWith(text, cs))
2644 result.append(idx);
2645 break;
2646 case Qt::MatchEndsWith:
2647 if (t.endsWith(text, cs))
2648 result.append(idx);
2649 break;
2650 case Qt::MatchFixedString:
2651 if (t.compare(text, cs) == 0)
2652 result.append(idx);
2653 break;
2654 case Qt::MatchContains:
2655 default:
2656 if (t.contains(text, cs))
2657 result.append(idx);
2658 }
2659 }
2660 if (recurse) {
2661 const auto parent = column != 0 ? idx.sibling(idx.row(), 0) : idx;
2662 if (hasChildren(parent)) { // search the hierarchy
2663 result += match(index(0, column, parent), role,
2664 (text.isEmpty() ? value : text),
2665 (allHits ? -1 : hits - result.size()), flags);
2666 }
2667 }
2668 }
2669 // prepare for the next iteration
2670 from = 0;
2671 to = start.row();
2672 }
2673 return result;
2674}
2675
2676/*!
2677 Returns the row and column span of the item represented by \a index.
2678
2679 \note Currently, span is not used.
2680*/
2681
2682QSize QAbstractItemModel::span(const QModelIndex &) const
2683{
2684 return QSize(1, 1);
2685}
2686
2687/*!
2688 \since 4.6
2689
2690 Returns the model's role names.
2691
2692 The default role names set by Qt are:
2693
2694 \table
2695 \header
2696 \li Qt Role
2697 \li QML Role Name
2698 \row
2699 \li Qt::DisplayRole
2700 \li display
2701 \row
2702 \li Qt::DecorationRole
2703 \li decoration
2704 \row
2705 \li Qt::EditRole
2706 \li edit
2707 \row
2708 \li Qt::ToolTipRole
2709 \li toolTip
2710 \row
2711 \li Qt::StatusTipRole
2712 \li statusTip
2713 \row
2714 \li Qt::WhatsThisRole
2715 \li whatsThis
2716 \endtable
2717*/
2718QHash<int,QByteArray> QAbstractItemModel::roleNames() const
2719{
2720 // if the return value ever becomes dependent on *this, also change the following overrides:
2721 // - QFileSystemModel
2722 // - QConcatenateTablesProxyModel
2723 return QAbstractItemModelPrivate::defaultRoleNames();
2724}
2725
2726/*!
2727 Lets the model know that it should submit cached information to permanent
2728 storage. This function is typically used for row editing.
2729
2730 Returns \c{true} if there is no error; otherwise returns \c{false}.
2731
2732 \sa revert()
2733*/
2734
2735bool QAbstractItemModel::submit()
2736{
2737 return true;
2738}
2739
2740/*!
2741 Lets the model know that it should discard cached information. This
2742 function is typically used for row editing.
2743
2744 \sa submit()
2745*/
2746
2747void QAbstractItemModel::revert()
2748{
2749 // do nothing
2750}
2751
2752/*!
2753 Returns the data for the given \a role and \a section in the header with
2754 the specified \a orientation.
2755
2756 For horizontal headers, the section number corresponds to the column
2757 number. Similarly, for vertical headers, the section number corresponds to
2758 the row number.
2759
2760 \sa Qt::ItemDataRole, setHeaderData(), QHeaderView
2761*/
2762
2763QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const
2764{
2765 Q_UNUSED(orientation);
2766 if (role == Qt::DisplayRole)
2767 return section + 1;
2768 return QVariant();
2769}
2770
2771/*!
2772 Sets the data for the given \a role and \a section in the header with the
2773 specified \a orientation to the \a value supplied.
2774
2775 Returns \c{true} if the header's data was updated; otherwise returns \c{false}.
2776
2777 When reimplementing this function, the headerDataChanged() signal must be
2778 emitted explicitly.
2779
2780 \sa Qt::ItemDataRole, headerData()
2781*/
2782
2783bool QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation,
2784 const QVariant &value, int role)
2785{
2786 Q_UNUSED(section);
2787 Q_UNUSED(orientation);
2788 Q_UNUSED(value);
2789 Q_UNUSED(role);
2790 return false;
2791}
2792
2793/*!
2794 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, const void *ptr) const
2795
2796 Creates a model index for the given \a row and \a column with the internal
2797 pointer \a ptr.
2798
2799 When using a QSortFilterProxyModel, its indexes have their own internal
2800 pointer. It is not advisable to access this internal pointer outside of the
2801 model. Use the data() function instead.
2802
2803 This function provides a consistent interface that model subclasses must
2804 use to create model indexes.
2805*/
2806
2807/*!
2808 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, quintptr id) const
2809
2810 Creates a model index for the given \a row and \a column with the internal
2811 identifier, \a id.
2812
2813 This function provides a consistent interface that model subclasses must
2814 use to create model indexes.
2815
2816 \sa QModelIndex::internalId()
2817*/
2818
2819/*!
2820 \internal
2821*/
2822void QAbstractItemModel::encodeData(const QModelIndexList &indexes, QDataStream &stream) const
2823{
2824 for (const auto &index : indexes)
2825 stream << index.row() << index.column() << itemData(index);
2826}
2827
2828/*!
2829 \internal
2830 */
2831bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &parent,
2832 QDataStream &stream)
2833{
2834 int top = INT_MAX;
2835 int left = INT_MAX;
2836 int bottom = 0;
2837 int right = 0;
2838 QList<int> rows, columns;
2839 QList<QMap<int, QVariant>> data;
2840
2841 while (!stream.atEnd()) {
2842 int r, c;
2843 QMap<int, QVariant> v;
2844 stream >> r >> c >> v;
2845 rows.append(r);
2846 columns.append(c);
2847 data.append(v);
2848 top = qMin(r, top);
2849 left = qMin(c, left);
2850 bottom = qMax(r, bottom);
2851 right = qMax(c, right);
2852 }
2853
2854 // insert the dragged items into the table, use a bit array to avoid overwriting items,
2855 // since items from different tables can have the same row and column
2856 int dragRowCount = 0;
2857 int dragColumnCount = right - left + 1;
2858
2859 // Compute the number of continuous rows upon insertion and modify the rows to match
2860 QList<int> rowsToInsert(bottom + 1);
2861 for (int i = 0; i < rows.size(); ++i)
2862 rowsToInsert[rows.at(i)] = 1;
2863 for (int i = 0; i < rowsToInsert.size(); ++i) {
2864 if (rowsToInsert.at(i) == 1){
2865 rowsToInsert[i] = dragRowCount;
2866 ++dragRowCount;
2867 }
2868 }
2869 for (int i = 0; i < rows.size(); ++i)
2870 rows[i] = top + rowsToInsert.at(rows.at(i));
2871
2872 QBitArray isWrittenTo(dragRowCount * dragColumnCount);
2873
2874 // make space in the table for the dropped data
2875 int colCount = columnCount(parent);
2876 if (colCount == 0) {
2877 insertColumns(colCount, dragColumnCount - colCount, parent);
2878 colCount = columnCount(parent);
2879 }
2880 insertRows(row, dragRowCount, parent);
2881
2882 row = qMax(0, row);
2883 column = qMax(0, column);
2884
2885 QList<QPersistentModelIndex> newIndexes(data.size());
2886 // set the data in the table
2887 for (int j = 0; j < data.size(); ++j) {
2888 int relativeRow = rows.at(j) - top;
2889 int relativeColumn = columns.at(j) - left;
2890 int destinationRow = relativeRow + row;
2891 int destinationColumn = relativeColumn + column;
2892 int flat = (relativeRow * dragColumnCount) + relativeColumn;
2893 // if the item was already written to, or we just can't fit it in the table, create a new row
2894 if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) {
2895 destinationColumn = qBound(column, destinationColumn, qMax(colCount - 1, column));
2896 destinationRow = row + dragRowCount;
2897 insertRows(row + dragRowCount, 1, parent);
2898 flat = (dragRowCount * dragColumnCount) + relativeColumn;
2899 isWrittenTo.resize(++dragRowCount * dragColumnCount);
2900 }
2901 if (!isWrittenTo.testBit(flat)) {
2902 newIndexes[j] = index(destinationRow, destinationColumn, parent);
2903 isWrittenTo.setBit(flat);
2904 }
2905 }
2906
2907 for(int k = 0; k < newIndexes.size(); k++) {
2908 if (newIndexes.at(k).isValid())
2909 setItemData(newIndexes.at(k), data.at(k));
2910 }
2911
2912 return true;
2913}
2914
2915/*!
2916 Begins a row insertion operation.
2917
2918 When reimplementing insertRows() in a subclass, you must call this function
2919 \e before inserting data into the model's underlying data store.
2920
2921 The \a parent index corresponds to the parent into which the new rows are
2922 inserted; \a first and \a last are the row numbers that the new rows will
2923 have after they have been inserted.
2924
2925 \table 80%
2926 \row
2927 \li \inlineimage modelview-begin-insert-rows.svg
2928 {Inserting rows 2, 3, 4 into a list}
2929 \li Specify the first and last row numbers for the span of rows you
2930 want to insert into an item in a model.
2931
2932 For example, as shown in the diagram, we insert three rows before
2933 row 2, so \a first is 2 and \a last is 4:
2934
2935 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 0
2936
2937 This inserts the three new rows as rows 2, 3, and 4.
2938 \row
2939 \li \inlineimage modelview-begin-append-rows.svg
2940 {Appending rows 4, 5 to a list}
2941 \li To append rows, insert them after the last row.
2942
2943 For example, as shown in the diagram, we append two rows to a
2944 collection of 4 existing rows (ending in row 3), so \a first is 4
2945 and \a last is 5:
2946
2947 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 1
2948
2949 This appends the two new rows as rows 4 and 5.
2950 \endtable
2951
2952 \note This function emits the rowsAboutToBeInserted() signal which
2953 connected views (or proxies) must handle before the data is inserted.
2954 Otherwise, the views may end up in an invalid state.
2955 \sa endInsertRows()
2956*/
2957void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
2958{
2959 Q_ASSERT(first >= 0);
2960 Q_ASSERT(first <= rowCount(parent)); // == is allowed, to insert at the end
2961 Q_ASSERT(last >= first);
2962 Q_D(QAbstractItemModel);
2963 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2964 emit rowsAboutToBeInserted(parent, first, last, QPrivateSignal());
2965 d->rowsAboutToBeInserted(parent, first, last);
2966}
2967
2968/*!
2969 Ends a row insertion operation.
2970
2971 When reimplementing insertRows() in a subclass, you must call this function
2972 \e after inserting data into the model's underlying data store.
2973
2974 \sa beginInsertRows()
2975*/
2976void QAbstractItemModel::endInsertRows()
2977{
2978 Q_D(QAbstractItemModel);
2979 QAbstractItemModelPrivate::Change change = d->changes.pop();
2980 d->rowsInserted(change.parent, change.first, change.last);
2981 emit rowsInserted(change.parent, change.first, change.last, QPrivateSignal());
2982}
2983
2984/*!
2985 Begins a row removal operation.
2986
2987 When reimplementing removeRows() in a subclass, you must call this
2988 function \e before removing data from the model's underlying data store.
2989
2990 The \a parent index corresponds to the parent from which the new rows are
2991 removed; \a first and \a last are the row numbers of the rows to be
2992 removed.
2993
2994 \table 80%
2995 \row
2996 \li \inlineimage modelview-begin-remove-rows.svg
2997 {Removing rows 2 and 3 from a list}
2998 \li Specify the first and last row numbers for the span of rows you
2999 want to remove from an item in a model.
3000
3001 For example, as shown in the diagram, we remove the two rows from
3002 row 2 to row 3, so \a first is 2 and \a last is 3:
3003
3004 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 2
3005 \endtable
3006
3007 \note This function emits the rowsAboutToBeRemoved() signal which connected
3008 views (or proxies) must handle before the data is removed. Otherwise, the
3009 views may end up in an invalid state.
3010
3011 \sa endRemoveRows()
3012*/
3013void QAbstractItemModel::beginRemoveRows(const QModelIndex &parent, int first, int last)
3014{
3015 Q_ASSERT(first >= 0);
3016 Q_ASSERT(last >= first);
3017 Q_ASSERT(last < rowCount(parent));
3018 Q_D(QAbstractItemModel);
3019 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
3020 emit rowsAboutToBeRemoved(parent, first, last, QPrivateSignal());
3021 d->rowsAboutToBeRemoved(parent, first, last);
3022}
3023
3024/*!
3025 Ends a row removal operation.
3026
3027 When reimplementing removeRows() in a subclass, you must call this function
3028 \e after removing data from the model's underlying data store.
3029
3030 \sa beginRemoveRows()
3031*/
3032void QAbstractItemModel::endRemoveRows()
3033{
3034 Q_D(QAbstractItemModel);
3035 QAbstractItemModelPrivate::Change change = d->changes.pop();
3036 d->rowsRemoved(change.parent, change.first, change.last);
3037 emit rowsRemoved(change.parent, change.first, change.last, QPrivateSignal());
3038}
3039
3040/*!
3041 Returns whether a move operation is valid.
3042
3043 A move operation is not allowed if it moves a continuous range of rows to a destination within
3044 itself, or if it attempts to move a row to one of its own descendants.
3045
3046 \internal
3047*/
3048bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int start, int end, const QModelIndex &destinationParent, int destinationStart, Qt::Orientation orientation)
3049{
3050 // Don't move the range within itself.
3051 if (destinationParent == srcParent)
3052 return !(destinationStart >= start && destinationStart <= end + 1);
3053
3054 QModelIndex destinationAncestor = destinationParent;
3055 int pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
3056 forever {
3057 if (destinationAncestor == srcParent) {
3058 if (pos >= start && pos <= end)
3059 return false;
3060 break;
3061 }
3062
3063 if (!destinationAncestor.isValid())
3064 break;
3065
3066 pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
3067 destinationAncestor = destinationAncestor.parent();
3068 }
3069
3070 return true;
3071}
3072
3073/*!
3074 \internal
3075
3076 see QTBUG-94546
3077 */
3078void QAbstractItemModelPrivate::executePendingOperations() const { }
3079
3080/*!
3081 \since 4.6
3082
3083 Begins a row move operation.
3084
3085 When reimplementing a subclass, this method simplifies moving
3086 entities in your model. This method is responsible for moving
3087 persistent indexes in the model, which you would otherwise be
3088 required to do yourself. Using beginMoveRows and endMoveRows
3089 is an alternative to emitting layoutAboutToBeChanged and
3090 layoutChanged directly along with changePersistentIndex.
3091
3092 The \a sourceParent index corresponds to the parent from which the
3093 rows are moved; \a sourceFirst and \a sourceLast are the first and last
3094 row numbers of the rows to be moved. The \a destinationParent index
3095 corresponds to the parent into which those rows are moved. The \a
3096 destinationChild is the row to which the rows will be moved. That
3097 is, the index at row \a sourceFirst in \a sourceParent will become
3098 row \a destinationChild in \a destinationParent, followed by all other
3099 rows up to \a sourceLast.
3100
3101 However, when moving rows down in the same parent (\a sourceParent
3102 and \a destinationParent are equal), the rows will be placed before the
3103 \a destinationChild index. That is, if you wish to move rows 0 and 1 so
3104 they will become rows 1 and 2, \a destinationChild should be 3. In this
3105 case, the new index for the source row \c i (which is between
3106 \a sourceFirst and \a sourceLast) is equal to
3107 \c {(destinationChild-sourceLast-1+i)}.
3108
3109 Note that if \a sourceParent and \a destinationParent are the same,
3110 you must ensure that the \a destinationChild is not within the range
3111 of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
3112 do not attempt to move a row to one of its own children or ancestors.
3113 This method returns \c{false} if either condition is true, in which case you
3114 should abort your move operation.
3115
3116 \table 80%
3117 \row
3118 \li \inlineimage modelview-move-rows-1.svg
3119 {Moving rows from one parent to another}
3120 \li Specify the first and last row numbers for the span of rows in
3121 the source parent you want to move in the model. Also specify
3122 the row in the destination parent to move the span to.
3123
3124 For example, as shown in the diagram, we move three rows from
3125 row 2 to 4 in the source, so \a sourceFirst is 2 and \a sourceLast is 4.
3126 We move those items to above row 2 in the destination, so \a destinationChild is 2.
3127
3128 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 6
3129
3130 This moves the three rows rows 2, 3, and 4 in the source to become 2, 3 and 4 in
3131 the destination. Other affected siblings are displaced accordingly.
3132 \row
3133 \li \inlineimage modelview-move-rows-2.svg
3134 {Appending rows to another parent}
3135 \li To append rows to another parent, move them to after the last row.
3136
3137 For example, as shown in the diagram, we move three rows to a
3138 collection of 6 existing rows (ending in row 5), so \a destinationChild is 6:
3139
3140 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 7
3141
3142 This moves the target rows to the end of the target parent as 6, 7 and 8.
3143 \row
3144 \li \inlineimage modelview-move-rows-3.svg
3145 {Moving a row up within the same parent}
3146 \li To move rows within the same parent, specify the row to move them to.
3147
3148 For example, as shown in the diagram, we move one item from row 2 to row 0,
3149 so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 0.
3150
3151 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 8
3152
3153 Note that other rows may be displaced accordingly. Note also that when moving
3154 items within the same parent you should not attempt invalid or no-op moves. In
3155 the above example, item 2 is at row 2 before the move, so it cannot be moved
3156 to row 2 (where it is already) or row 3 (no-op as row 3 means above row 3, where
3157 it is already)
3158
3159 \row
3160 \li \inlineimage modelview-move-rows-4.svg
3161 {Moving a row down within the same parent}
3162 \li To move rows within the same parent, specify the row to move them to.
3163
3164 For example, as shown in the diagram, we move one item from row 2 to row 4,
3165 so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 4.
3166
3167 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 9
3168
3169 Note that other rows may be displaced accordingly.
3170 \endtable
3171
3172 \sa endMoveRows()
3173*/
3174bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
3175{
3176 Q_ASSERT(sourceFirst >= 0);
3177 Q_ASSERT(sourceLast >= sourceFirst);
3178 Q_ASSERT(destinationChild >= 0);
3179 Q_D(QAbstractItemModel);
3180
3181 if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical)) {
3182 return false;
3183 }
3184
3185 QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
3186 sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
3187 d->changes.push(sourceChange);
3188 int destinationLast = destinationChild + (sourceLast - sourceFirst);
3189 QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
3190 destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
3191 d->changes.push(destinationChange);
3192
3193 emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
3194 d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical);
3195 return true;
3196}
3197
3198/*!
3199 Ends a row move operation.
3200
3201 When implementing a subclass, you must call this
3202 function \e after moving data within the model's underlying data
3203 store.
3204
3205 \sa beginMoveRows()
3206
3207 \since 4.6
3208*/
3209void QAbstractItemModel::endMoveRows()
3210{
3211 Q_D(QAbstractItemModel);
3212
3213 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
3214 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
3215
3216 QModelIndex adjustedSource = removeChange.parent;
3217 QModelIndex adjustedDestination = insertChange.parent;
3218
3219 const int numMoved = removeChange.last - removeChange.first + 1;
3220 if (insertChange.needsAdjust)
3221 adjustedDestination = createIndex(adjustedDestination.row() - numMoved, adjustedDestination.column(), adjustedDestination.internalPointer());
3222
3223 if (removeChange.needsAdjust)
3224 adjustedSource = createIndex(adjustedSource.row() + numMoved, adjustedSource.column(), adjustedSource.internalPointer());
3225
3226 d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Vertical);
3227
3228 emit rowsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
3229}
3230
3231/*!
3232 Begins a column insertion operation.
3233
3234 When reimplementing insertColumns() in a subclass, you must call this
3235 function \e before inserting data into the model's underlying data store.
3236
3237 The \a parent index corresponds to the parent into which the new columns
3238 are inserted; \a first and \a last are the column numbers of the new
3239 columns will have after they have been inserted.
3240
3241 \table 80%
3242 \row
3243 \li \inlineimage modelview-begin-insert-columns.svg
3244 {Inserting columns 4, 5, 6 into a row}
3245 \li Specify the first and last column numbers for the span of columns
3246 you want to insert into an item in a model.
3247
3248 For example, as shown in the diagram, we insert three columns
3249 before column 4, so \a first is 4 and \a last is 6:
3250
3251 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 3
3252
3253 This inserts the three new columns as columns 4, 5, and 6.
3254 \row
3255 \li \inlineimage modelview-begin-append-columns.svg
3256 {Appending columns 6, 7, 8 to a row}
3257 \li To append columns, insert them after the last column.
3258
3259 For example, as shown in the diagram, we append three columns to a
3260 collection of six existing columns (ending in column 5), so
3261 \a first is 6 and \a last is 8:
3262
3263 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 4
3264
3265 This appends the two new columns as columns 6, 7, and 8.
3266 \endtable
3267
3268 \note This function emits the columnsAboutToBeInserted() signal which
3269 connected views (or proxies) must handle before the data is inserted.
3270 Otherwise, the views may end up in an invalid state.
3271
3272 \sa endInsertColumns()
3273*/
3274void QAbstractItemModel::beginInsertColumns(const QModelIndex &parent, int first, int last)
3275{
3276 Q_ASSERT(first >= 0);
3277 Q_ASSERT(first <= columnCount(parent)); // == is allowed, to insert at the end
3278 Q_ASSERT(last >= first);
3279 Q_D(QAbstractItemModel);
3280 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
3281 emit columnsAboutToBeInserted(parent, first, last, QPrivateSignal());
3282 d->columnsAboutToBeInserted(parent, first, last);
3283}
3284
3285/*!
3286 Ends a column insertion operation.
3287
3288 When reimplementing insertColumns() in a subclass, you must call this
3289 function \e after inserting data into the model's underlying data
3290 store.
3291
3292 \sa beginInsertColumns()
3293*/
3294void QAbstractItemModel::endInsertColumns()
3295{
3296 Q_D(QAbstractItemModel);
3297 QAbstractItemModelPrivate::Change change = d->changes.pop();
3298 d->columnsInserted(change.parent, change.first, change.last);
3299 emit columnsInserted(change.parent, change.first, change.last, QPrivateSignal());
3300}
3301
3302/*!
3303 Begins a column removal operation.
3304
3305 When reimplementing removeColumns() in a subclass, you must call this
3306 function \e before removing data from the model's underlying data store.
3307
3308 The \a parent index corresponds to the parent from which the new columns
3309 are removed; \a first and \a last are the column numbers of the first and
3310 last columns to be removed.
3311
3312 \table 80%
3313 \row
3314 \li \inlineimage modelview-begin-remove-columns.svg
3315 {Removing columns 4, 5, 6 from a row}
3316 \li Specify the first and last column numbers for the span of columns
3317 you want to remove from an item in a model.
3318
3319 For example, as shown in the diagram, we remove the three columns
3320 from column 4 to column 6, so \a first is 4 and \a last is 6:
3321
3322 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 5
3323 \endtable
3324
3325 \note This function emits the columnsAboutToBeRemoved() signal which
3326 connected views (or proxies) must handle before the data is removed.
3327 Otherwise, the views may end up in an invalid state.
3328
3329 \sa endRemoveColumns()
3330*/
3331void QAbstractItemModel::beginRemoveColumns(const QModelIndex &parent, int first, int last)
3332{
3333 Q_ASSERT(first >= 0);
3334 Q_ASSERT(last >= first);
3335 Q_ASSERT(last < columnCount(parent));
3336 Q_D(QAbstractItemModel);
3337 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
3338 emit columnsAboutToBeRemoved(parent, first, last, QPrivateSignal());
3339 d->columnsAboutToBeRemoved(parent, first, last);
3340}
3341
3342/*!
3343 Ends a column removal operation.
3344
3345 When reimplementing removeColumns() in a subclass, you must call this
3346 function \e after removing data from the model's underlying data store.
3347
3348 \sa beginRemoveColumns()
3349*/
3350void QAbstractItemModel::endRemoveColumns()
3351{
3352 Q_D(QAbstractItemModel);
3353 QAbstractItemModelPrivate::Change change = d->changes.pop();
3354 d->columnsRemoved(change.parent, change.first, change.last);
3355 emit columnsRemoved(change.parent, change.first, change.last, QPrivateSignal());
3356}
3357
3358/*!
3359 Begins a column move operation.
3360
3361 When reimplementing a subclass, this method simplifies moving
3362 entities in your model. This method is responsible for moving
3363 persistent indexes in the model, which you would otherwise be
3364 required to do yourself. Using beginMoveColumns and endMoveColumns
3365 is an alternative to emitting layoutAboutToBeChanged and
3366 layoutChanged directly along with changePersistentIndex.
3367
3368 The \a sourceParent index corresponds to the parent from which the
3369 columns are moved; \a sourceFirst and \a sourceLast are the first and last
3370 column numbers of the columns to be moved. The \a destinationParent index
3371 corresponds to the parent into which those columns are moved. The \a
3372 destinationChild is the column to which the columns will be moved. That
3373 is, the index at column \a sourceFirst in \a sourceParent will become
3374 column \a destinationChild in \a destinationParent, followed by all other
3375 columns up to \a sourceLast.
3376
3377 However, when moving columns down in the same parent (\a sourceParent
3378 and \a destinationParent are equal), the columns will be placed before the
3379 \a destinationChild index. That is, if you wish to move columns 0 and 1 so
3380 they will become columns 1 and 2, \a destinationChild should be 3. In this
3381 case, the new index for the source column \c i (which is between
3382 \a sourceFirst and \a sourceLast) is equal to
3383 \c {(destinationChild-sourceLast-1+i)}.
3384
3385 Note that if \a sourceParent and \a destinationParent are the same,
3386 you must ensure that the \a destinationChild is not within the range
3387 of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
3388 do not attempt to move a column to one of its own children or ancestors.
3389 This method returns \c{false} if either condition is true, in which case you
3390 should abort your move operation.
3391
3392 \sa endMoveColumns()
3393
3394 \since 4.6
3395*/
3396bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
3397{
3398 Q_ASSERT(sourceFirst >= 0);
3399 Q_ASSERT(sourceLast >= sourceFirst);
3400 Q_ASSERT(destinationChild >= 0);
3401 Q_D(QAbstractItemModel);
3402
3403 if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal)) {
3404 return false;
3405 }
3406
3407 QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
3408 sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
3409 d->changes.push(sourceChange);
3410 int destinationLast = destinationChild + (sourceLast - sourceFirst);
3411 QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
3412 destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
3413 d->changes.push(destinationChange);
3414
3415 emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, QPrivateSignal());
3416 d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
3417 return true;
3418}
3419
3420/*!
3421 Ends a column move operation.
3422
3423 When implementing a subclass, you must call this
3424 function \e after moving data within the model's underlying data
3425 store.
3426
3427 \sa beginMoveColumns()
3428
3429 \since 4.6
3430*/
3431void QAbstractItemModel::endMoveColumns()
3432{
3433 Q_D(QAbstractItemModel);
3434
3435 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
3436 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
3437
3438 QModelIndex adjustedSource = removeChange.parent;
3439 QModelIndex adjustedDestination = insertChange.parent;
3440
3441 const int numMoved = removeChange.last - removeChange.first + 1;
3442 if (insertChange.needsAdjust)
3443 adjustedDestination = createIndex(adjustedDestination.row(), adjustedDestination.column() - numMoved, adjustedDestination.internalPointer());
3444
3445 if (removeChange.needsAdjust)
3446 adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
3447
3448 d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
3449 emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, QPrivateSignal());
3450}
3451
3452/*!
3453 Begins a model reset operation.
3454
3455 A reset operation resets the model to its current state in any attached views.
3456
3457 \note Any views attached to this model will be reset as well.
3458
3459 When a model is reset it means that any previous data reported from the
3460 model is now invalid and has to be queried for again. This also means that
3461 the current item and any selected items will become invalid.
3462
3463 When a model radically changes its data it can sometimes be easier to just
3464 call this function rather than emit dataChanged() to inform other
3465 components when the underlying data source, or its structure, has changed.
3466
3467 You must call this function before resetting any internal data structures in your model
3468 or proxy model.
3469
3470 This function emits the signal modelAboutToBeReset().
3471
3472 \sa modelAboutToBeReset(), modelReset(), endResetModel()
3473 \since 4.6
3474*/
3475void QAbstractItemModel::beginResetModel()
3476{
3477 Q_D(QAbstractItemModel);
3478 if (d->resetting) {
3479 qWarning() << "beginResetModel called on" << this << "without calling endResetModel first";
3480 // Warn, but don't return early in case user code relies on the incorrect behavior.
3481 }
3482
3483 qCDebug(lcReset) << "beginResetModel called; about to emit modelAboutToBeReset";
3484 d->resetting = true;
3485 emit modelAboutToBeReset(QPrivateSignal());
3486}
3487
3488/*!
3489 Completes a model reset operation.
3490
3491 You must call this function after resetting any internal data structure in your model
3492 or proxy model.
3493
3494 This function emits the signal modelReset().
3495
3496 \sa beginResetModel()
3497 \since 4.6
3498*/
3499void QAbstractItemModel::endResetModel()
3500{
3501 Q_D(QAbstractItemModel);
3502 if (!d->resetting) {
3503 qWarning() << "endResetModel called on" << this << "without calling beginResetModel first";
3504 // Warn, but don't return early in case user code relies on the incorrect behavior.
3505 }
3506
3507 qCDebug(lcReset) << "endResetModel called; about to emit modelReset";
3508 d->invalidatePersistentIndexes();
3509 resetInternalData();
3510 d->resetting = false;
3511 emit modelReset(QPrivateSignal());
3512}
3513
3514/*!
3515 Changes the QPersistentModelIndex that is equal to the given \a from model
3516 index to the given \a to model index.
3517
3518 If no persistent model index equal to the given \a from model index was
3519 found, nothing is changed.
3520
3521 \sa persistentIndexList(), changePersistentIndexList()
3522*/
3523void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QModelIndex &to)
3524{
3525 Q_D(QAbstractItemModel);
3526 if (d->persistent.indexes.isEmpty())
3527 return;
3528 // find the data and reinsert it sorted
3529 const auto it = d->persistent.indexes.constFind(from);
3530 if (it != d->persistent.indexes.cend()) {
3531 QPersistentModelIndexData *data = *it;
3532 d->persistent.indexes.erase(it);
3533 data->index = to;
3534 if (to.isValid())
3535 d->persistent.insertMultiAtEnd(to, data);
3536 }
3537}
3538
3539/*!
3540 \since 4.1
3541
3542 Changes the {QPersistentModelIndex}es that are equal to the indexes in the
3543 given \a from model index list to the given \a to model index list.
3544
3545 If no persistent model indexes equal to the indexes in the given \a from
3546 model index list are found, nothing is changed.
3547
3548 \sa persistentIndexList(), changePersistentIndex()
3549*/
3550void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
3551 const QModelIndexList &to)
3552{
3553 Q_D(QAbstractItemModel);
3554 if (d->persistent.indexes.isEmpty())
3555 return;
3556 QList<QPersistentModelIndexData *> toBeReinserted;
3557 toBeReinserted.reserve(to.size());
3558 for (int i = 0; i < from.size(); ++i) {
3559 if (from.at(i) == to.at(i))
3560 continue;
3561 const auto it = d->persistent.indexes.constFind(from.at(i));
3562 if (it != d->persistent.indexes.cend()) {
3563 QPersistentModelIndexData *data = *it;
3564 d->persistent.indexes.erase(it);
3565 data->index = to.at(i);
3566 if (data->index.isValid())
3567 toBeReinserted << data;
3568 }
3569 }
3570
3571 for (auto *data : std::as_const(toBeReinserted))
3572 d->persistent.insertMultiAtEnd(data->index, data);
3573}
3574
3575/*!
3576 \since 4.2
3577
3578 Returns the list of indexes stored as persistent indexes in the model.
3579*/
3580QModelIndexList QAbstractItemModel::persistentIndexList() const
3581{
3582 Q_D(const QAbstractItemModel);
3583 QModelIndexList result;
3584 result.reserve(d->persistent.indexes.size());
3585 for (auto *data : std::as_const(d->persistent.indexes))
3586 result.append(data->index);
3587 return result;
3588}
3589
3590/*!
3591 \enum QAbstractItemModel::CheckIndexOption
3592 \since 5.11
3593
3594 This enum can be used to control the checks performed by
3595 QAbstractItemModel::checkIndex().
3596
3597 \value NoOption No check options are specified.
3598
3599 \value IndexIsValid The model index passed to
3600 QAbstractItemModel::checkIndex() is checked to be a valid model index.
3601
3602 \value DoNotUseParent Does not perform any check
3603 involving the usage of the parent of the index passed to
3604 QAbstractItemModel::checkIndex().
3605
3606 \value ParentIsInvalid The parent of the model index
3607 passed to QAbstractItemModel::checkIndex() is checked to be an invalid
3608 model index. If both this option and DoNotUseParent
3609 are specified, then this option is ignored.
3610*/
3611
3612/*!
3613 \since 5.11
3614
3615 This function checks whether \a index is a legal model index for
3616 this model. A legal model index is either an invalid model index, or a
3617 valid model index for which all the following holds:
3618
3619 \list
3620
3621 \li the index' model is \c{this};
3622 \li the index' row is greater or equal than zero;
3623 \li the index' row is less than the row count for the index' parent;
3624 \li the index' column is greater or equal than zero;
3625 \li the index' column is less than the column count for the index' parent.
3626
3627 \endlist
3628
3629 The \a options argument may change some of these checks. If \a options
3630 contains \c{IndexIsValid}, then \a index must be a valid
3631 index; this is useful when reimplementing functions such as \l{data()} or
3632 \l{setData()}, which expect valid indexes.
3633
3634 If \a options contains \c{DoNotUseParent}, then the
3635 checks that would call \l{parent()} are omitted; this allows calling this
3636 function from a \l{parent()} reimplementation (otherwise, this would result
3637 in endless recursion and a crash).
3638
3639 If \a options does not contain \c{DoNotUseParent}, and it
3640 contains \c{ParentIsInvalid}, then an additional check is
3641 performed: the parent index is checked for not being valid. This is useful
3642 when implementing flat models such as lists or tables, where no model index
3643 should have a valid parent index.
3644
3645 This function returns true if all the checks succeeded, and false otherwise.
3646 This allows to use the function in \l{Q_ASSERT} and similar other debugging
3647 mechanisms. If some check failed, a warning message will be printed in the
3648 \c{qt.core.qabstractitemmodel.checkindex} logging category, containing
3649 some information that may be useful for debugging the failure.
3650
3651 \note This function is a debugging helper for implementing your own item
3652 models. When developing complex models, as well as when building
3653 complicated model hierarchies (e.g. using proxy models), it is useful to
3654 call this function in order to catch bugs relative to illegal model indices
3655 (as defined above) accidentally passed to some QAbstractItemModel API.
3656
3657 \warning Note that it's undefined behavior to pass illegal indices to item
3658 models, so applications must refrain from doing so, and not rely on any
3659 "defensive" programming that item models could employ to handle illegal
3660 indexes gracefully.
3661
3662 \sa QModelIndex
3663*/
3664bool QAbstractItemModel::checkIndex(const QModelIndex &index, CheckIndexOptions options) const
3665{
3666 if (!index.isValid()) {
3667 if (options & CheckIndexOption::IndexIsValid) {
3668 qCWarning(lcCheckIndex) << "Index" << index << "is not valid (expected valid)";
3669 return false;
3670 }
3671 return true;
3672 }
3673
3674 if (index.model() != this) {
3675 qCWarning(lcCheckIndex) << "Index" << index
3676 << "is for model" << index.model()
3677 << "which is different from this model" << this;
3678 return false;
3679 }
3680
3681 if (index.row() < 0) {
3682 qCWarning(lcCheckIndex) << "Index" << index
3683 << "has negative row" << index.row();
3684 return false;
3685 }
3686
3687 if (index.column() < 0) {
3688 qCWarning(lcCheckIndex) << "Index" << index
3689 << "has negative column" << index.column();
3690 return false;
3691 }
3692
3693 if (!(options & CheckIndexOption::DoNotUseParent)) {
3694 const QModelIndex parentIndex = index.parent();
3695 if (options & CheckIndexOption::ParentIsInvalid) {
3696 if (parentIndex.isValid()) {
3697 qCWarning(lcCheckIndex) << "Index" << index
3698 << "has valid parent" << parentIndex
3699 << "(expected an invalid parent)";
3700 return false;
3701 }
3702 }
3703
3704 const int rc = rowCount(parentIndex);
3705 if (index.row() >= rc) {
3706 qCWarning(lcCheckIndex) << "Index" << index
3707 << "has out of range row" << index.row()
3708 << "rowCount() is" << rc;
3709 return false;
3710 }
3711
3712 const int cc = columnCount(parentIndex);
3713 if (index.column() >= cc) {
3714 qCWarning(lcCheckIndex) << "Index" << index
3715 << "has out of range column" << index.column()
3716 << "columnCount() is" << cc;
3717 return false;
3718
3719 }
3720 }
3721
3722 return true;
3723}
3724
3725/*!
3726 \since 6.0
3727
3728 Fills the \a roleDataSpan with the requested data for the given \a index.
3729
3730 The default implementation will call simply data() for each role in
3731 the span. A subclass can reimplement this function to provide data
3732 to views more efficiently:
3733
3734 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 15
3735
3736 In the snippet above, \c{index} is the same for the entire call.
3737 This means that accessing to the necessary data structures in order
3738 to retrieve the information for \c{index} can be done only once
3739 (hoisting the relevant code out of the loop).
3740
3741 The usage of QModelRoleData::setData(), or similarly
3742 QVariant::setValue(), is encouraged over constructing a QVariant
3743 separately and using a plain assignment operator; this is
3744 because the former allow to re-use the memory already allocated for
3745 the QVariant object stored inside a QModelRoleData, while the latter
3746 always allocates the new variant and then destroys the old one.
3747
3748 Note that views may call multiData() with spans that have been used
3749 in previous calls, and therefore may already contain some data.
3750 Therefore, it is imperative that if the model cannot return the
3751 data for a given role, then it must clear the data in the
3752 corresponding QModelRoleData object. This can be done by calling
3753 QModelRoleData::clearData(), or similarly by setting a default
3754 constructed QVariant, and so on. Failure to clear the data will
3755 result in the view believing that the "old" data is meant to be
3756 used for the corresponding role.
3757
3758 Finally, in order to avoid code duplication, a subclass may also
3759 decide to reimplement data() in terms of multiData(), by supplying
3760 a span of just one element:
3761
3762 \snippet code/src_corelib_kernel_qabstractitemmodel.cpp 16
3763
3764 \note Models are not allowed to modify the roles in the span, or
3765 to rearrange the span elements. Doing so results in undefined
3766 behavior.
3767
3768 \note It is illegal to pass an invalid model index to this function.
3769
3770 \sa QModelRoleDataSpan, data()
3771*/
3772void QAbstractItemModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const
3773{
3774 Q_ASSERT(checkIndex(index, CheckIndexOption::IndexIsValid));
3775
3776 for (QModelRoleData &d : roleDataSpan)
3777 d.setData(data(index, d.role()));
3778}
3779
3780/*!
3781 \class QAbstractTableModel
3782 \inmodule QtCore
3783 \brief The QAbstractTableModel class provides an abstract model that can be
3784 subclassed to create table models.
3785
3786 \ingroup model-view
3787
3788 QAbstractTableModel provides a standard interface for models that represent
3789 their data as a two-dimensional array of items. It is not used directly,
3790 but must be subclassed.
3791
3792 Since the model provides a more specialized interface than
3793 QAbstractItemModel, it is not suitable for use with tree views, although it
3794 can be used to provide data to a QListView. If you need to represent a
3795 simple list of items, and only need a model to contain a single column of
3796 data, subclassing the QAbstractListModel may be more appropriate.
3797
3798 The rowCount() and columnCount() functions return the dimensions of the
3799 table. To retrieve a model index corresponding to an item in the model, use
3800 index() and provide only the row and column numbers.
3801
3802 \section1 Subclassing
3803
3804 When subclassing QAbstractTableModel, you must implement rowCount(),
3805 columnCount(), and data(). Default implementations of the index() and
3806 parent() functions are provided by QAbstractTableModel.
3807 Well behaved models will also implement headerData().
3808
3809 Editable models need to implement setData(), and implement flags() to
3810 return a value containing
3811 \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
3812
3813 Models that provide interfaces to resizable data structures can
3814 provide implementations of insertRows(), removeRows(), insertColumns(),
3815 and removeColumns(). When implementing these functions, it is
3816 important to call the appropriate functions so that all connected views
3817 are aware of any changes:
3818
3819 \list
3820 \li An insertRows() implementation must call beginInsertRows()
3821 \e before inserting new rows into the data structure, and it must
3822 call endInsertRows() \e{immediately afterwards}.
3823 \li An insertColumns() implementation must call beginInsertColumns()
3824 \e before inserting new columns into the data structure, and it must
3825 call endInsertColumns() \e{immediately afterwards}.
3826 \li A removeRows() implementation must call beginRemoveRows()
3827 \e before the rows are removed from the data structure, and it must
3828 call endRemoveRows() \e{immediately afterwards}.
3829 \li A removeColumns() implementation must call beginRemoveColumns()
3830 \e before the columns are removed from the data structure, and it must
3831 call endRemoveColumns() \e{immediately afterwards}.
3832 \endlist
3833
3834 \note Some general guidelines for subclassing models are available in the
3835 \l{Model Subclassing Reference}.
3836
3837 \include models.qdocinc {thread-safety-section1}{QAbstractTableModel}
3838
3839 \sa {Model Classes}, QAbstractItemModel, QAbstractListModel
3840*/
3841
3842/*!
3843 Constructs an abstract table model for the given \a parent.
3844*/
3845
3846QAbstractTableModel::QAbstractTableModel(QObject *parent)
3847 : QAbstractItemModel(parent)
3848{
3849
3850}
3851
3852/*!
3853 \internal
3854
3855 Constructs an abstract table model with \a dd and the given \a parent.
3856*/
3857
3858QAbstractTableModel::QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent)
3859 : QAbstractItemModel(dd, parent)
3860{
3861
3862}
3863
3864/*!
3865 Destroys the abstract table model.
3866*/
3867
3868QAbstractTableModel::~QAbstractTableModel()
3869{
3870
3871}
3872
3873/*!
3874 \fn QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
3875
3876 Returns the index of the data in \a row and \a column with \a parent.
3877
3878 \sa parent()
3879*/
3880
3881QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent) const
3882{
3883 return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
3884}
3885
3886/*!
3887 \fn QModelIndex QAbstractTableModel::parent(const QModelIndex &index) const
3888
3889 Returns the parent of the model item with the given \a index.
3890
3891 \sa index(), hasChildren()
3892*/
3893
3894QModelIndex QAbstractTableModel::parent(const QModelIndex &) const
3895{
3896 return QModelIndex();
3897}
3898
3899/*!
3900 \reimp
3901*/
3902QModelIndex QAbstractTableModel::sibling(int row, int column, const QModelIndex &) const
3903{
3904 return index(row, column);
3905}
3906
3907bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
3908{
3909 if (!parent.isValid())
3910 return rowCount(parent) > 0 && columnCount(parent) > 0;
3911 return false;
3912}
3913
3914/*!
3915 \reimp
3916 */
3917Qt::ItemFlags QAbstractTableModel::flags(const QModelIndex &index) const
3918{
3919 Qt::ItemFlags f = QAbstractItemModel::flags(index);
3920 if (index.isValid())
3921 f |= Qt::ItemNeverHasChildren;
3922 return f;
3923}
3924
3925/*!
3926 \class QAbstractListModel
3927 \inmodule QtCore
3928 \brief The QAbstractListModel class provides an abstract model that can be
3929 subclassed to create one-dimensional list models.
3930
3931 \ingroup model-view
3932
3933 QAbstractListModel provides a standard interface for models that represent
3934 their data as a simple non-hierarchical sequence of items. It is not used
3935 directly, but must be subclassed.
3936
3937 Since the model provides a more specialized interface than
3938 QAbstractItemModel, it is not suitable for use with tree views; you will
3939 need to subclass QAbstractItemModel if you want to provide a model for
3940 that purpose. If you need to use a number of list models to manage data,
3941 it may be more appropriate to subclass QAbstractTableModel instead.
3942
3943 Simple models can be created by subclassing this class and implementing
3944 the minimum number of required functions. For example, we could implement
3945 a simple read-only QStringList-based model that provides a list of strings
3946 to a QListView widget. In such a case, we only need to implement the
3947 rowCount() function to return the number of items in the list, and the
3948 data() function to retrieve items from the list.
3949
3950 Since the model represents a one-dimensional structure, the rowCount()
3951 function returns the total number of items in the model. The columnCount()
3952 function is implemented for interoperability with all kinds of views, but
3953 by default informs views that the model contains only one column.
3954
3955 \section1 Subclassing
3956
3957 When subclassing QAbstractListModel, you must provide implementations
3958 of the rowCount() and data() functions. Well behaved models also provide
3959 a headerData() implementation.
3960
3961 If your model is used within QML and requires roles other than the
3962 default ones provided by the roleNames() function, you must override it.
3963
3964 For editable list models, you must also provide an implementation of
3965 setData(), and implement the flags() function so that it returns a value
3966 containing \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
3967
3968 Note that QAbstractListModel provides a default implementation of
3969 columnCount() that informs views that there is only a single column
3970 of items in this model.
3971
3972 Models that provide interfaces to resizable list-like data structures
3973 can provide implementations of insertRows() and removeRows(). When
3974 implementing these functions, it is important to call the appropriate
3975 functions so that all connected views are aware of any changes:
3976
3977 \list
3978 \li An insertRows() implementation must call beginInsertRows()
3979 \e before inserting new rows into the data structure, and it must
3980 call endInsertRows() \e{immediately afterwards}.
3981 \li A removeRows() implementation must call beginRemoveRows()
3982 \e before the rows are removed from the data structure, and it must
3983 call endRemoveRows() \e{immediately afterwards}.
3984 \endlist
3985
3986 \note Some general guidelines for subclassing models are available in the
3987 \l{Model Subclassing Reference}.
3988
3989 \sa {Model Classes}, {Model Subclassing Reference}, QAbstractItemView,
3990 QAbstractTableModel
3991*/
3992
3993/*!
3994 Constructs an abstract list model with the given \a parent.
3995*/
3996
3997QAbstractListModel::QAbstractListModel(QObject *parent)
3998 : QAbstractItemModel(parent)
3999{
4000
4001}
4002
4003/*!
4004 \internal
4005
4006 Constructs an abstract list model with \a dd and the given \a parent.
4007*/
4008
4009QAbstractListModel::QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent)
4010 : QAbstractItemModel(dd, parent)
4011{
4012
4013}
4014
4015/*!
4016 Destroys the abstract list model.
4017*/
4018
4019QAbstractListModel::~QAbstractListModel()
4020{
4021
4022}
4023
4024/*!
4025 \fn QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
4026
4027 Returns the index of the data in \a row and \a column with \a parent.
4028
4029 \sa parent()
4030*/
4031
4032QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent) const
4033{
4034 return hasIndex(row, column, parent) ? createIndex(row, column) : QModelIndex();
4035}
4036
4037/*!
4038 Returns the parent of the model item with the given \a index.
4039
4040 \sa index(), hasChildren()
4041*/
4042
4043QModelIndex QAbstractListModel::parent(const QModelIndex & /* index */) const
4044{
4045 return QModelIndex();
4046}
4047
4048/*!
4049 \reimp
4050*/
4051QModelIndex QAbstractListModel::sibling(int row, int column, const QModelIndex &) const
4052{
4053 return index(row, column);
4054}
4055
4056/*!
4057 \reimp
4058 */
4059Qt::ItemFlags QAbstractListModel::flags(const QModelIndex &index) const
4060{
4061 Qt::ItemFlags f = QAbstractItemModel::flags(index);
4062 if (index.isValid())
4063 f |= Qt::ItemNeverHasChildren;
4064 return f;
4065}
4066
4067/*!
4068 \internal
4069
4070 Returns the number of columns in the list with the given \a parent.
4071
4072 \sa rowCount()
4073*/
4074
4075int QAbstractListModel::columnCount(const QModelIndex &parent) const
4076{
4077 return parent.isValid() ? 0 : 1;
4078}
4079
4080bool QAbstractListModel::hasChildren(const QModelIndex &parent) const
4081{
4082 return parent.isValid() ? false : (rowCount() > 0);
4083}
4084
4085/*!
4086 \typedef QModelIndexList
4087 \relates QModelIndex
4088
4089 Synonym for QList<QModelIndex>.
4090*/
4091
4092bool QAbstractItemModelPrivate::dropOnItem(const QModelIndex &index, QDataStream &stream)
4093{
4094 Q_Q(QAbstractItemModel);
4095
4096 int top = INT_MAX;
4097 int left = INT_MAX;
4098 QList<int> rows, columns;
4099 QList<QMap<int, QVariant>> data;
4100
4101 while (!stream.atEnd()) {
4102 int r, c;
4103 QMap<int, QVariant> v;
4104 stream >> r >> c >> v;
4105 rows.append(r);
4106 columns.append(c);
4107 data.append(v);
4108 top = qMin(r, top);
4109 left = qMin(c, left);
4110 }
4111
4112 for (int i = 0; i < data.size(); ++i) {
4113 int r = (rows.at(i) - top) + index.row();
4114 int c = (columns.at(i) - left) + index.column();
4115 if (q->hasIndex(r, c))
4116 q->setItemData(q->index(r, c), data.at(i));
4117 }
4118
4119 return true;
4120}
4121
4122/*!
4123 \reimp
4124*/
4125bool QAbstractTableModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
4126 int row, int column, const QModelIndex &parent)
4127{
4128 Q_D(QAbstractItemModel);
4129 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
4130 return false;
4131
4132 QStringList types = mimeTypes();
4133 if (types.isEmpty())
4134 return false;
4135 QString format = types.at(0);
4136 if (!data->hasFormat(format))
4137 return false;
4138
4139 QByteArray encoded = data->data(format);
4140 QDataStream stream(&encoded, QDataStream::ReadOnly);
4141
4142 // if the drop is on an item, replace the data in the items
4143 if (parent.isValid() && row == -1 && column == -1)
4144 return d->dropOnItem(parent, stream);
4145
4146 if (row == -1)
4147 row = rowCount(parent);
4148
4149 // otherwise insert new rows for the data
4150 return decodeData(row, column, parent, stream);
4151}
4152
4153/*!
4154 \reimp
4155*/
4156bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
4157 int row, int column, const QModelIndex &parent)
4158{
4159 Q_D(QAbstractItemModel);
4160 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
4161 return false;
4162
4163 QStringList types = mimeTypes();
4164 if (types.isEmpty())
4165 return false;
4166 QString format = types.at(0);
4167 if (!data->hasFormat(format))
4168 return false;
4169
4170 QByteArray encoded = data->data(format);
4171 QDataStream stream(&encoded, QDataStream::ReadOnly);
4172
4173 // if the drop is on an item, replace the data in the items
4174 if (parent.isValid() && row == -1 && column == -1)
4175 return d->dropOnItem(parent, stream);
4176
4177 if (row == -1)
4178 row = rowCount(parent);
4179
4180 // otherwise insert new rows for the data
4181 return decodeData(row, column, parent, stream);
4182}
4183
4184/*!
4185 \fn QAbstractItemModel::modelAboutToBeReset()
4186 \since 4.2
4187
4188 This signal is emitted when beginResetModel() is called, before the model's internal
4189 state (e.g. persistent model indexes) has been invalidated.
4190
4191 \sa beginResetModel(), modelReset()
4192*/
4193
4194/*!
4195 \fn QAbstractItemModel::modelReset()
4196 \since 4.1
4197
4198 This signal is emitted when endResetModel() is called, after the
4199 model's internal state (e.g. persistent model indexes) has been invalidated.
4200
4201 Note that if a model is reset it should be considered that all information
4202 previously retrieved from it is invalid. This includes but is not limited
4203 to the rowCount() and columnCount(), flags(), data retrieved through data(),
4204 and roleNames().
4205
4206 \sa endResetModel(), modelAboutToBeReset()
4207*/
4208
4209/*!
4210 \fn bool QModelIndex::operator<(const QModelIndex &lhs, const QModelIndex &rhs)
4211 \since 4.1
4212
4213 Returns \c{true} if \a lhs model index is smaller than the \a rhs
4214 model index; otherwise returns \c{false}.
4215
4216 The less than calculation is not directly useful to developers - the way that indexes
4217 with different parents compare is not defined. This operator only exists so that the
4218 class can be used with QMap.
4219*/
4220
4221/*!
4222 \fn size_t qHash(const QPersistentModelIndex &key, size_t seed)
4223 \since 5.0
4224 \qhashold{QPersistentModelIndex}
4225*/
4226
4227
4228/*!
4229 \internal
4230 QMultiHash::insert inserts the value before the old value. and find() return the new value.
4231 We need insertMultiAtEnd because we don't want to overwrite the old one, which should be removed later
4232
4233 There should be only one instance QPersistentModelIndexData per index, but in some intermediate state there may be
4234 severals of PersistantModelIndex pointing to the same index, but one is already updated, and the other one is not.
4235 This make sure than when updating the first one we don't overwrite the second one in the hash, and the second one
4236 will be updated right later.
4237 */
4238void QAbstractItemModelPrivate::Persistent::insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data)
4239{
4240 auto newIt = indexes.insert(key, data);
4241 auto it = newIt;
4242 ++it;
4243 while (it != indexes.end() && it.key() == key) {
4244 qSwap(*newIt,*it);
4245 newIt = it;
4246 ++it;
4247 }
4248}
4249
4250QT_END_NAMESPACE
4251
4252#include "moc_qabstractitemmodel.cpp"
4253#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,...)