source: trunk/src/corelib/kernel/qabstractitemmodel.cpp@ 967

Last change on this file since 967 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 118.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
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
55QT_BEGIN_NAMESPACE
56
57QPersistentModelIndexData *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
74void 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
115QPersistentModelIndex::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
127QPersistentModelIndex::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
137QPersistentModelIndex::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
152QPersistentModelIndex::~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
168bool 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
185bool 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
206QPersistentModelIndex &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
222QPersistentModelIndex &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
241QPersistentModelIndex::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
259bool 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
273bool 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
286int 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
299int 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
315void *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
331qint64 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*/
344QModelIndex 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
358QModelIndex 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
372QModelIndex 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*/
385QVariant 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*/
397Qt::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*/
407const 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
426bool QPersistentModelIndex::isValid() const
427{
428 return d && d->index.isValid();
429}
430
431#ifndef QT_NO_DEBUG_STREAM
432QDebug 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
445QDebug 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
455class QEmptyItemModel : public QAbstractItemModel
456{
457public:
458 explicit QEmptyItemModel(QObject *parent = 0) : QAbstractItemModel(parent) {}
459 QModelIndex index(int, int, const QModelIndex &) const { return QModelIndex(); }
460 QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
461 int rowCount(const QModelIndex &) const { return 0; }
462 int columnCount(const QModelIndex &) const { return 0; }
463 bool hasChildren(const QModelIndex &) const { return false; }
464 QVariant data(const QModelIndex &, int) const { return QVariant(); }
465};
466
467Q_GLOBAL_STATIC(QEmptyItemModel, qEmptyModel)
468
469QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
470{
471 return qEmptyModel();
472}
473
474namespace {
475 struct DefaultRoleNames : public QHash<int, QByteArray>
476 {
477 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
488Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames)
489
490const QHash<int,QByteArray> &QAbstractItemModelPrivate::defaultRoleNames()
491{
492 return *qDefaultRoleNames();
493}
494
495
496static 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*/
526bool 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() < v2.toString();
536 }
537}
538
539void 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
564void 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
583void 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
602void 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*/
667void 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
695void 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
713void 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
743void 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
770void 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
788void 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
807void 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
838void 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 Constructs an abstract item model with the given \a parent.
1352*/
1353QAbstractItemModel::QAbstractItemModel(QObject *parent)
1354 : QObject(*new QAbstractItemModelPrivate, parent)
1355{
1356}
1357
1358/*!
1359 \internal
1360*/
1361QAbstractItemModel::QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent)
1362 : QObject(dd, parent)
1363{
1364}
1365
1366/*!
1367 Destroys the abstract item model.
1368*/
1369QAbstractItemModel::~QAbstractItemModel()
1370{
1371 d_func()->invalidatePersistentIndexes();
1372}
1373
1374/*!
1375 \fn QModelIndex QAbstractItemModel::sibling(int row, int column, const QModelIndex &index) const
1376
1377 Returns the sibling at \a row and \a column for the item at \a index, or an
1378 invalid QModelIndex if there is no sibling at that location.
1379
1380 sibling() is just a convenience function that finds the item's parent, and
1381 uses it to retrieve the index of the child item in the specified \a row and
1382 \a column.
1383
1384 \sa index(), QModelIndex::row(), QModelIndex::column()
1385*/
1386
1387
1388/*!
1389 \fn int QAbstractItemModel::rowCount(const QModelIndex &parent) const
1390
1391 Returns the number of rows under the given \a parent. When the parent is
1392 valid it means that rowCount is returning the number of children of parent.
1393
1394 \note When implementing a table based model, rowCount() should return 0
1395 when the parent is valid.
1396
1397 \sa columnCount()
1398*/
1399
1400/*!
1401 \fn int QAbstractItemModel::columnCount(const QModelIndex &parent) const
1402
1403 Returns the number of columns for the children of the given \a parent.
1404
1405 In most subclasses, the number of columns is independent of the \a parent.
1406
1407 For example:
1408
1409 \snippet examples/itemviews/simpledommodel/dommodel.cpp 2
1410
1411 \note When implementing a table based model, columnCount() should return 0
1412 when the parent is valid.
1413
1414 \sa rowCount()
1415*/
1416
1417/*!
1418 \fn void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
1419
1420 This signal is emitted whenever the data in an existing item changes.
1421
1422 If the items are of the same parent, the affected ones are those between
1423 \a topLeft and \a bottomRight inclusive. If the items do not have the same
1424 parent, the behavior is undefined.
1425
1426 When reimplementing the setData() function, this signal must be emitted
1427 explicitly.
1428
1429 \sa headerDataChanged(), setData(), layoutChanged()
1430*/
1431
1432/*!
1433 \fn void QAbstractItemModel::rowsInserted(const QModelIndex &parent, int start, int end)
1434
1435 This signal is emitted after rows have been inserted into the
1436 model. The new items are those between \a start and \a end
1437 inclusive, under the given \a parent item.
1438
1439 \note Components connected to this signal use it to adapt to changes in the
1440 model's dimensions. It can only be emitted by the QAbstractItemModel
1441 implementation, and cannot be explicitly emitted in subclass code.
1442
1443 \sa insertRows(), beginInsertRows()
1444*/
1445
1446/*!
1447 \fn void QAbstractItemModel::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
1448
1449 This signal is emitted just before rows are inserted into the model. The
1450 new items will be positioned between \a start and \a end inclusive, under
1451 the given \a parent item.
1452
1453 \note Components connected to this signal use it to adapt to changes
1454 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1455 implementation, and cannot be explicitly emitted in subclass code.
1456
1457 \sa insertRows(), beginInsertRows()
1458*/
1459
1460/*!
1461 \fn void QAbstractItemModel::rowsRemoved(const QModelIndex &parent, int start, int end)
1462
1463 This signal is emitted after rows have been removed from the model. The
1464 removed items are those between \a start and \a end inclusive, under the
1465 given \a parent item.
1466
1467 \note Components connected to this signal use it to adapt to changes
1468 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1469 implementation, and cannot be explicitly emitted in subclass code.
1470
1471 \sa removeRows(), beginRemoveRows()
1472*/
1473
1474/*!
1475 \fn void QAbstractItemModel::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
1476
1477 This signal is emitted just before rows are removed from the model. The
1478 items that will be removed are those between \a start and \a end inclusive,
1479 under the given \a parent item.
1480
1481 \note Components connected to this signal use it to adapt to changes
1482 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1483 implementation, and cannot be explicitly emitted in subclass code.
1484
1485 \sa removeRows(), beginRemoveRows()
1486*/
1487
1488/*!
1489 \fn void QAbstractItemModel::rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
1490 \since 4.6
1491
1492 This signal is emitted after rows have been moved within the
1493 model. The items between \a sourceStart and \a sourceEnd
1494 inclusive, under the given \a sourceParent item have been moved to \a destinationParent
1495 starting at the row \a destinationRow.
1496
1497 \bold{Note:} Components connected to this signal use it to adapt to changes
1498 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1499 implementation, and cannot be explicitly emitted in subclass code.
1500
1501 \sa beginMoveRows()
1502*/
1503
1504/*!
1505 \fn void QAbstractItemModel::rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
1506 \since 4.6
1507
1508 This signal is emitted just before rows are moved within the
1509 model. The items that will be moved are those between \a sourceStart and \a sourceEnd
1510 inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
1511 starting at the row \a destinationRow.
1512
1513 \bold{Note:} Components connected to this signal use it to adapt to changes
1514 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1515 implementation, and cannot be explicitly emitted in subclass code.
1516
1517 \sa beginMoveRows()
1518*/
1519
1520/*!
1521 \fn void QAbstractItemModel::columnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
1522 \since 4.6
1523
1524 This signal is emitted after columns have been moved within the
1525 model. The items between \a sourceStart and \a sourceEnd
1526 inclusive, under the given \a sourceParent item have been moved to \a destinationParent
1527 starting at the column \a destinationColumn.
1528
1529 \bold{Note:} Components connected to this signal use it to adapt to changes
1530 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1531 implementation, and cannot be explicitly emitted in subclass code.
1532
1533 \sa beginMoveRows()
1534*/
1535
1536/*!
1537 \fn void QAbstractItemModel::columnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
1538 \since 4.6
1539
1540 This signal is emitted just before columns are moved within the
1541 model. The items that will be moved are those between \a sourceStart and \a sourceEnd
1542 inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
1543 starting at the column \a destinationColumn.
1544
1545 \bold{Note:} Components connected to this signal use it to adapt to changes
1546 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1547 implementation, and cannot be explicitly emitted in subclass code.
1548
1549 \sa beginMoveRows()
1550*/
1551
1552/*!
1553 \fn void QAbstractItemModel::columnsInserted(const QModelIndex &parent, int start, int end)
1554
1555 This signal is emitted after columns have been inserted into the model. The
1556 new items are those between \a start and \a end inclusive, under the given
1557 \a parent item.
1558
1559 \note Components connected to this signal use it to adapt to changes in the
1560 model's dimensions. It can only be emitted by the QAbstractItemModel
1561 implementation, and cannot be explicitly emitted in subclass code.
1562
1563 \sa insertColumns(), beginInsertColumns()
1564*/
1565
1566/*!
1567 \fn void QAbstractItemModel::columnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
1568
1569 This signal is emitted just before columns are inserted into the model. The
1570 new items will be positioned between \a start and \a end inclusive, under
1571 the given \a parent item.
1572
1573 \note Components connected to this signal use it to adapt to changes in the
1574 model's dimensions. It can only be emitted by the QAbstractItemModel
1575 implementation, and cannot be explicitly emitted in subclass code.
1576
1577 \sa insertColumns(), beginInsertColumns()
1578*/
1579
1580/*!
1581 \fn void QAbstractItemModel::columnsRemoved(const QModelIndex &parent, int start, int end)
1582
1583 This signal is emitted after columns have been removed from the model.
1584 The removed items are those between \a start and \a end inclusive,
1585 under the given \a parent item.
1586
1587 \note Components connected to this signal use it to adapt to changes in
1588 the model's dimensions. It can only be emitted by the QAbstractItemModel
1589 implementation, and cannot be explicitly emitted in subclass code.
1590
1591 \sa removeColumns(), beginRemoveColumns()
1592*/
1593
1594/*!
1595 \fn void QAbstractItemModel::columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
1596
1597 This signal is emitted just before columns are removed from the model. The
1598 items to be removed are those between \a start and \a end inclusive, under
1599 the given \a parent item.
1600
1601 \note Components connected to this signal use it to adapt to changes in the
1602 model's dimensions. It can only be emitted by the QAbstractItemModel
1603 implementation, and cannot be explicitly emitted in subclass code.
1604
1605 \sa removeColumns(), beginRemoveColumns()
1606*/
1607
1608/*!
1609 Returns true if the model returns a valid QModelIndex for \a row and
1610 \a column with \a parent, otherwise returns false.
1611*/
1612bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const
1613{
1614 if (row < 0 || column < 0)
1615 return false;
1616 return row < rowCount(parent) && column < columnCount(parent);
1617}
1618
1619
1620/*!
1621 Returns true if \a parent has any children; otherwise returns false.
1622
1623 Use rowCount() on the parent to find out the number of children.
1624
1625 \sa parent() index()
1626*/
1627bool QAbstractItemModel::hasChildren(const QModelIndex &parent) const
1628{
1629 return (rowCount(parent) > 0) && (columnCount(parent) > 0);
1630}
1631
1632
1633/*!
1634 Returns a map with values for all predefined roles in the model for the
1635 item at the given \a index.
1636
1637 Reimplement this function if you want to extend the default behavior of
1638 this function to include custom roles in the map.
1639
1640 \sa Qt::ItemDataRole, data()
1641*/
1642QMap<int, QVariant> QAbstractItemModel::itemData(const QModelIndex &index) const
1643{
1644 QMap<int, QVariant> roles;
1645 for (int i = 0; i < Qt::UserRole; ++i) {
1646 QVariant variantData = data(index, i);
1647 if (variantData.isValid())
1648 roles.insert(i, variantData);
1649 }
1650 return roles;
1651}
1652
1653/*!
1654 Sets the \a role data for the item at \a index to \a value.
1655
1656 Returns true if successful; otherwise returns false.
1657
1658 The dataChanged() signal should be emitted if the data was successfully
1659 set.
1660
1661 The base class implementation returns false. This function and data() must
1662 be reimplemented for editable models.
1663
1664 \sa Qt::ItemDataRole, data(), itemData()
1665*/
1666bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
1667{
1668 Q_UNUSED(index);
1669 Q_UNUSED(value);
1670 Q_UNUSED(role);
1671 return false;
1672}
1673
1674/*!
1675 \fn QVariant QAbstractItemModel::data(const QModelIndex &index, int role) const = 0
1676
1677 Returns the data stored under the given \a role for the item referred to
1678 by the \a index.
1679
1680 \note If you do not have a value to return, return an \bold invalid
1681 QVariant instead of returning 0.
1682
1683 \sa Qt::ItemDataRole, setData(), headerData()
1684*/
1685
1686/*!
1687 Sets the role data for the item at \a index to the associated value in
1688 \a roles, for every Qt::ItemDataRole.
1689
1690 Returns true if successful; otherwise returns false.
1691
1692 Roles that are not in \a roles will not be modified.
1693
1694 \sa setData() data() itemData()
1695*/
1696bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
1697{
1698 bool b = true;
1699 for (QMap<int, QVariant>::ConstIterator it = roles.begin(); it != roles.end(); ++it)
1700 b = b && setData(index, it.value(), it.key());
1701 return b;
1702}
1703
1704/*!
1705 Returns a list of MIME types that can be used to describe a list of model
1706 indexes.
1707
1708 \sa mimeData()
1709*/
1710QStringList QAbstractItemModel::mimeTypes() const
1711{
1712 QStringList types;
1713 types << QLatin1String("application/x-qabstractitemmodeldatalist");
1714 return types;
1715}
1716
1717/*!
1718 Returns an object that contains serialized items of data corresponding to
1719 the list of \a indexes specified. The formats used to describe the encoded
1720 data is obtained from the mimeTypes() function.
1721
1722 If the list of indexes is empty, or there are no supported MIME types, 0 is
1723 returned rather than a serialized empty list.
1724
1725 \sa mimeTypes(), dropMimeData()
1726*/
1727QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
1728{
1729 if (indexes.count() <= 0)
1730 return 0;
1731 QStringList types = mimeTypes();
1732 if (types.isEmpty())
1733 return 0;
1734 QMimeData *data = new QMimeData();
1735 QString format = types.at(0);
1736 QByteArray encoded;
1737 QDataStream stream(&encoded, QIODevice::WriteOnly);
1738 encodeData(indexes, stream);
1739 data->setData(format, encoded);
1740 return data;
1741}
1742
1743/*!
1744 Handles the \a data supplied by a drag and drop operation that ended with
1745 the given \a action.
1746
1747 Returns true if the data and action can be handled by the model; otherwise
1748 returns false.
1749
1750 Although the specified \a row, \a column and \a parent indicate the
1751 location of an item in the model where the operation ended, it is the
1752 responsibility of the view to provide a suitable location for where the
1753 data should be inserted.
1754
1755 For instance, a drop action on an item in a QTreeView can result in new
1756 items either being inserted as children of the item specified by \a row,
1757 \a column, and \a parent, or as siblings of the item.
1758
1759 When row and column are -1 it means that it is up to the model to decide
1760 where to place the data. This can occur in a tree when data is dropped on
1761 a parent. Models will usually append the data to the parent in this case.
1762
1763 \sa supportedDropActions(), {Using drag and drop with item views}
1764*/
1765bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
1766 int row, int column, const QModelIndex &parent)
1767{
1768 // check if the action is supported
1769 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
1770 return false;
1771 // check if the format is supported
1772 QStringList types = mimeTypes();
1773 if (types.isEmpty())
1774 return false;
1775 QString format = types.at(0);
1776 if (!data->hasFormat(format))
1777 return false;
1778 if (row > rowCount(parent))
1779 row = rowCount(parent);
1780 if (row == -1)
1781 row = rowCount(parent);
1782 if (column == -1)
1783 column = 0;
1784 // decode and insert
1785 QByteArray encoded = data->data(format);
1786 QDataStream stream(&encoded, QIODevice::ReadOnly);
1787 return decodeData(row, column, parent, stream);
1788}
1789
1790/*!
1791 \since 4.2
1792
1793 Returns the drop actions supported by this model.
1794
1795 The default implementation returns Qt::CopyAction. Reimplement this
1796 function if you wish to support additional actions. You must also
1797 reimplement the dropMimeData() function to handle the additional
1798 operations.
1799
1800 \sa dropMimeData(), Qt::DropActions, {Using drag and drop with item
1801 views}
1802*/
1803Qt::DropActions QAbstractItemModel::supportedDropActions() const
1804{
1805 return Qt::CopyAction;
1806}
1807
1808/*!
1809 Returns the actions supported by the data in this model.
1810
1811 The default implementation returns supportedDropActions() unless specific
1812 values have been set with setSupportedDragActions().
1813
1814 supportedDragActions() is used by QAbstractItemView::startDrag() as the
1815 default values when a drag occurs.
1816
1817 \sa Qt::DropActions, {Using drag and drop with item views}
1818*/
1819Qt::DropActions QAbstractItemModel::supportedDragActions() const
1820{
1821 // ### Qt 5: make this virtual or these properties
1822 Q_D(const QAbstractItemModel);
1823 if (d->supportedDragActions != -1)
1824 return d->supportedDragActions;
1825 return supportedDropActions();
1826}
1827
1828/*!
1829 \since 4.2
1830
1831 Sets the supported drag \a actions for the items in the model.
1832
1833 \sa supportedDragActions(), {Using drag and drop with item views}
1834*/
1835void QAbstractItemModel::setSupportedDragActions(Qt::DropActions actions)
1836{
1837 Q_D(QAbstractItemModel);
1838 d->supportedDragActions = actions;
1839}
1840
1841/*!
1842 \note The base class implementation of this function does nothing and
1843 returns false.
1844
1845 On models that support this, inserts \a count rows into the model before
1846 the given \a row. Items in the new row will be children of the item
1847 represented by the \a parent model index.
1848
1849 If \a row is 0, the rows are prepended to any existing rows in the parent.
1850
1851 If \a row is rowCount(), the rows are appended to any existing rows in the
1852 parent.
1853
1854 If \a parent has no children, a single column with \a count rows is
1855 inserted.
1856
1857 Returns true if the rows were successfully inserted; otherwise returns
1858 false.
1859
1860 If you implement your own model, you can reimplement this function if you
1861 want to support insertions. Alternatively, you can provide your own API for
1862 altering the data. In either case, you will need to call
1863 beginInsertRows() and endInsertRows() to notify other components that the
1864 model has changed.
1865
1866 \sa insertColumns(), removeRows(), beginInsertRows(), endInsertRows()
1867*/
1868bool QAbstractItemModel::insertRows(int, int, const QModelIndex &)
1869{
1870 return false;
1871}
1872
1873/*!
1874 On models that support this, inserts \a count new columns into the model
1875 before the given \a column. The items in each new column will be children
1876 of the item represented by the \a parent model index.
1877
1878 If \a column is 0, the columns are prepended to any existing columns.
1879
1880 If \a column is columnCount(), the columns are appended to any existing
1881 columns.
1882
1883 If \a parent has no children, a single row with \a count columns is
1884 inserted.
1885
1886 Returns true if the columns were successfully inserted; otherwise returns
1887 false.
1888
1889 The base class implementation does nothing and returns false.
1890
1891 If you implement your own model, you can reimplement this function if you
1892 want to support insertions. Alternatively, you can provide your own API for
1893 altering the data.
1894
1895 \sa insertRows(), removeColumns(), beginInsertColumns(), endInsertColumns()
1896*/
1897bool QAbstractItemModel::insertColumns(int, int, const QModelIndex &)
1898{
1899 return false;
1900}
1901
1902/*!
1903 On models that support this, removes \a count rows starting with the given
1904 \a row under parent \a parent from the model.
1905
1906 Returns true if the rows were successfully removed; otherwise returns
1907 false.
1908
1909 The base class implementation does nothing and returns false.
1910
1911 If you implement your own model, you can reimplement this function if you
1912 want to support removing. Alternatively, you can provide your own API for
1913 altering the data.
1914
1915 \sa removeRow(), removeColumns(), insertColumns(), beginRemoveRows(),
1916 endRemoveRows()
1917*/
1918bool QAbstractItemModel::removeRows(int, int, const QModelIndex &)
1919{
1920 return false;
1921}
1922
1923/*!
1924 On models that support this, removes \a count columns starting with the
1925 given \a column under parent \a parent from the model.
1926
1927 Returns true if the columns 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 removeColumn(), removeRows(), insertColumns(), beginRemoveColumns(),
1937 endRemoveColumns()
1938*/
1939bool QAbstractItemModel::removeColumns(int, int, const QModelIndex &)
1940{
1941 return false;
1942}
1943
1944/*!
1945 Fetches any available data for the items with the parent specified by the
1946 \a parent index.
1947
1948 Reimplement this if you are populating your model incrementally.
1949
1950 The default implementation does nothing.
1951
1952 \sa canFetchMore()
1953*/
1954void QAbstractItemModel::fetchMore(const QModelIndex &)
1955{
1956 // do nothing
1957}
1958
1959/*!
1960 Returns true if there is more data available for \a parent; otherwise
1961 returns false.
1962
1963 The default implementation always returns false.
1964
1965 If canFetchMore() returns true, QAbstractItemView will call fetchMore().
1966 However, the fetchMore() function is only called when the model is being
1967 populated incrementally.
1968
1969 \sa fetchMore()
1970*/
1971bool QAbstractItemModel::canFetchMore(const QModelIndex &) const
1972{
1973 return false;
1974}
1975
1976/*!
1977 Returns the item flags for the given \a index.
1978
1979 The base class implementation returns a combination of flags that enables
1980 the item (\c ItemIsEnabled) and allows it to be selected
1981 (\c ItemIsSelectable).
1982
1983 \sa Qt::ItemFlags
1984*/
1985Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const
1986{
1987 Q_D(const QAbstractItemModel);
1988 if (!d->indexValid(index))
1989 return 0;
1990
1991 return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
1992}
1993
1994/*!
1995 Sorts the model by \a column in the given \a order.
1996
1997 The base class implementation does nothing.
1998*/
1999void QAbstractItemModel::sort(int column, Qt::SortOrder order)
2000{
2001 Q_UNUSED(column);
2002 Q_UNUSED(order);
2003 // do nothing
2004}
2005
2006/*!
2007 Returns a model index for the buddy of the item represented by \a index.
2008 When the user wants to edit an item, the view will call this function to
2009 check whether another item in the model should be edited instead. Then, the
2010 view will construct a delegate using the model index returned by the buddy
2011 item.
2012
2013 The default implementation of this function has each item as its own buddy.
2014*/
2015QModelIndex QAbstractItemModel::buddy(const QModelIndex &index) const
2016{
2017 return index;
2018}
2019
2020/*!
2021 Returns a list of indexes for the items in the column of the \a start index
2022 where data stored under the given \a role matches the specified \a value.
2023 The way the search is performed is defined by the \a flags given. The list
2024 that is returned may be empty.
2025
2026 The search begins from the \a start index, and continues until the number
2027 of matching data items equals \a hits, the search reaches the last row, or
2028 the search reaches \a start again - depending on whether \c MatchWrap is
2029 specified in \a flags. If you want to search for all matching items, use
2030 \a hits = -1.
2031
2032 By default, this function will perform a wrapping, string-based comparison
2033 on all items, searching for items that begin with the search term specified
2034 by \a value.
2035
2036 \note The default implementation of this function only searches columns.
2037 Reimplement this function to include a different search behavior.
2038*/
2039QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
2040 const QVariant &value, int hits,
2041 Qt::MatchFlags flags) const
2042{
2043 QModelIndexList result;
2044 uint matchType = flags & 0x0F;
2045 Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
2046 bool recurse = flags & Qt::MatchRecursive;
2047 bool wrap = flags & Qt::MatchWrap;
2048 bool allHits = (hits == -1);
2049 QString text; // only convert to a string if it is needed
2050 QModelIndex p = parent(start);
2051 int from = start.row();
2052 int to = rowCount(p);
2053
2054 // iterates twice if wrapping
2055 for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
2056 for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) {
2057 QModelIndex idx = index(r, start.column(), p);
2058 if (!idx.isValid())
2059 continue;
2060 QVariant v = data(idx, role);
2061 // QVariant based matching
2062 if (matchType == Qt::MatchExactly) {
2063 if (value == v)
2064 result.append(idx);
2065 } else { // QString based matching
2066 if (text.isEmpty()) // lazy conversion
2067 text = value.toString();
2068 QString t = v.toString();
2069 switch (matchType) {
2070 case Qt::MatchRegExp:
2071 if (QRegExp(text, cs).exactMatch(t))
2072 result.append(idx);
2073 break;
2074 case Qt::MatchWildcard:
2075 if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t))
2076 result.append(idx);
2077 break;
2078 case Qt::MatchStartsWith:
2079 if (t.startsWith(text, cs))
2080 result.append(idx);
2081 break;
2082 case Qt::MatchEndsWith:
2083 if (t.endsWith(text, cs))
2084 result.append(idx);
2085 break;
2086 case Qt::MatchFixedString:
2087 if (t.compare(text, cs) == 0)
2088 result.append(idx);
2089 break;
2090 case Qt::MatchContains:
2091 default:
2092 if (t.contains(text, cs))
2093 result.append(idx);
2094 }
2095 }
2096 if (recurse && hasChildren(idx)) { // search the hierarchy
2097 result += match(index(0, idx.column(), idx), role,
2098 (text.isEmpty() ? value : text),
2099 (allHits ? -1 : hits - result.count()), flags);
2100 }
2101 }
2102 // prepare for the next iteration
2103 from = 0;
2104 to = start.row();
2105 }
2106 return result;
2107}
2108
2109/*!
2110 Returns the row and column span of the item represented by \a index.
2111
2112 \note Currently, span is not used.
2113*/
2114
2115QSize QAbstractItemModel::span(const QModelIndex &) const
2116{
2117 return QSize(1, 1);
2118}
2119
2120/*!
2121 \since 4.6
2122
2123 Sets the model's role names to \a roleNames.
2124
2125 This function allows mapping of role identifiers to role property names in
2126 Declarative UI. This function must be called before the model is used.
2127 Modifying the role names after the model has been set may result in
2128 undefined behaviour.
2129
2130 \sa roleNames()
2131*/
2132void QAbstractItemModel::setRoleNames(const QHash<int,QByteArray> &roleNames)
2133{
2134 Q_D(QAbstractItemModel);
2135 d->roleNames = roleNames;
2136}
2137
2138/*!
2139 \since 4.6
2140
2141 Returns the model's role names.
2142
2143 \sa setRoleNames()
2144*/
2145const QHash<int,QByteArray> &QAbstractItemModel::roleNames() const
2146{
2147 Q_D(const QAbstractItemModel);
2148 return d->roleNames;
2149}
2150
2151/*!
2152 Lets the model know that it should submit cached information to permanent
2153 storage. This function is typically used for row editing.
2154
2155 Returns true if there is no error; otherwise returns false.
2156
2157 \sa revert()
2158*/
2159
2160bool QAbstractItemModel::submit()
2161{
2162 return true;
2163}
2164
2165/*!
2166 Lets the model know that it should discard cached information. This
2167 function is typically used for row editing.
2168
2169 \sa submit()
2170*/
2171
2172void QAbstractItemModel::revert()
2173{
2174 // do nothing
2175}
2176
2177/*!
2178 Returns the data for the given \a role and \a section in the header with
2179 the specified \a orientation.
2180
2181 For horizontal headers, the section number corresponds to the column
2182 number. Similarly, for vertical headers, the section number corresponds to
2183 the row number.
2184
2185 \sa Qt::ItemDataRole, setHeaderData(), QHeaderView
2186*/
2187
2188QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const
2189{
2190 Q_UNUSED(orientation);
2191 if (role == Qt::DisplayRole)
2192 return section + 1;
2193 return QVariant();
2194}
2195
2196/*!
2197 Sets the data for the given \a role and \a section in the header with the
2198 specified \a orientation to the \a value supplied.
2199
2200 Returns true if the header's data was updated; otherwise returns false.
2201
2202 When reimplementing this function, the headerDataChanged() signal must be
2203 emitted explicitly.
2204
2205 \sa Qt::ItemDataRole, headerData()
2206*/
2207
2208bool QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation,
2209 const QVariant &value, int role)
2210{
2211 Q_UNUSED(section);
2212 Q_UNUSED(orientation);
2213 Q_UNUSED(value);
2214 Q_UNUSED(role);
2215 return false;
2216}
2217
2218/*!
2219 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, void *ptr) const
2220
2221 Creates a model index for the given \a row and \a column with the internal
2222 pointer \a ptr.
2223
2224 When using a QSortFilterProxyModel, its indexes have their own internal
2225 pointer. It is not advisable to access this internal pointer outside of the
2226 model. Use the data() function instead.
2227
2228 This function provides a consistent interface that model subclasses must
2229 use to create model indexes.
2230*/
2231
2232/*!
2233 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, int id) const
2234 \obsolete
2235
2236 Use QModelIndex
2237 QAbstractItemModel::createIndex(int row, int column, quint32 id) instead.
2238*/
2239
2240/*!
2241 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, quint32 id) const
2242
2243 Creates a model index for the given \a row and \a column with the internal
2244 identifier, \a id.
2245
2246 This function provides a consistent interface that model subclasses must
2247 use to create model indexes.
2248
2249 \sa QModelIndex::internalId()
2250*/
2251
2252/*!
2253 \internal
2254*/
2255void QAbstractItemModel::encodeData(const QModelIndexList &indexes, QDataStream &stream) const
2256{
2257 QModelIndexList::ConstIterator it = indexes.begin();
2258 for (; it != indexes.end(); ++it)
2259 stream << (*it).row() << (*it).column() << itemData(*it);
2260}
2261
2262/*!
2263 \internal
2264 */
2265bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &parent,
2266 QDataStream &stream)
2267{
2268 int top = INT_MAX;
2269 int left = INT_MAX;
2270 int bottom = 0;
2271 int right = 0;
2272 QVector<int> rows, columns;
2273 QVector<QMap<int, QVariant> > data;
2274
2275 while (!stream.atEnd()) {
2276 int r, c;
2277 QMap<int, QVariant> v;
2278 stream >> r >> c >> v;
2279 rows.append(r);
2280 columns.append(c);
2281 data.append(v);
2282 top = qMin(r, top);
2283 left = qMin(c, left);
2284 bottom = qMax(r, bottom);
2285 right = qMax(c, right);
2286 }
2287
2288 // insert the dragged items into the table, use a bit array to avoid overwriting items,
2289 // since items from different tables can have the same row and column
2290 int dragRowCount = 0;
2291 int dragColumnCount = right - left + 1;
2292
2293 // Compute the number of continuous rows upon insertion and modify the rows to match
2294 QVector<int> rowsToInsert(bottom + 1);
2295 for (int i = 0; i < rows.count(); ++i)
2296 rowsToInsert[rows.at(i)] = 1;
2297 for (int i = 0; i < rowsToInsert.count(); ++i) {
2298 if (rowsToInsert[i] == 1){
2299 rowsToInsert[i] = dragRowCount;
2300 ++dragRowCount;
2301 }
2302 }
2303 for (int i = 0; i < rows.count(); ++i)
2304 rows[i] = top + rowsToInsert[rows[i]];
2305
2306 QBitArray isWrittenTo(dragRowCount * dragColumnCount);
2307
2308 // make space in the table for the dropped data
2309 int colCount = columnCount(parent);
2310 if (colCount == 0) {
2311 insertColumns(colCount, dragColumnCount - colCount, parent);
2312 colCount = columnCount(parent);
2313 }
2314 insertRows(row, dragRowCount, parent);
2315
2316 row = qMax(0, row);
2317 column = qMax(0, column);
2318
2319 QVector<QPersistentModelIndex> newIndexes(data.size());
2320 // set the data in the table
2321 for (int j = 0; j < data.size(); ++j) {
2322 int relativeRow = rows.at(j) - top;
2323 int relativeColumn = columns.at(j) - left;
2324 int destinationRow = relativeRow + row;
2325 int destinationColumn = relativeColumn + column;
2326 int flat = (relativeRow * dragColumnCount) + relativeColumn;
2327 // if the item was already written to, or we just can't fit it in the table, create a new row
2328 if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) {
2329 destinationColumn = qBound(column, destinationColumn, colCount - 1);
2330 destinationRow = row + dragRowCount;
2331 insertRows(row + dragRowCount, 1, parent);
2332 flat = (dragRowCount * dragColumnCount) + relativeColumn;
2333 isWrittenTo.resize(++dragRowCount * dragColumnCount);
2334 }
2335 if (!isWrittenTo.testBit(flat)) {
2336 newIndexes[j] = index(destinationRow, destinationColumn, parent);
2337 isWrittenTo.setBit(flat);
2338 }
2339 }
2340
2341 for(int k = 0; k < newIndexes.size(); k++) {
2342 if (newIndexes.at(k).isValid())
2343 setItemData(newIndexes.at(k), data.at(k));
2344 }
2345
2346 return true;
2347}
2348
2349/*!
2350 Begins a row insertion operation.
2351
2352 When reimplementing insertRows() in a subclass, you must call this function
2353 \e before inserting data into the model's underlying data store.
2354
2355 The \a parent index corresponds to the parent into which the new rows are
2356 inserted; \a first and \a last are the row numbers that the new rows will
2357 have after they have been inserted.
2358
2359 \table 80%
2360 \row
2361 \o \inlineimage modelview-begin-insert-rows.png Inserting rows
2362 \o Specify the first and last row numbers for the span of rows you
2363 want to insert into an item in a model.
2364
2365 For example, as shown in the diagram, we insert three rows before
2366 row 2, so \a first is 2 and \a last is 4:
2367
2368 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 0
2369
2370 This inserts the three new rows as rows 2, 3, and 4.
2371 \row
2372 \o \inlineimage modelview-begin-append-rows.png Appending rows
2373 \o To append rows, insert them after the last row.
2374
2375 For example, as shown in the diagram, we append two rows to a
2376 collection of 4 existing rows (ending in row 3), so \a first is 4
2377 and \a last is 5:
2378
2379 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 1
2380
2381 This appends the two new rows as rows 4 and 5.
2382 \endtable
2383
2384 \note This function emits the rowsAboutToBeInserted() signal which
2385 connected views (or proxies) must handle before the data is inserted.
2386 Otherwise, the views may end up in an invalid state.
2387 \sa endInsertRows()
2388*/
2389void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
2390{
2391 Q_ASSERT(first >= 0);
2392 Q_ASSERT(last >= first);
2393 Q_D(QAbstractItemModel);
2394 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2395 emit rowsAboutToBeInserted(parent, first, last);
2396 d->rowsAboutToBeInserted(parent, first, last);
2397}
2398
2399/*!
2400 Ends a row insertion operation.
2401
2402 When reimplementing insertRows() in a subclass, you must call this function
2403 \e after inserting data into the model's underlying data store.
2404
2405 \sa beginInsertRows()
2406*/
2407void QAbstractItemModel::endInsertRows()
2408{
2409 Q_D(QAbstractItemModel);
2410 QAbstractItemModelPrivate::Change change = d->changes.pop();
2411 d->rowsInserted(change.parent, change.first, change.last);
2412 emit rowsInserted(change.parent, change.first, change.last);
2413}
2414
2415/*!
2416 Begins a row removal operation.
2417
2418 When reimplementing removeRows() in a subclass, you must call this
2419 function \e before removing data from the model's underlying data store.
2420
2421 The \a parent index corresponds to the parent from which the new rows are
2422 removed; \a first and \a last are the row numbers of the rows to be
2423 removed.
2424
2425 \table 80%
2426 \row
2427 \o \inlineimage modelview-begin-remove-rows.png Removing rows
2428 \o Specify the first and last row numbers for the span of rows you
2429 want to remove from an item in a model.
2430
2431 For example, as shown in the diagram, we remove the two rows from
2432 row 2 to row 3, so \a first is 2 and \a last is 3:
2433
2434 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 2
2435 \endtable
2436
2437 \note This function emits the rowsAboutToBeRemoved() signal which connected
2438 views (or proxies) must handle before the data is removed. Otherwise, the
2439 views may end up in an invalid state.
2440
2441 \sa endRemoveRows()
2442*/
2443void QAbstractItemModel::beginRemoveRows(const QModelIndex &parent, int first, int last)
2444{
2445 Q_ASSERT(first >= 0);
2446 Q_ASSERT(last >= first);
2447 Q_D(QAbstractItemModel);
2448 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2449 emit rowsAboutToBeRemoved(parent, first, last);
2450 d->rowsAboutToBeRemoved(parent, first, last);
2451}
2452
2453/*!
2454 Ends a row removal operation.
2455
2456 When reimplementing removeRows() in a subclass, you must call this function
2457 \e after removing data from the model's underlying data store.
2458
2459 \sa beginRemoveRows()
2460*/
2461void QAbstractItemModel::endRemoveRows()
2462{
2463 Q_D(QAbstractItemModel);
2464 QAbstractItemModelPrivate::Change change = d->changes.pop();
2465 d->rowsRemoved(change.parent, change.first, change.last);
2466 emit rowsRemoved(change.parent, change.first, change.last);
2467}
2468
2469/*!
2470 Returns whether a move operation is valid.
2471
2472 A move operation is not allowed if it moves a continuous range of rows to a destination within
2473 itself, or if it attempts to move a row to one of its own descendants.
2474
2475 \internal
2476*/
2477bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int start, int end, const QModelIndex &destinationParent, int destinationStart, Qt::Orientation orientation)
2478{
2479 // Don't move the range within itself.
2480 if (destinationParent == srcParent)
2481 return !(destinationStart >= start && destinationStart <= end + 1);
2482
2483 QModelIndex destinationAncestor = destinationParent;
2484 int pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
2485 forever {
2486 if (destinationAncestor == srcParent) {
2487 if (pos >= start && pos <= end)
2488 return false;
2489 break;
2490 }
2491
2492 if (!destinationAncestor.isValid())
2493 break;
2494
2495 pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
2496 destinationAncestor = destinationAncestor.parent();
2497 }
2498
2499 return true;
2500}
2501
2502/*!
2503 \since 4.6
2504
2505 Begins a row move operation.
2506
2507 When reimplementing a subclass, this method simplifies moving
2508 entities in your model. This method is responsible for moving
2509 persistent indexes in the model, which you would otherwise be
2510 required to do yourself. Using beginMoveRows and endMoveRows
2511 is an alternative to emitting layoutAboutToBeChanged and
2512 layoutChanged directly along with changePersistentIndexes.
2513 layoutAboutToBeChanged is emitted by this method for compatibility
2514 reasons.
2515
2516 The \a sourceParent index corresponds to the parent from which the
2517 rows are moved; \a sourceFirst and \a sourceLast are the first and last
2518 row numbers of the rows to be moved. The \a destinationParent index
2519 corresponds to the parent into which those rows are moved. The \a
2520 destinationChild is the row to which the rows will be moved. That
2521 is, the index at row \a sourceFirst in \a sourceParent will become
2522 row \a destinationChild in \a destinationParent, followed by all other
2523 rows up to \a sourceLast.
2524
2525 However, when moving rows down in the same parent (\a sourceParent
2526 and \a destinationParent are equal), the rows will be placed before the
2527 \a destinationChild index. That is, if you wish to move rows 0 and 1 so
2528 they will become rows 1 and 2, \a destinationChild should be 3. In this
2529 case, the new index for the source row \c i (which is between
2530 \a sourceFirst and \a sourceLast) is equal to
2531 \c {(destinationChild-sourceLast-1+i)}.
2532
2533 Note that if \a sourceParent and \a destinationParent are the same,
2534 you must ensure that the \a destinationChild is not within the range
2535 of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
2536 do not attempt to move a row to one of its own children or ancestors.
2537 This method returns false if either condition is true, in which case you
2538 should abort your move operation.
2539
2540 \table 80%
2541 \row
2542 \o \inlineimage modelview-move-rows-1.png Moving rows to another parent
2543 \o Specify the first and last row numbers for the span of rows in
2544 the source parent you want to move in the model. Also specify
2545 the row in the destination parent to move the span to.
2546
2547 For example, as shown in the diagram, we move three rows from
2548 row 2 to 4 in the source, so \a sourceFirst is 2 and \a sourceLast is 4.
2549 We move those items to above row 2 in the destination, so \a destinationChild is 2.
2550
2551 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 6
2552
2553 This moves the three rows rows 2, 3, and 4 in the source to become 2, 3 and 4 in
2554 the destination. Other affected siblings are displaced accordingly.
2555 \row
2556 \o \inlineimage modelview-move-rows-2.png Moving rows to append to another parent
2557 \o To append rows to another parent, move them to after the last row.
2558
2559 For example, as shown in the diagram, we move three rows to a
2560 collection of 6 existing rows (ending in row 5), so \a destinationChild is 6:
2561
2562 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 7
2563
2564 This moves the target rows to the end of the target parent as 6, 7 and 8.
2565 \row
2566 \o \inlineimage modelview-move-rows-3.png Moving rows in the same parent up
2567 \o To move rows within the same parent, specify the row to move them to.
2568
2569 For example, as shown in the diagram, we move one item from row 2 to row 0,
2570 so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 0.
2571
2572 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 8
2573
2574 Note that other rows may be displaced accordingly. Note also that when moving
2575 items within the same parent you should not attempt invalid or no-op moves. In
2576 the above example, item 2 is at row 2 before the move, so it can not be moved
2577 to row 2 (where it is already) or row 3 (no-op as row 3 means above row 3, where
2578 it is already)
2579
2580 \row
2581 \o \inlineimage modelview-move-rows-4.png Moving rows in the same parent down
2582 \o To move rows within the same parent, specify the row to move them to.
2583
2584 For example, as shown in the diagram, we move one item from row 2 to row 4,
2585 so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 4.
2586
2587 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 9
2588
2589 Note that other rows may be displaced accordingly.
2590 \endtable
2591
2592 \sa endMoveRows()
2593*/
2594bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
2595{
2596 Q_ASSERT(sourceFirst >= 0);
2597 Q_ASSERT(sourceLast >= sourceFirst);
2598 Q_ASSERT(destinationChild >= 0);
2599 Q_D(QAbstractItemModel);
2600
2601 if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical)) {
2602 return false;
2603 }
2604
2605 QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
2606 sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
2607 d->changes.push(sourceChange);
2608 int destinationLast = destinationChild + (sourceLast - sourceFirst);
2609 QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
2610 destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
2611 d->changes.push(destinationChange);
2612
2613 emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild);
2614 emit layoutAboutToBeChanged();
2615 d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical);
2616 return true;
2617}
2618
2619/*!
2620 Ends a row move operation.
2621
2622 When implementing a subclass, you must call this
2623 function \e after moving data within the model's underlying data
2624 store.
2625
2626 layoutChanged is emitted by this method for compatibility reasons.
2627
2628 \sa beginMoveRows()
2629
2630 \since 4.6
2631*/
2632void QAbstractItemModel::endMoveRows()
2633{
2634 Q_D(QAbstractItemModel);
2635
2636 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
2637 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
2638
2639 QModelIndex adjustedSource = removeChange.parent;
2640 QModelIndex adjustedDestination = insertChange.parent;
2641
2642 const int numMoved = removeChange.last - removeChange.first + 1;
2643 if (insertChange.needsAdjust)
2644 adjustedDestination = createIndex(adjustedDestination.row() - numMoved, adjustedDestination.column(), adjustedDestination.internalPointer());
2645
2646 if (removeChange.needsAdjust)
2647 adjustedSource = createIndex(adjustedSource.row() + numMoved, adjustedSource.column(), adjustedSource.internalPointer());
2648
2649 d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Vertical);
2650
2651 emit rowsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first);
2652 emit layoutChanged();
2653}
2654
2655/*!
2656 Begins a column insertion operation.
2657
2658 When reimplementing insertColumns() in a subclass, you must call this
2659 function \e before inserting data into the model's underlying data store.
2660
2661 The \a parent index corresponds to the parent into which the new columns
2662 are inserted; \a first and \a last are the column numbers of the new
2663 columns will have after they have been inserted.
2664
2665 \table 80%
2666 \row
2667 \o \inlineimage modelview-begin-insert-columns.png Inserting columns
2668 \o Specify the first and last column numbers for the span of columns
2669 you want to insert into an item in a model.
2670
2671 For example, as shown in the diagram, we insert three columns
2672 before column 4, so \a first is 4 and \a last is 6:
2673
2674 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 3
2675
2676 This inserts the three new columns as columns 4, 5, and 6.
2677 \row
2678 \o \inlineimage modelview-begin-append-columns.png Appending columns
2679 \o To append columns, insert them after the last column.
2680
2681 For example, as shown in the diagram, we append three columns to a
2682 collection of six existing columns (ending in column 5), so
2683 \a first is 6 and \a last is 8:
2684
2685 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 4
2686
2687 This appends the two new columns as columns 6, 7, and 8.
2688 \endtable
2689
2690 \note This function emits the columnsAboutToBeInserted() signal which
2691 connected views (or proxies) must handle before the data is inserted.
2692 Otherwise, the views may end up in an invalid state.
2693
2694 \sa endInsertColumns()
2695*/
2696void QAbstractItemModel::beginInsertColumns(const QModelIndex &parent, int first, int last)
2697{
2698 Q_ASSERT(first >= 0);
2699 Q_ASSERT(last >= first);
2700 Q_D(QAbstractItemModel);
2701 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2702 emit columnsAboutToBeInserted(parent, first, last);
2703 d->columnsAboutToBeInserted(parent, first, last);
2704}
2705
2706/*!
2707 Ends a column insertion operation.
2708
2709 When reimplementing insertColumns() in a subclass, you must call this
2710 function \e after inserting data into the model's underlying data
2711 store.
2712
2713 \sa beginInsertColumns()
2714*/
2715void QAbstractItemModel::endInsertColumns()
2716{
2717 Q_D(QAbstractItemModel);
2718 QAbstractItemModelPrivate::Change change = d->changes.pop();
2719 d->columnsInserted(change.parent, change.first, change.last);
2720 emit columnsInserted(change.parent, change.first, change.last);
2721}
2722
2723/*!
2724 Begins a column removal operation.
2725
2726 When reimplementing removeColumns() in a subclass, you must call this
2727 function \e before removing data from the model's underlying data store.
2728
2729 The \a parent index corresponds to the parent from which the new columns
2730 are removed; \a first and \a last are the column numbers of the first and
2731 last columns to be removed.
2732
2733 \table 80%
2734 \row
2735 \o \inlineimage modelview-begin-remove-columns.png Removing columns
2736 \o Specify the first and last column numbers for the span of columns
2737 you want to remove from an item in a model.
2738
2739 For example, as shown in the diagram, we remove the three columns
2740 from column 4 to column 6, so \a first is 4 and \a last is 6:
2741
2742 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 5
2743 \endtable
2744
2745 \note This function emits the columnsAboutToBeRemoved() signal which
2746 connected views (or proxies) must handle before the data is removed.
2747 Otherwise, the views may end up in an invalid state.
2748
2749 \sa endRemoveColumns()
2750*/
2751void QAbstractItemModel::beginRemoveColumns(const QModelIndex &parent, int first, int last)
2752{
2753 Q_ASSERT(first >= 0);
2754 Q_ASSERT(last >= first);
2755 Q_D(QAbstractItemModel);
2756 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2757 emit columnsAboutToBeRemoved(parent, first, last);
2758 d->columnsAboutToBeRemoved(parent, first, last);
2759}
2760
2761/*!
2762 Ends a column removal operation.
2763
2764 When reimplementing removeColumns() in a subclass, you must call this
2765 function \e after removing data from the model's underlying data store.
2766
2767 \sa beginRemoveColumns()
2768*/
2769void QAbstractItemModel::endRemoveColumns()
2770{
2771 Q_D(QAbstractItemModel);
2772 QAbstractItemModelPrivate::Change change = d->changes.pop();
2773 d->columnsRemoved(change.parent, change.first, change.last);
2774 emit columnsRemoved(change.parent, change.first, change.last);
2775}
2776
2777/*!
2778 Begins a column move operation.
2779
2780 When reimplementing a subclass, this method simplifies moving
2781 entities in your model. This method is responsible for moving
2782 persistent indexes in the model, which you would otherwise be
2783 required to do yourself. Using beginMoveRows and endMoveRows
2784 is an alternative to emitting layoutAboutToBeChanged and
2785 layoutChanged directly along with changePersistentIndexes.
2786 layoutAboutToBeChanged is emitted by this method for compatibility
2787 reasons.
2788
2789 The \a sourceParent index corresponds to the parent from which the
2790 columns are moved; \a sourceFirst and \a sourceLast are the first and last
2791 column numbers of the columns to be moved. The \a destinationParent index
2792 corresponds to the parent into which those columns are moved. The \a
2793 destinationChild is the column to which the columns will be moved. That
2794 is, the index at column \a sourceFirst in \a sourceParent will become
2795 column \a destinationChild in \a destinationParent, followed by all other
2796 columns up to \a sourceLast.
2797
2798 However, when moving columns down in the same parent (\a sourceParent
2799 and \a destinationParent are equal), the columnss will be placed before the
2800 \a destinationChild index. That is, if you wish to move columns 0 and 1 so
2801 they will become columns 1 and 2, \a destinationChild should be 3. In this
2802 case, the new index for the source column \c i (which is between
2803 \a sourceFirst and \a sourceLast) is equal to
2804 \c {(destinationChild-sourceLast-1+i)}.
2805
2806 Note that if \a sourceParent and \a destinationParent are the same,
2807 you must ensure that the \a destinationChild is not within the range
2808 of \a sourceFirst and \a sourceLast + 1. You must also ensure that you
2809 do not attempt to move a column to one of its own children or ancestors.
2810 This method returns false if either condition is true, in which case you
2811 should abort your move operation.
2812
2813 \sa endMoveColumns()
2814
2815 \since 4.6
2816*/
2817bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
2818{
2819 Q_ASSERT(sourceFirst >= 0);
2820 Q_ASSERT(sourceLast >= sourceFirst);
2821 Q_ASSERT(destinationChild >= 0);
2822 Q_D(QAbstractItemModel);
2823
2824 if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal)) {
2825 return false;
2826 }
2827
2828 QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast);
2829 sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent;
2830 d->changes.push(sourceChange);
2831 int destinationLast = destinationChild + (sourceLast - sourceFirst);
2832 QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast);
2833 destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent;
2834 d->changes.push(destinationChange);
2835
2836 d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
2837
2838 emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild);
2839 emit layoutAboutToBeChanged();
2840 return true;
2841}
2842
2843/*!
2844 Ends a column move operation.
2845
2846 When implementing a subclass, you must call this
2847 function \e after moving data within the model's underlying data
2848 store.
2849
2850 layoutChanged is emitted by this method for compatibility reasons.
2851
2852 \sa beginMoveColumns()
2853
2854 \since 4.6
2855*/
2856void QAbstractItemModel::endMoveColumns()
2857{
2858 Q_D(QAbstractItemModel);
2859
2860 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
2861 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
2862
2863 QModelIndex adjustedSource = removeChange.parent;
2864 QModelIndex adjustedDestination = insertChange.parent;
2865
2866 const int numMoved = removeChange.last - removeChange.first + 1;
2867 if (insertChange.needsAdjust)
2868 adjustedDestination = createIndex(adjustedDestination.row(), adjustedDestination.column() - numMoved, adjustedDestination.internalPointer());
2869
2870 if (removeChange.needsAdjust)
2871 adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer());
2872
2873 d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal);
2874
2875 emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first);
2876 emit layoutChanged();
2877}
2878
2879/*!
2880 Resets the model to its original state in any attached views.
2881
2882 \note Use beginResetModel() and endResetModel() instead whenever possible.
2883 Use this method only if there is no way to call beginResetModel() before invalidating the model.
2884 Otherwise it could lead to unexpected behaviour, especially when used with proxy models.
2885*/
2886void QAbstractItemModel::reset()
2887{
2888 Q_D(QAbstractItemModel);
2889 emit modelAboutToBeReset();
2890 d->invalidatePersistentIndexes();
2891 emit modelReset();
2892}
2893
2894/*!
2895 Begins a model reset operation.
2896
2897 A reset operation resets the model to its current state in any attached views.
2898
2899 \note Any views attached to this model will be reset as well.
2900
2901 When a model is reset it means that any previous data reported from the
2902 model is now invalid and has to be queried for again. This also means that
2903 the current item and any selected items will become invalid.
2904
2905 When a model radically changes its data it can sometimes be easier to just
2906 call this function rather than emit dataChanged() to inform other
2907 components when the underlying data source, or its structure, has changed.
2908
2909 You must call this function before resetting any internal data structures in your model
2910 or proxy model.
2911
2912 \sa modelAboutToBeReset(), modelReset(), endResetModel()
2913 \since 4.6
2914*/
2915void QAbstractItemModel::beginResetModel()
2916{
2917 emit modelAboutToBeReset();
2918}
2919
2920/*!
2921 Completes a model reset operation.
2922
2923 You must call this function after resetting any internal data structure in your model
2924 or proxy model.
2925
2926 \sa beginResetModel()
2927 \since 4.6
2928*/
2929void QAbstractItemModel::endResetModel()
2930{
2931 Q_D(QAbstractItemModel);
2932 d->invalidatePersistentIndexes();
2933 emit modelReset();
2934}
2935
2936/*!
2937 Changes the QPersistentModelIndex that is equal to the given \a from model
2938 index to the given \a to model index.
2939
2940 If no persistent model index equal to the given \a from model index was
2941 found, nothing is changed.
2942
2943 \sa persistentIndexList(), changePersistentIndexList()
2944*/
2945void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QModelIndex &to)
2946{
2947 Q_D(QAbstractItemModel);
2948 if (d->persistent.indexes.isEmpty())
2949 return;
2950 // find the data and reinsert it sorted
2951 const QHash<QModelIndex, QPersistentModelIndexData *>::iterator it = d->persistent.indexes.find(from);
2952 if (it != d->persistent.indexes.end()) {
2953 QPersistentModelIndexData *data = *it;
2954 d->persistent.indexes.erase(it);
2955 data->index = to;
2956 if (to.isValid())
2957 d->persistent.insertMultiAtEnd(to, data);
2958 else
2959 data->model = 0;
2960 }
2961}
2962
2963/*!
2964 \since 4.1
2965
2966 Changes the QPersistentModelIndexes that is equal to the indexes in the
2967 given \a from model index list to the given \a to model index list.
2968
2969 If no persistent model indexes equal to the indexes in the given \a from
2970 model index list was found, nothing is changed.
2971
2972 \sa persistentIndexList(), changePersistentIndex()
2973*/
2974void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
2975 const QModelIndexList &to)
2976{
2977 Q_D(QAbstractItemModel);
2978 if (d->persistent.indexes.isEmpty())
2979 return;
2980 QVector<QPersistentModelIndexData *> toBeReinserted;
2981 toBeReinserted.reserve(to.count());
2982 for (int i = 0; i < from.count(); ++i) {
2983 if (from.at(i) == to.at(i))
2984 continue;
2985 const QHash<QModelIndex, QPersistentModelIndexData *>::iterator it = d->persistent.indexes.find(from.at(i));
2986 if (it != d->persistent.indexes.end()) {
2987 QPersistentModelIndexData *data = *it;
2988 d->persistent.indexes.erase(it);
2989 data->index = to.at(i);
2990 if (data->index.isValid())
2991 toBeReinserted << data;
2992 else
2993 data->model = 0;
2994 }
2995 }
2996
2997 for (QVector<QPersistentModelIndexData *>::const_iterator it = toBeReinserted.constBegin();
2998 it != toBeReinserted.constEnd() ; ++it) {
2999 QPersistentModelIndexData *data = *it;
3000 d->persistent.insertMultiAtEnd(data->index, data);
3001 }
3002}
3003
3004/*!
3005 \since 4.2
3006
3007 Returns the list of indexes stored as persistent indexes in the model.
3008*/
3009QModelIndexList QAbstractItemModel::persistentIndexList() const
3010{
3011 Q_D(const QAbstractItemModel);
3012 QModelIndexList result;
3013 for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = d->persistent.indexes.constBegin();
3014 it != d->persistent.indexes.constEnd(); ++it) {
3015 QPersistentModelIndexData *data = *it;
3016 result.append(data->index);
3017 }
3018 return result;
3019}
3020
3021
3022/*!
3023 \class QAbstractTableModel
3024 \brief The QAbstractTableModel class provides an abstract model that can be
3025 subclassed to create table models.
3026
3027 \ingroup model-view
3028
3029 QAbstractTableModel provides a standard interface for models that represent
3030 their data as a two-dimensional array of items. It is not used directly,
3031 but must be subclassed.
3032
3033 Since the model provides a more specialized interface than
3034 QAbstractItemModel, it is not suitable for use with tree views, although it
3035 can be used to provide data to a QListView. If you need to represent a
3036 simple list of items, and only need a model to contain a single column of
3037 data, subclassing the QAbstractListModel may be more appropriate.
3038
3039 The rowCount() and columnCount() functions return the dimensions of the
3040 table. To retrieve a model index corresponding to an item in the model, use
3041 index() and provide only the row and column numbers.
3042
3043 \section1 Subclassing
3044
3045 When subclassing QAbstractTableModel, you must implement rowCount(),
3046 columnCount(), and data(). Default implementations of the index() and
3047 parent() functions are provided by QAbstractTableModel.
3048 Well behaved models will also implement headerData().
3049
3050 Editable models need to implement setData(), and implement flags() to
3051 return a value containing
3052 \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
3053
3054 Models that provide interfaces to resizable data structures can
3055 provide implementations of insertRows(), removeRows(), insertColumns(),
3056 and removeColumns(). When implementing these functions, it is
3057 important to call the appropriate functions so that all connected views
3058 are aware of any changes:
3059
3060 \list
3061 \o An insertRows() implementation must call beginInsertRows()
3062 \e before inserting new rows into the data structure, and it must
3063 call endInsertRows() \e{immediately afterwards}.
3064 \o An insertColumns() implementation must call beginInsertColumns()
3065 \e before inserting new columns into the data structure, and it must
3066 call endInsertColumns() \e{immediately afterwards}.
3067 \o A removeRows() implementation must call beginRemoveRows()
3068 \e before the rows are removed from the data structure, and it must
3069 call endRemoveRows() \e{immediately afterwards}.
3070 \o A removeColumns() implementation must call beginRemoveColumns()
3071 \e before the columns are removed from the data structure, and it must
3072 call endRemoveColumns() \e{immediately afterwards}.
3073 \endlist
3074
3075 \note Some general guidelines for subclassing models are available in the
3076 \l{Model Subclassing Reference}.
3077
3078 \note
3079
3080 \sa {Model Classes}, QAbstractItemModel, QAbstractListModel,
3081 {Pixelator Example}
3082*/
3083
3084/*!
3085 Constructs an abstract table model for the given \a parent.
3086*/
3087
3088QAbstractTableModel::QAbstractTableModel(QObject *parent)
3089 : QAbstractItemModel(parent)
3090{
3091
3092}
3093
3094/*!
3095 \internal
3096
3097 Constructs an abstract table model with \a dd and the given \a parent.
3098*/
3099
3100QAbstractTableModel::QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent)
3101 : QAbstractItemModel(dd, parent)
3102{
3103
3104}
3105
3106/*!
3107 Destroys the abstract table model.
3108*/
3109
3110QAbstractTableModel::~QAbstractTableModel()
3111{
3112
3113}
3114
3115/*!
3116 \fn QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
3117
3118 Returns the index of the data in \a row and \a column with \a parent.
3119
3120 \sa parent()
3121*/
3122
3123QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent) const
3124{
3125 return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex();
3126}
3127
3128/*!
3129 \fn QModelIndex QAbstractTableModel::parent(const QModelIndex &index) const
3130
3131 Returns the parent of the model item with the given \a index.
3132
3133 \sa index() hasChildren()
3134*/
3135
3136QModelIndex QAbstractTableModel::parent(const QModelIndex &) const
3137{
3138 return QModelIndex();
3139}
3140
3141bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
3142{
3143 if (parent.model() == this || !parent.isValid())
3144 return rowCount(parent) > 0 && columnCount(parent) > 0;
3145 return false;
3146}
3147
3148/*!
3149 \class QAbstractListModel
3150 \brief The QAbstractListModel class provides an abstract model that can be
3151 subclassed to create one-dimensional list models.
3152
3153 \ingroup model-view
3154
3155 QAbstractListModel provides a standard interface for models that represent
3156 their data as a simple non-hierarchical sequence of items. It is not used
3157 directly, but must be subclassed.
3158
3159 Since the model provides a more specialized interface than
3160 QAbstractItemModel, it is not suitable for use with tree views; you will
3161 need to subclass QAbstractItemModel if you want to provide a model for
3162 that purpose. If you need to use a number of list models to manage data,
3163 it may be more appropriate to subclass QAbstractTableModel class instead.
3164
3165 Simple models can be created by subclassing this class and implementing
3166 the minimum number of required functions. For example, we could implement
3167 a simple read-only QStringList-based model that provides a list of strings
3168 to a QListView widget. In such a case, we only need to implement the
3169 rowCount() function to return the number of items in the list, and the
3170 data() function to retrieve items from the list.
3171
3172 Since the model represents a one-dimensional structure, the rowCount()
3173 function returns the total number of items in the model. The columnCount()
3174 function is implemented for interoperability with all kinds of views, but
3175 by default informs views that the model contains only one column.
3176
3177 \section1 Subclassing
3178
3179 When subclassing QAbstractListModel, you must provide implementations
3180 of the rowCount() and data() functions. Well behaved models also provide
3181 a headerData() implementation.
3182
3183 For editable list models, you must also provide an implementation of
3184 setData(), implement the flags() function so that it returns a value
3185 containing \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
3186
3187 Note that QAbstractListModel provides a default implementation of
3188 columnCount() that informs views that there is only a single column
3189 of items in this model.
3190
3191 Models that provide interfaces to resizable list-like data structures
3192 can provide implementations of insertRows() and removeRows(). When
3193 implementing these functions, it is important to call the appropriate
3194 functions so that all connected views are aware of any changes:
3195
3196 \list
3197 \o An insertRows() implementation must call beginInsertRows()
3198 \e before inserting new rows into the data structure, and it must
3199 call endInsertRows() \e{immediately afterwards}.
3200 \o A removeRows() implementation must call beginRemoveRows()
3201 \e before the rows are removed from the data structure, and it must
3202 call endRemoveRows() \e{immediately afterwards}.
3203 \endlist
3204
3205 \note Some general guidelines for subclassing models are available in the
3206 \l{Model Subclassing Reference}.
3207
3208 \sa {Model Classes}, {Model Subclassing Reference}, QAbstractItemView,
3209 QAbstractTableModel, {Item Views Puzzle Example}
3210*/
3211
3212/*!
3213 Constructs an abstract list model with the given \a parent.
3214*/
3215
3216QAbstractListModel::QAbstractListModel(QObject *parent)
3217 : QAbstractItemModel(parent)
3218{
3219
3220}
3221
3222/*!
3223 \internal
3224
3225 Constructs an abstract list model with \a dd and the given \a parent.
3226*/
3227
3228QAbstractListModel::QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent)
3229 : QAbstractItemModel(dd, parent)
3230{
3231
3232}
3233
3234/*!
3235 Destroys the abstract list model.
3236*/
3237
3238QAbstractListModel::~QAbstractListModel()
3239{
3240
3241}
3242
3243/*!
3244 \fn QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
3245
3246 Returns the index of the data in \a row and \a column with \a parent.
3247
3248 \sa parent()
3249*/
3250
3251QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent) const
3252{
3253 return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex();
3254}
3255
3256/*!
3257 Returns the parent of the model item with the given \a index.
3258
3259 \sa index() hasChildren()
3260*/
3261
3262QModelIndex QAbstractListModel::parent(const QModelIndex & /* index */) const
3263{
3264 return QModelIndex();
3265}
3266
3267/*!
3268 \internal
3269
3270 Returns the number of columns in the list with the given \a parent.
3271
3272 \sa rowCount()
3273*/
3274
3275int QAbstractListModel::columnCount(const QModelIndex &parent) const
3276{
3277 return parent.isValid() ? 0 : 1;
3278}
3279
3280bool QAbstractListModel::hasChildren(const QModelIndex &parent) const
3281{
3282 return parent.isValid() ? false : (rowCount() > 0);
3283}
3284
3285/*!
3286 \typedef QModelIndexList
3287 \relates QModelIndex
3288
3289 Synonym for QList<QModelIndex>.
3290*/
3291
3292/*!
3293 \reimp
3294*/
3295bool QAbstractTableModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
3296 int row, int column, const QModelIndex &parent)
3297{
3298 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
3299 return false;
3300
3301 QStringList types = mimeTypes();
3302 if (types.isEmpty())
3303 return false;
3304 QString format = types.at(0);
3305 if (!data->hasFormat(format))
3306 return false;
3307
3308 QByteArray encoded = data->data(format);
3309 QDataStream stream(&encoded, QIODevice::ReadOnly);
3310
3311 // if the drop is on an item, replace the data in the items
3312 if (parent.isValid() && row == -1 && column == -1) {
3313 int top = INT_MAX;
3314 int left = INT_MAX;
3315 QVector<int> rows, columns;
3316 QVector<QMap<int, QVariant> > data;
3317
3318 while (!stream.atEnd()) {
3319 int r, c;
3320 QMap<int, QVariant> v;
3321 stream >> r >> c >> v;
3322 rows.append(r);
3323 columns.append(c);
3324 data.append(v);
3325 top = qMin(r, top);
3326 left = qMin(c, left);
3327 }
3328
3329 for (int i = 0; i < data.size(); ++i) {
3330 int r = (rows.at(i) - top) + parent.row();
3331 int c = (columns.at(i) - left) + parent.column();
3332 if (hasIndex(r, c))
3333 setItemData(index(r, c), data.at(i));
3334 }
3335
3336 return true;
3337 }
3338
3339 // otherwise insert new rows for the data
3340 return decodeData(row, column, parent, stream);
3341}
3342
3343/*!
3344 \reimp
3345*/
3346bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
3347 int row, int column, const QModelIndex &parent)
3348{
3349 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
3350 return false;
3351
3352 QStringList types = mimeTypes();
3353 if (types.isEmpty())
3354 return false;
3355 QString format = types.at(0);
3356 if (!data->hasFormat(format))
3357 return false;
3358
3359 QByteArray encoded = data->data(format);
3360 QDataStream stream(&encoded, QIODevice::ReadOnly);
3361
3362 // if the drop is on an item, replace the data in the items
3363 if (parent.isValid() && row == -1 && column == -1) {
3364 int top = INT_MAX;
3365 int left = INT_MAX;
3366 QVector<int> rows, columns;
3367 QVector<QMap<int, QVariant> > data;
3368
3369 while (!stream.atEnd()) {
3370 int r, c;
3371 QMap<int, QVariant> v;
3372 stream >> r >> c >> v;
3373 rows.append(r);
3374 columns.append(c);
3375 data.append(v);
3376 top = qMin(r, top);
3377 left = qMin(c, left);
3378 }
3379
3380 for (int i = 0; i < data.size(); ++i) {
3381 int r = (rows.at(i) - top) + parent.row();
3382 if (columns.at(i) == left && hasIndex(r, 0))
3383 setItemData(index(r), data.at(i));
3384 }
3385
3386 return true;
3387 }
3388
3389 if (row == -1)
3390 row = rowCount(parent);
3391
3392 // otherwise insert new rows for the data
3393 return decodeData(row, column, parent, stream);
3394}
3395
3396/*!
3397 \fn QAbstractItemModel::modelAboutToBeReset()
3398 \since 4.2
3399
3400 This signal is emitted when reset() is called, before the model's internal
3401 state (e.g. persistent model indexes) has been invalidated.
3402
3403 \sa beginResetModel(), modelReset()
3404*/
3405
3406/*!
3407 \fn QAbstractItemModel::modelReset()
3408 \since 4.1
3409
3410 This signal is emitted when reset() is called, after the model's internal
3411 state (e.g. persistent model indexes) has been invalidated.
3412
3413 \sa endResetModel(), modelAboutToBeReset()
3414*/
3415
3416/*!
3417 \fn bool QModelIndex::operator<(const QModelIndex &other) const
3418 \since 4.1
3419
3420 Returns true if this model index is smaller than the \a other
3421 model index; otherwise returns false.
3422*/
3423
3424/*!
3425 \fn uint qHash(const QPersistentModelIndex &index)
3426 \since 4.5
3427
3428 Returns a hash of the QPersistentModelIndex
3429 */
3430
3431
3432/*!
3433 \internal
3434 QHash::insertMulti insert the value before the old value. and find() return the new value.
3435 We need insertMultiAtEnd because we don't want to overwrite the old one, which should be removed later
3436
3437 There should be only one instance QPersistentModelIndexData per index, but in some intermediate state there may be
3438 severals of PersistantModelIndex pointing to the same index, but one is already updated, and the other one is not.
3439 This make sure than when updating the first one we don't overwrite the second one in the hash, and the second one
3440 will be updated right later.
3441 */
3442void QAbstractItemModelPrivate::Persistent::insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data)
3443{
3444 QHash<QModelIndex,QPersistentModelIndexData *>::iterator newIt =
3445 indexes.insertMulti(key, data);
3446 QHash<QModelIndex,QPersistentModelIndexData *>::iterator it = newIt + 1;
3447 while (it != indexes.end() && it.key() == key) {
3448 qSwap(*newIt,*it);
3449 newIt = it;
3450 ++it;
3451 }
3452}
3453
3454QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.