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