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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp