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