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