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