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