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

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