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

Last change on this file since 641 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 112.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 \sa parent(), sibling()
1010*/
1011
1012/*!
1013 \fn QVariant QModelIndex::data(int role) const
1014
1015 Returns the data for the given \a role for the item referred to by the
1016 index.
1017*/
1018
1019/*!
1020 \fn Qt::ItemFlags QModelIndex::flags() const
1021 \since 4.2
1022
1023 Returns the flags for the item referred to by the index.
1024*/
1025
1026/*!
1027 \fn bool QModelIndex::operator==(const QModelIndex &other) const
1028
1029 Returns true if this model index refers to the same location as the
1030 \a other model index; otherwise returns false.
1031
1032 All values in the model index are used when comparing with another model
1033 index.
1034*/
1035
1036
1037/*!
1038 \fn bool QModelIndex::operator!=(const QModelIndex &other) const
1039
1040 Returns true if this model index does not refer to the same location as
1041 the \a other model index; otherwise returns false.
1042*/
1043
1044
1045/*!
1046 \fn QModelIndex QModelIndex::parent() const
1047
1048 Returns the parent of the model index, or QModelIndex() if it has no
1049 parent.
1050
1051 \sa child(), sibling(), model()
1052*/
1053
1054/*!
1055 \class QAbstractItemModel
1056
1057 \brief The QAbstractItemModel class provides the abstract interface for
1058 item model classes.
1059
1060 \ingroup model-view
1061
1062
1063 The QAbstractItemModel class defines the standard interface that item
1064 models must use to be able to interoperate with other components in the
1065 model/view architecture. It is not supposed to be instantiated directly.
1066 Instead, you should subclass it to create new models.
1067
1068 The QAbstractItemModel class is one of the \l{Model/View Classes}
1069 and is part of Qt's \l{Model/View Programming}{model/view framework}.
1070
1071 If you need a model to use with a QListView or a QTableView, you should
1072 consider subclassing QAbstractListModel or QAbstractTableModel instead of
1073 this class.
1074
1075 The underlying data model is exposed to views and delegates as a hierarchy
1076 of tables. If you do not make use of the hierarchy, then the model is a
1077 simple table of rows and columns. Each item has a unique index specified by
1078 a QModelIndex.
1079
1080 \image modelindex-no-parent.png
1081
1082 Every item of data that can be accessed via a model has an associated model
1083 index. You can obtain this model index using the index() function. Each
1084 index may have a sibling() index; child items have a parent() index.
1085
1086 Each item has a number of data elements associated with it and they can be
1087 retrieved by specifying a role (see \l Qt::ItemDataRole) to the model's
1088 data() function. Data for all available roles can be obtained at the same
1089 time using the itemData() function.
1090
1091 Data for each role is set using a particular \l Qt::ItemDataRole. Data for
1092 individual roles are set individually with setData(), or they can be set
1093 for all roles with setItemData().
1094
1095 Items can be queried with flags() (see \l Qt::ItemFlag) to see if they can
1096 be selected, dragged, or manipulated in other ways.
1097
1098 If an item has child objects, hasChildren() returns true for the
1099 corresponding index.
1100
1101 The model has a rowCount() and a columnCount() for each level of the
1102 hierarchy. Rows and columns can be inserted and removed with insertRows(),
1103 insertColumns(), removeRows(), and removeColumns().
1104
1105 The model emits signals to indicate changes. For example, dataChanged() is
1106 emitted whenever items of data made available by the model are changed.
1107 Changes to the headers supplied by the model cause headerDataChanged() to
1108 be emitted. If the structure of the underlying data changes, the model can
1109 emit layoutChanged() to indicate to any attached views that they should
1110 redisplay any items shown, taking the new structure into account.
1111
1112 The items available through the model can be searched for particular data
1113 using the match() function.
1114
1115 To sort the model, you can use sort().
1116
1117
1118 \section1 Subclassing
1119
1120 \note Some general guidelines for subclassing models are available in the
1121 \l{Model Subclassing Reference}.
1122
1123 When subclassing QAbstractItemModel, at the very least you must implement
1124 index(), parent(), rowCount(), columnCount(), and data(). These functions
1125 are used in all read-only models, and form the basis of editable models.
1126
1127 You can also reimplement hasChildren() to provide special behavior for
1128 models where the implementation of rowCount() is expensive. This makes it
1129 possible for models to restrict the amount of data requested by views, and
1130 can be used as a way to implement lazy population of model data.
1131
1132 To enable editing in your model, you must also implement setData(), and
1133 reimplement flags() to ensure that \c ItemIsEditable is returned. You can
1134 also reimplement headerData() and setHeaderData() to control the way the
1135 headers for your model are presented.
1136
1137 The dataChanged() and headerDataChanged() signals must be emitted
1138 explicitly when reimplementing the setData() and setHeaderData() functions,
1139 respectively.
1140
1141 Custom models need to create model indexes for other components to use. To
1142 do this, call createIndex() with suitable row and column numbers for the
1143 item, and an identifier for it, either as a pointer or as an integer value.
1144 The combination of these values must be unique for each item. Custom models
1145 typically use these unique identifiers in other reimplemented functions to
1146 retrieve item data and access information about the item's parents and
1147 children. See the \l{Simple Tree Model Example} for more information about
1148 unique identifiers.
1149
1150 It is not necessary to support every role defined in Qt::ItemDataRole.
1151 Depending on the type of data contained within a model, it may only be
1152 useful to implement the data() function to return valid information for
1153 some of the more common roles. Most models provide at least a textual
1154 representation of item data for the Qt::DisplayRole, and well-behaved
1155 models should also provide valid information for the Qt::ToolTipRole and
1156 Qt::WhatsThisRole. Supporting these roles enables models to be used with
1157 standard Qt views. However, for some models that handle highly-specialized
1158 data, it may be appropriate to provide data only for user-defined roles.
1159
1160 Models that provide interfaces to resizable data structures can provide
1161 implementations of insertRows(), removeRows(), insertColumns(),and
1162 removeColumns(). When implementing these functions, it is important to
1163 notify any connected views about changes to the model's dimensions both
1164 \e before and \e after they occur:
1165
1166 \list
1167 \o An insertRows() implementation must call beginInsertRows() \e before
1168 inserting new rows into the data structure, and endInsertRows()
1169 \e{immediately afterwards}.
1170 \o An insertColumns() implementation must call beginInsertColumns()
1171 \e before inserting new columns into the data structure, and
1172 endInsertColumns() \e{immediately afterwards}.
1173 \o A removeRows() implementation must call beginRemoveRows() \e before
1174 the rows are removed from the data structure, and endRemoveRows()
1175 \e{immediately afterwards}.
1176 \o A removeColumns() implementation must call beginRemoveColumns()
1177 \e before the columns are removed from the data structure, and
1178 endRemoveColumns() \e{immediately afterwards}.
1179 \endlist
1180
1181 The \e private signals that these functions emit give attached components
1182 the chance to take action before any data becomes unavailable. The
1183 encapsulation of the insert and remove operations with these begin and end
1184 functions also enables the model to manage \l{QPersistentModelIndex}
1185 {persistent model indexes} correctly. \bold{If you want selections to be
1186 handled properly, you must ensure that you call these functions.} If you
1187 insert or remove an item with children, you do not need to call these
1188 functions for the child items. In other words, the parent item will take
1189 care of its child items.
1190
1191 To create models that populate incrementally, you can reimplement
1192 fetchMore() and canFetchMore(). If the reimplementation of fetchMore() adds
1193 rows to the model, \l{QAbstractItemModel::}{beginInsertRows()} and
1194 \l{QAbstractItemModel::}{endInsertRows()} must be called.
1195
1196 \sa {Model Classes}, {Model Subclassing Reference}, QModelIndex,
1197 QAbstractItemView, {Using Drag and Drop with Item Views},
1198 {Simple DOM Model Example}, {Simple Tree Model Example},
1199 {Editable Tree Model Example}, {Fetch More Example}
1200*/
1201
1202/*!
1203 \fn QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const = 0
1204
1205 Returns the index of the item in the model specified by the given \a row,
1206 \a column and \a parent index.
1207
1208 When reimplementing this function in a subclass, call createIndex() to
1209 generate model indexes that other components can use to refer to items in
1210 your model.
1211
1212 \sa createIndex()
1213*/
1214
1215/*!
1216 \fn bool QAbstractItemModel::insertColumn(int column, const QModelIndex &parent)
1217
1218 Inserts a single column before the given \a column in the child items of
1219 the \a parent specified.
1220
1221 Returns true if the column is inserted; otherwise returns false.
1222
1223 \sa insertColumns() insertRow() removeColumn()
1224*/
1225
1226/*!
1227 \fn bool QAbstractItemModel::insertRow(int row, const QModelIndex &parent)
1228
1229 \note The base class implementation of this function does nothing and
1230 returns false.
1231
1232 Inserts a single row before the given \a row in the child items of the
1233 \a parent specified.
1234
1235 Returns true if the row is inserted; otherwise returns false.
1236
1237 \sa insertRows() insertColumn() removeRow()
1238*/
1239
1240/*!
1241 \fn QObject *QAbstractItemModel::parent() const
1242 \internal
1243*/
1244
1245/*!
1246 \fn QModelIndex QAbstractItemModel::parent(const QModelIndex &index) const = 0
1247
1248 Returns the parent of the model item with the given \a index. If the model
1249 has no parent, an invalid QModelIndex is returned.
1250
1251 A common convention used in models that expose tree data structures is that
1252 only items in the first column have children. For that case, when
1253 reimplementing this function in a subclass the column of the returned
1254 QModelIndex would be 0.
1255
1256 When reimplementing this function in a subclass, be careful to avoid
1257 calling QModelIndex member functions, such as QModelIndex::parent(), since
1258 indexes belonging to your model will simply call your implementation,
1259 leading to infinite recursion.
1260
1261 \sa createIndex()
1262*/
1263
1264/*!
1265 \fn bool QAbstractItemModel::removeColumn(int column, const QModelIndex &parent)
1266
1267 Removes the given \a column from the child items of the \a parent
1268 specified.
1269
1270 Returns true if the column is removed; otherwise returns false.
1271
1272 \sa removeColumns(), removeRow(), insertColumn()
1273*/
1274
1275/*!
1276 \fn bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent)
1277
1278 Removes the given \a row from the child items of the \a parent specified.
1279
1280 Returns true if the row is removed; otherwise returns false.
1281
1282 This is a convenience function that calls removeRows(). The
1283 QAbstractItemModel implementation of removeRows() does nothing.
1284
1285 \sa removeRows(), removeColumn(), insertRow()
1286*/
1287
1288/*!
1289 \fn void QAbstractItemModel::headerDataChanged(Qt::Orientation orientation, int first, int last)
1290
1291 This signal is emitted whenever a header is changed. The \a orientation
1292 indicates whether the horizontal or vertical header has changed. The
1293 sections in the header from the \a first to the \a last need to be updated.
1294
1295 When reimplementing the setHeaderData() function, this signal must be
1296 emitted explicitly.
1297
1298 If you are changing the number of columns or rows you do not need to emit
1299 this signal, but use the begin/end functions (refer to the section on
1300 subclassing in the QAbstractItemModel class description for details).
1301
1302 \sa headerData(), setHeaderData(), dataChanged()
1303*/
1304
1305/*!
1306 \fn void QAbstractItemModel::layoutAboutToBeChanged()
1307 \since 4.2
1308
1309 This signal is emitted just before the layout of a model is changed.
1310 Components connected to this signal use it to adapt to changes in the
1311 model's layout.
1312
1313 Subclasses should update any persistent model indexes after emitting
1314 layoutAboutToBeChanged().
1315
1316 \sa layoutChanged(), changePersistentIndex()
1317*/
1318
1319/*!
1320 \fn void QAbstractItemModel::layoutChanged()
1321
1322 This signal is emitted whenever the layout of items exposed by the model
1323 has changed; for example, when the model has been sorted. When this signal
1324 is received by a view, it should update the layout of items to reflect this
1325 change.
1326
1327 When subclassing QAbstractItemModel or QAbstractProxyModel, ensure that you
1328 emit layoutAboutToBeChanged() before changing the order of items or
1329 altering the structure of the data you expose to views, and emit
1330 layoutChanged() after changing the layout.
1331
1332 Subclasses should update any persistent model indexes before emitting
1333 layoutChanged(). In other words, when the structure changes:
1334
1335 \list
1336 \o Call beginLayoutChanged()
1337 \o Remember the QModelIndex that will change
1338 \o Update your internal data
1339 \o Call changePersistentIndex()
1340 \o Call endLayoutChanged()
1341 \endlist
1342
1343
1344 \sa layoutAboutToBeChanged(), dataChanged(), headerDataChanged(), modelReset(),
1345 changePersistentIndex()
1346*/
1347
1348/*!
1349 Constructs an abstract item model with the given \a parent.
1350*/
1351QAbstractItemModel::QAbstractItemModel(QObject *parent)
1352 : QObject(*new QAbstractItemModelPrivate, parent)
1353{
1354}
1355
1356/*!
1357 \internal
1358*/
1359QAbstractItemModel::QAbstractItemModel(QAbstractItemModelPrivate &dd, QObject *parent)
1360 : QObject(dd, parent)
1361{
1362}
1363
1364/*!
1365 Destroys the abstract item model.
1366*/
1367QAbstractItemModel::~QAbstractItemModel()
1368{
1369 d_func()->invalidatePersistentIndexes();
1370}
1371
1372/*!
1373 \fn QModelIndex QAbstractItemModel::sibling(int row, int column, const QModelIndex &index) const
1374
1375 Returns the sibling at \a row and \a column for the item at \a index, or an
1376 invalid QModelIndex if there is no sibling at that location.
1377
1378 sibling() is just a convenience function that finds the item's parent, and
1379 uses it to retrieve the index of the child item in the specified \a row and
1380 \a column.
1381
1382 \sa index(), QModelIndex::row(), QModelIndex::column()
1383*/
1384
1385
1386/*!
1387 \fn int QAbstractItemModel::rowCount(const QModelIndex &parent) const
1388
1389 Returns the number of rows under the given \a parent. When the parent is
1390 valid it means that rowCount is returning the number of children of parent.
1391
1392 \note When implementing a table based model, rowCount() should return 0
1393 when the parent is valid.
1394
1395 \sa columnCount()
1396*/
1397
1398/*!
1399 \fn int QAbstractItemModel::columnCount(const QModelIndex &parent) const
1400
1401 Returns the number of columns for the children of the given \a parent.
1402
1403 In most subclasses, the number of columns is independent of the \a parent.
1404
1405 For example:
1406
1407 \snippet examples/itemviews/simpledommodel/dommodel.cpp 2
1408
1409 \note When implementing a table based model, columnCount() should return 0
1410 when the parent is valid.
1411
1412 \sa rowCount()
1413*/
1414
1415/*!
1416 \fn void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
1417
1418 This signal is emitted whenever the data in an existing item changes.
1419
1420 If the items are of the same parent, the affected ones are those between
1421 \a topLeft and \a bottomRight inclusive. If the items do not have the same
1422 parent, the behavior is undefined.
1423
1424 When reimplementing the setData() function, this signal must be emitted
1425 explicitly.
1426
1427 \sa headerDataChanged(), setData(), layoutChanged()
1428*/
1429
1430/*!
1431 \fn void QAbstractItemModel::rowsInserted(const QModelIndex &parent, int start, int end)
1432
1433 This signal is emitted after rows have been inserted into the
1434 model. The new items are those between \a start and \a end
1435 inclusive, under the given \a parent item.
1436
1437 \note Components connected to this signal use it to adapt to changes in the
1438 model's dimensions. It can only be emitted by the QAbstractItemModel
1439 implementation, and cannot be explicitly emitted in subclass code.
1440
1441 \sa insertRows(), beginInsertRows()
1442*/
1443
1444/*!
1445 \fn void QAbstractItemModel::rowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
1446
1447 This signal is emitted just before rows are inserted into the model. The
1448 new items will be positioned between \a start and \a end inclusive, under
1449 the given \a parent item.
1450
1451 \note Components connected to this signal use it to adapt to changes
1452 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1453 implementation, and cannot be explicitly emitted in subclass code.
1454
1455 \sa insertRows(), beginInsertRows()
1456*/
1457
1458/*!
1459 \fn void QAbstractItemModel::rowsRemoved(const QModelIndex &parent, int start, int end)
1460
1461 This signal is emitted after rows have been removed from the model. The
1462 removed items are those between \a start and \a end inclusive, under the
1463 given \a parent item.
1464
1465 \note Components connected to this signal use it to adapt to changes
1466 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1467 implementation, and cannot be explicitly emitted in subclass code.
1468
1469 \sa removeRows(), beginRemoveRows()
1470*/
1471
1472/*!
1473 \fn void QAbstractItemModel::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
1474
1475 This signal is emitted just before rows are removed from the model. The
1476 items that will be removed are those between \a start and \a end inclusive,
1477 under the given \a parent item.
1478
1479 \note Components connected to this signal use it to adapt to changes
1480 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1481 implementation, and cannot be explicitly emitted in subclass code.
1482
1483 \sa removeRows(), beginRemoveRows()
1484*/
1485
1486/*!
1487 \fn void QAbstractItemModel::rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
1488 \since 4.6
1489
1490 This signal is emitted after rows have been moved within the
1491 model. The items between \a sourceStart and \a sourceEnd
1492 inclusive, under the given \a sourceParent item have been moved to \a destinationParent
1493 starting at the row \a destinationRow.
1494
1495 \bold{Note:} Components connected to this signal use it to adapt to changes
1496 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1497 implementation, and cannot be explicitly emitted in subclass code.
1498
1499 \sa beginMoveRows()
1500*/
1501
1502/*!
1503 \fn void QAbstractItemModel::rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
1504 \since 4.6
1505
1506 This signal is emitted just before rows are moved within the
1507 model. The items that will be moved are those between \a sourceStart and \a sourceEnd
1508 inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
1509 starting at the row \a destinationRow.
1510
1511 \bold{Note:} Components connected to this signal use it to adapt to changes
1512 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1513 implementation, and cannot be explicitly emitted in subclass code.
1514
1515 \sa beginMoveRows()
1516*/
1517
1518/*!
1519 \fn void QAbstractItemModel::columnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
1520 \since 4.6
1521
1522 This signal is emitted after columns have been moved within the
1523 model. The items between \a sourceStart and \a sourceEnd
1524 inclusive, under the given \a sourceParent item have been moved to \a destinationParent
1525 starting at the column \a destinationColumn.
1526
1527 \bold{Note:} Components connected to this signal use it to adapt to changes
1528 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1529 implementation, and cannot be explicitly emitted in subclass code.
1530
1531 \sa beginMoveRows()
1532*/
1533
1534/*!
1535 \fn void QAbstractItemModel::columnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
1536 \since 4.6
1537
1538 This signal is emitted just before columns are moved within the
1539 model. The items that will be moved are those between \a sourceStart and \a sourceEnd
1540 inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
1541 starting at the column \a destinationColumn.
1542
1543 \bold{Note:} Components connected to this signal use it to adapt to changes
1544 in the model's dimensions. It can only be emitted by the QAbstractItemModel
1545 implementation, and cannot be explicitly emitted in subclass code.
1546
1547 \sa beginMoveRows()
1548*/
1549
1550/*!
1551 \fn void QAbstractItemModel::columnsInserted(const QModelIndex &parent, int start, int end)
1552
1553 This signal is emitted after columns have been inserted into the model. The
1554 new items are those between \a start and \a end inclusive, under the given
1555 \a parent item.
1556
1557 \note Components connected to this signal use it to adapt to changes in the
1558 model's dimensions. It can only be emitted by the QAbstractItemModel
1559 implementation, and cannot be explicitly emitted in subclass code.
1560
1561 \sa insertColumns(), beginInsertColumns()
1562*/
1563
1564/*!
1565 \fn void QAbstractItemModel::columnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
1566
1567 This signal is emitted just before columns are inserted into the model. The
1568 new items will be positioned between \a start and \a end inclusive, under
1569 the given \a parent item.
1570
1571 \note Components connected to this signal use it to adapt to changes in the
1572 model's dimensions. It can only be emitted by the QAbstractItemModel
1573 implementation, and cannot be explicitly emitted in subclass code.
1574
1575 \sa insertColumns(), beginInsertColumns()
1576*/
1577
1578/*!
1579 \fn void QAbstractItemModel::columnsRemoved(const QModelIndex &parent, int start, int end)
1580
1581 This signal is emitted after columns have been removed from the model.
1582 The removed items are those between \a start and \a end inclusive,
1583 under the given \a parent item.
1584
1585 \note Components connected to this signal use it to adapt to changes in
1586 the model's dimensions. It can only be emitted by the QAbstractItemModel
1587 implementation, and cannot be explicitly emitted in subclass code.
1588
1589 \sa removeColumns(), beginRemoveColumns()
1590*/
1591
1592/*!
1593 \fn void QAbstractItemModel::columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
1594
1595 This signal is emitted just before columns are removed from the model. The
1596 items to be removed are those between \a start and \a end inclusive, under
1597 the given \a parent item.
1598
1599 \note Components connected to this signal use it to adapt to changes in the
1600 model's dimensions. It can only be emitted by the QAbstractItemModel
1601 implementation, and cannot be explicitly emitted in subclass code.
1602
1603 \sa removeColumns(), beginRemoveColumns()
1604*/
1605
1606/*!
1607 Returns true if the model returns a valid QModelIndex for \a row and
1608 \a column with \a parent, otherwise returns false.
1609*/
1610bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const
1611{
1612 if (row < 0 || column < 0)
1613 return false;
1614 return row < rowCount(parent) && column < columnCount(parent);
1615}
1616
1617
1618/*!
1619 Returns true if \a parent has any children; otherwise returns false.
1620
1621 Use rowCount() on the parent to find out the number of children.
1622
1623 \sa parent() index()
1624*/
1625bool QAbstractItemModel::hasChildren(const QModelIndex &parent) const
1626{
1627 return (rowCount(parent) > 0) && (columnCount(parent) > 0);
1628}
1629
1630
1631/*!
1632 Returns a map with values for all predefined roles in the model for the
1633 item at the given \a index.
1634
1635 Reimplement this function if you want to extend the default behavior of
1636 this function to include custom roles in the map.
1637
1638 \sa Qt::ItemDataRole, data()
1639*/
1640QMap<int, QVariant> QAbstractItemModel::itemData(const QModelIndex &index) const
1641{
1642 QMap<int, QVariant> roles;
1643 for (int i = 0; i < Qt::UserRole; ++i) {
1644 QVariant variantData = data(index, i);
1645 if (variantData.isValid())
1646 roles.insert(i, variantData);
1647 }
1648 return roles;
1649}
1650
1651/*!
1652 Sets the \a role data for the item at \a index to \a value.
1653
1654 Returns true if successful; otherwise returns false.
1655
1656 The dataChanged() signal should be emitted if the data was successfully
1657 set.
1658
1659 The base class implementation returns false. This function and data() must
1660 be reimplemented for editable models.
1661
1662 \sa Qt::ItemDataRole, data(), itemData()
1663*/
1664bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
1665{
1666 Q_UNUSED(index);
1667 Q_UNUSED(value);
1668 Q_UNUSED(role);
1669 return false;
1670}
1671
1672/*!
1673 \fn QVariant QAbstractItemModel::data(const QModelIndex &index, int role) const = 0
1674
1675 Returns the data stored under the given \a role for the item referred to
1676 by the \a index.
1677
1678 \note If you do not have a value to return, return an \bold invalid
1679 QVariant instead of returning 0.
1680
1681 \sa Qt::ItemDataRole, setData(), headerData()
1682*/
1683
1684/*!
1685 Sets the role data for the item at \a index to the associated value in
1686 \a roles, for every Qt::ItemDataRole.
1687
1688 Returns true if successful; otherwise returns false.
1689
1690 Roles that are not in \a roles will not be modified.
1691
1692 \sa setData() data() itemData()
1693*/
1694bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
1695{
1696 bool b = true;
1697 for (QMap<int, QVariant>::ConstIterator it = roles.begin(); it != roles.end(); ++it)
1698 b = b && setData(index, it.value(), it.key());
1699 return b;
1700}
1701
1702/*!
1703 Returns a list of MIME types that can be used to describe a list of model
1704 indexes.
1705
1706 \sa mimeData()
1707*/
1708QStringList QAbstractItemModel::mimeTypes() const
1709{
1710 QStringList types;
1711 types << QLatin1String("application/x-qabstractitemmodeldatalist");
1712 return types;
1713}
1714
1715/*!
1716 Returns an object that contains serialized items of data corresponding to
1717 the list of \a indexes specified. The formats used to describe the encoded
1718 data is obtained from the mimeTypes() function.
1719
1720 If the list of indexes is empty, or there are no supported MIME types, 0 is
1721 returned rather than a serialized empty list.
1722
1723 \sa mimeTypes(), dropMimeData()
1724*/
1725QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
1726{
1727 if (indexes.count() <= 0)
1728 return 0;
1729 QStringList types = mimeTypes();
1730 if (types.isEmpty())
1731 return 0;
1732 QMimeData *data = new QMimeData();
1733 QString format = types.at(0);
1734 QByteArray encoded;
1735 QDataStream stream(&encoded, QIODevice::WriteOnly);
1736 encodeData(indexes, stream);
1737 data->setData(format, encoded);
1738 return data;
1739}
1740
1741/*!
1742 Handles the \a data supplied by a drag and drop operation that ended with
1743 the given \a action.
1744
1745 Returns true if the data and action can be handled by the model; otherwise
1746 returns false.
1747
1748 Although the specified \a row, \a column and \a parent indicate the
1749 location of an item in the model where the operation ended, it is the
1750 responsibility of the view to provide a suitable location for where the
1751 data should be inserted.
1752
1753 For instance, a drop action on an item in a QTreeView can result in new
1754 items either being inserted as children of the item specified by \a row,
1755 \a column, and \a parent, or as siblings of the item.
1756
1757 When row and column are -1 it means that it is up to the model to decide
1758 where to place the data. This can occur in a tree when data is dropped on
1759 a parent. Models will usually append the data to the parent in this case.
1760
1761 \sa supportedDropActions(), {Using Drag and Drop with Item Views}
1762*/
1763bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
1764 int row, int column, const QModelIndex &parent)
1765{
1766 // check if the action is supported
1767 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
1768 return false;
1769 // check if the format is supported
1770 QStringList types = mimeTypes();
1771 if (types.isEmpty())
1772 return false;
1773 QString format = types.at(0);
1774 if (!data->hasFormat(format))
1775 return false;
1776 if (row > rowCount(parent))
1777 row = rowCount(parent);
1778 if (row == -1)
1779 row = rowCount(parent);
1780 if (column == -1)
1781 column = 0;
1782 // decode and insert
1783 QByteArray encoded = data->data(format);
1784 QDataStream stream(&encoded, QIODevice::ReadOnly);
1785 return decodeData(row, column, parent, stream);
1786}
1787
1788/*!
1789 \since 4.2
1790
1791 Returns the drop actions supported by this model.
1792
1793 The default implementation returns Qt::CopyAction. Reimplement this
1794 function if you wish to support additional actions. You must also
1795 reimplement the dropMimeData() function to handle the additional
1796 operations.
1797
1798 \sa dropMimeData(), Qt::DropActions, {Using Drag and Drop with Item
1799 Views}
1800*/
1801Qt::DropActions QAbstractItemModel::supportedDropActions() const
1802{
1803 return Qt::CopyAction;
1804}
1805
1806/*!
1807 Returns the actions supported by the data in this model.
1808
1809 The default implementation returns supportedDropActions() unless specific
1810 values have been set with setSupportedDragActions().
1811
1812 supportedDragActions() is used by QAbstractItemView::startDrag() as the
1813 default values when a drag occurs.
1814
1815 \sa Qt::DropActions, {Using Drag and Drop with Item Views}
1816*/
1817Qt::DropActions QAbstractItemModel::supportedDragActions() const
1818{
1819 // ### Qt 5: make this virtual or these properties
1820 Q_D(const QAbstractItemModel);
1821 if (d->supportedDragActions != -1)
1822 return d->supportedDragActions;
1823 return supportedDropActions();
1824}
1825
1826/*!
1827 \since 4.2
1828
1829 Sets the supported drag \a actions for the items in the model.
1830
1831 \sa supportedDragActions(), {Using Drag and Drop with Item Views}
1832*/
1833void QAbstractItemModel::setSupportedDragActions(Qt::DropActions actions)
1834{
1835 Q_D(QAbstractItemModel);
1836 d->supportedDragActions = actions;
1837}
1838
1839/*!
1840 \note The base class implementation of this function does nothing and
1841 returns false.
1842
1843 On models that support this, inserts \a count rows into the model before
1844 the given \a row. Items in the new row will be children of the item
1845 represented by the \a parent model index.
1846
1847 If \a row is 0, the rows are prepended to any existing rows in the parent.
1848
1849 If \a row is rowCount(), the rows are appended to any existing rows in the
1850 parent.
1851
1852 If \a parent has no children, a single column with \a count rows is
1853 inserted.
1854
1855 Returns true if the rows were successfully inserted; otherwise returns
1856 false.
1857
1858 If you implement your own model, you can reimplement this function if you
1859 want to support insertions. Alternatively, you can provide your own API for
1860 altering the data. In either case, you will need to call
1861 beginInsertRows() and endInsertRows() to notify other components that the
1862 model has changed.
1863
1864 \sa insertColumns(), removeRows(), beginInsertRows(), endInsertRows()
1865*/
1866bool QAbstractItemModel::insertRows(int, int, const QModelIndex &)
1867{
1868 return false;
1869}
1870
1871/*!
1872 On models that support this, inserts \a count new columns into the model
1873 before the given \a column. The items in each new column will be children
1874 of the item represented by the \a parent model index.
1875
1876 If \a column is 0, the columns are prepended to any existing columns.
1877
1878 If \a column is columnCount(), the columns are appended to any existing
1879 columns.
1880
1881 If \a parent has no children, a single row with \a count columns is
1882 inserted.
1883
1884 Returns true if the columns were successfully inserted; otherwise returns
1885 false.
1886
1887 The base class implementation does nothing and returns false.
1888
1889 If you implement your own model, you can reimplement this function if you
1890 want to support insertions. Alternatively, you can provide your own API for
1891 altering the data.
1892
1893 \sa insertRows(), removeColumns(), beginInsertColumns(), endInsertColumns()
1894*/
1895bool QAbstractItemModel::insertColumns(int, int, const QModelIndex &)
1896{
1897 return false;
1898}
1899
1900/*!
1901 On models that support this, removes \a count rows starting with the given
1902 \a row under parent \a parent from the model.
1903
1904 Returns true if the rows were successfully removed; otherwise returns
1905 false.
1906
1907 The base class implementation does nothing and returns false.
1908
1909 If you implement your own model, you can reimplement this function if you
1910 want to support removing. Alternatively, you can provide your own API for
1911 altering the data.
1912
1913 \sa removeRow(), removeColumns(), insertColumns(), beginRemoveRows(),
1914 endRemoveRows()
1915*/
1916bool QAbstractItemModel::removeRows(int, int, const QModelIndex &)
1917{
1918 return false;
1919}
1920
1921/*!
1922 On models that support this, removes \a count columns starting with the
1923 given \a column under parent \a parent from the model.
1924
1925 Returns true if the columns were successfully removed; otherwise returns
1926 false.
1927
1928 The base class implementation does nothing and returns false.
1929
1930 If you implement your own model, you can reimplement this function if you
1931 want to support removing. Alternatively, you can provide your own API for
1932 altering the data.
1933
1934 \sa removeColumn(), removeRows(), insertColumns(), beginRemoveColumns(),
1935 endRemoveColumns()
1936*/
1937bool QAbstractItemModel::removeColumns(int, int, const QModelIndex &)
1938{
1939 return false;
1940}
1941
1942/*!
1943 Fetches any available data for the items with the parent specified by the
1944 \a parent index.
1945
1946 Reimplement this if you are populating your model incrementally.
1947
1948 The default implementation does nothing.
1949
1950 \sa canFetchMore()
1951*/
1952void QAbstractItemModel::fetchMore(const QModelIndex &)
1953{
1954 // do nothing
1955}
1956
1957/*!
1958 Returns true if there is more data available for \a parent; otherwise
1959 returns false.
1960
1961 The default implementation always returns false.
1962
1963 If canFetchMore() returns true, QAbstractItemView will call fetchMore().
1964 However, the fetchMore() function is only called when the model is being
1965 populated incrementally.
1966
1967 \sa fetchMore()
1968*/
1969bool QAbstractItemModel::canFetchMore(const QModelIndex &) const
1970{
1971 return false;
1972}
1973
1974/*!
1975 Returns the item flags for the given \a index.
1976
1977 The base class implementation returns a combination of flags that enables
1978 the item (\c ItemIsEnabled) and allows it to be selected
1979 (\c ItemIsSelectable).
1980
1981 \sa Qt::ItemFlags
1982*/
1983Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const
1984{
1985 Q_D(const QAbstractItemModel);
1986 if (!d->indexValid(index))
1987 return 0;
1988
1989 return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
1990}
1991
1992/*!
1993 Sorts the model by \a column in the given \a order.
1994
1995 The base class implementation does nothing.
1996*/
1997void QAbstractItemModel::sort(int column, Qt::SortOrder order)
1998{
1999 Q_UNUSED(column);
2000 Q_UNUSED(order);
2001 // do nothing
2002}
2003
2004/*!
2005 Returns a model index for the buddy of the item represented by \a index.
2006 When the user wants to edit an item, the view will call this function to
2007 check whether another item in the model should be edited instead. Then, the
2008 view will construct a delegate using the model index returned by the buddy
2009 item.
2010
2011 The default implementation of this function has each item as its own buddy.
2012*/
2013QModelIndex QAbstractItemModel::buddy(const QModelIndex &index) const
2014{
2015 return index;
2016}
2017
2018/*!
2019 Returns a list of indexes for the items in the column of the \a start index
2020 where data stored under the given \a role matches the specified \a value.
2021 The way the search is performed is defined by the \a flags given. The list
2022 that is returned may be empty.
2023
2024 The search begins from the \a start index, and continues until the number
2025 of matching data items equals \a hits, the search reaches the last row, or
2026 the search reaches \a start again - depending on whether \c MatchWrap is
2027 specified in \a flags. If you want to search for all matching items, use
2028 \a hits = -1.
2029
2030 By default, this function will perform a wrapping, string-based comparison
2031 on all items, searching for items that begin with the search term specified
2032 by \a value.
2033
2034 \note The default implementation of this function only searches columns.
2035 Reimplement this function to include a different search behavior.
2036*/
2037QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
2038 const QVariant &value, int hits,
2039 Qt::MatchFlags flags) const
2040{
2041 QModelIndexList result;
2042 uint matchType = flags & 0x0F;
2043 Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
2044 bool recurse = flags & Qt::MatchRecursive;
2045 bool wrap = flags & Qt::MatchWrap;
2046 bool allHits = (hits == -1);
2047 QString text; // only convert to a string if it is needed
2048 QModelIndex p = parent(start);
2049 int from = start.row();
2050 int to = rowCount(p);
2051
2052 // iterates twice if wrapping
2053 for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
2054 for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) {
2055 QModelIndex idx = index(r, start.column(), p);
2056 if (!idx.isValid())
2057 continue;
2058 QVariant v = data(idx, role);
2059 // QVariant based matching
2060 if (matchType == Qt::MatchExactly) {
2061 if (value == v)
2062 result.append(idx);
2063 } else { // QString based matching
2064 if (text.isEmpty()) // lazy conversion
2065 text = value.toString();
2066 QString t = v.toString();
2067 switch (matchType) {
2068 case Qt::MatchRegExp:
2069 if (QRegExp(text, cs).exactMatch(t))
2070 result.append(idx);
2071 break;
2072 case Qt::MatchWildcard:
2073 if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t))
2074 result.append(idx);
2075 break;
2076 case Qt::MatchStartsWith:
2077 if (t.startsWith(text, cs))
2078 result.append(idx);
2079 break;
2080 case Qt::MatchEndsWith:
2081 if (t.endsWith(text, cs))
2082 result.append(idx);
2083 break;
2084 case Qt::MatchFixedString:
2085 if (t.compare(text, cs) == 0)
2086 result.append(idx);
2087 break;
2088 case Qt::MatchContains:
2089 default:
2090 if (t.contains(text, cs))
2091 result.append(idx);
2092 }
2093 }
2094 if (recurse && hasChildren(idx)) { // search the hierarchy
2095 result += match(index(0, idx.column(), idx), role,
2096 (text.isEmpty() ? value : text),
2097 (allHits ? -1 : hits - result.count()), flags);
2098 }
2099 }
2100 // prepare for the next iteration
2101 from = 0;
2102 to = start.row();
2103 }
2104 return result;
2105}
2106
2107/*!
2108 Returns the row and column span of the item represented by \a index.
2109
2110 \note Currently, span is not used.
2111*/
2112
2113QSize QAbstractItemModel::span(const QModelIndex &) const
2114{
2115 return QSize(1, 1);
2116}
2117
2118/*!
2119 \since 4.6
2120
2121 Sets the model's role names to \a roleNames.
2122
2123 This function allows mapping of role identifiers to role property names in
2124 Declarative UI. This function must be called before the model is used.
2125 Modifying the role names after the model has been set may result in
2126 undefined behaviour.
2127
2128 \sa roleNames()
2129*/
2130void QAbstractItemModel::setRoleNames(const QHash<int,QByteArray> &roleNames)
2131{
2132 Q_D(QAbstractItemModel);
2133 d->roleNames = roleNames;
2134}
2135
2136/*!
2137 \since 4.6
2138
2139 Returns the model's role names.
2140
2141 \sa setRoleNames()
2142*/
2143const QHash<int,QByteArray> &QAbstractItemModel::roleNames() const
2144{
2145 Q_D(const QAbstractItemModel);
2146 return d->roleNames;
2147}
2148
2149/*!
2150 Lets the model know that it should submit cached information to permanent
2151 storage. This function is typically used for row editing.
2152
2153 Returns true if there is no error; otherwise returns false.
2154
2155 \sa revert()
2156*/
2157
2158bool QAbstractItemModel::submit()
2159{
2160 return true;
2161}
2162
2163/*!
2164 Lets the model know that it should discard cached information. This
2165 function is typically used for row editing.
2166
2167 \sa submit()
2168*/
2169
2170void QAbstractItemModel::revert()
2171{
2172 // do nothing
2173}
2174
2175/*!
2176 Returns the data for the given \a role and \a section in the header with
2177 the specified \a orientation.
2178
2179 For horizontal headers, the section number corresponds to the column
2180 number. Similarly, for vertical headers, the section number corresponds to
2181 the row number.
2182
2183 \sa Qt::ItemDataRole, setHeaderData(), QHeaderView
2184*/
2185
2186QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const
2187{
2188 Q_UNUSED(orientation);
2189 if (role == Qt::DisplayRole)
2190 return section + 1;
2191 return QVariant();
2192}
2193
2194/*!
2195 Sets the data for the given \a role and \a section in the header with the
2196 specified \a orientation to the \a value supplied.
2197
2198 Returns true if the header's data was updated; otherwise returns false.
2199
2200 When reimplementing this function, the headerDataChanged() signal must be
2201 emitted explicitly.
2202
2203 \sa Qt::ItemDataRole, headerData()
2204*/
2205
2206bool QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation,
2207 const QVariant &value, int role)
2208{
2209 Q_UNUSED(section);
2210 Q_UNUSED(orientation);
2211 Q_UNUSED(value);
2212 Q_UNUSED(role);
2213 return false;
2214}
2215
2216/*!
2217 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, void *ptr) const
2218
2219 Creates a model index for the given \a row and \a column with the internal
2220 pointer \a ptr.
2221
2222 When using a QSortFilterProxyModel, its indexes have their own internal
2223 pointer. It is not advisable to access this internal pointer outside of the
2224 model. Use the data() function instead.
2225
2226 This function provides a consistent interface that model subclasses must
2227 use to create model indexes.
2228*/
2229
2230/*!
2231 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, int id) const
2232 \obsolete
2233
2234 Use QModelIndex
2235 QAbstractItemModel::createIndex(int row, int column, quint32 id) instead.
2236*/
2237
2238/*!
2239 \fn QModelIndex QAbstractItemModel::createIndex(int row, int column, quint32 id) const
2240
2241 Creates a model index for the given \a row and \a column with the internal
2242 identifier, \a id.
2243
2244 This function provides a consistent interface that model subclasses must
2245 use to create model indexes.
2246
2247 \sa QModelIndex::internalId()
2248*/
2249
2250/*!
2251 \internal
2252*/
2253void QAbstractItemModel::encodeData(const QModelIndexList &indexes, QDataStream &stream) const
2254{
2255 QModelIndexList::ConstIterator it = indexes.begin();
2256 for (; it != indexes.end(); ++it)
2257 stream << (*it).row() << (*it).column() << itemData(*it);
2258}
2259
2260/*!
2261 \internal
2262 */
2263bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &parent,
2264 QDataStream &stream)
2265{
2266 int top = INT_MAX;
2267 int left = INT_MAX;
2268 int bottom = 0;
2269 int right = 0;
2270 QVector<int> rows, columns;
2271 QVector<QMap<int, QVariant> > data;
2272
2273 while (!stream.atEnd()) {
2274 int r, c;
2275 QMap<int, QVariant> v;
2276 stream >> r >> c >> v;
2277 rows.append(r);
2278 columns.append(c);
2279 data.append(v);
2280 top = qMin(r, top);
2281 left = qMin(c, left);
2282 bottom = qMax(r, bottom);
2283 right = qMax(c, right);
2284 }
2285
2286 // insert the dragged items into the table, use a bit array to avoid overwriting items,
2287 // since items from different tables can have the same row and column
2288 int dragRowCount = 0;
2289 int dragColumnCount = right - left + 1;
2290
2291 // Compute the number of continuous rows upon insertion and modify the rows to match
2292 QVector<int> rowsToInsert(bottom + 1);
2293 for (int i = 0; i < rows.count(); ++i)
2294 rowsToInsert[rows.at(i)] = 1;
2295 for (int i = 0; i < rowsToInsert.count(); ++i) {
2296 if (rowsToInsert[i] == 1){
2297 rowsToInsert[i] = dragRowCount;
2298 ++dragRowCount;
2299 }
2300 }
2301 for (int i = 0; i < rows.count(); ++i)
2302 rows[i] = top + rowsToInsert[rows[i]];
2303
2304 QBitArray isWrittenTo(dragRowCount * dragColumnCount);
2305
2306 // make space in the table for the dropped data
2307 int colCount = columnCount(parent);
2308 if (colCount == 0) {
2309 insertColumns(colCount, dragColumnCount - colCount, parent);
2310 colCount = columnCount(parent);
2311 }
2312 insertRows(row, dragRowCount, parent);
2313
2314 row = qMax(0, row);
2315 column = qMax(0, column);
2316
2317 QVector<QPersistentModelIndex> newIndexes(data.size());
2318 // set the data in the table
2319 for (int j = 0; j < data.size(); ++j) {
2320 int relativeRow = rows.at(j) - top;
2321 int relativeColumn = columns.at(j) - left;
2322 int destinationRow = relativeRow + row;
2323 int destinationColumn = relativeColumn + column;
2324 int flat = (relativeRow * dragColumnCount) + relativeColumn;
2325 // if the item was already written to, or we just can't fit it in the table, create a new row
2326 if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) {
2327 destinationColumn = qBound(column, destinationColumn, colCount - 1);
2328 destinationRow = row + dragRowCount;
2329 insertRows(row + dragRowCount, 1, parent);
2330 flat = (dragRowCount * dragColumnCount) + relativeColumn;
2331 isWrittenTo.resize(++dragRowCount * dragColumnCount);
2332 }
2333 if (!isWrittenTo.testBit(flat)) {
2334 newIndexes[j] = index(destinationRow, destinationColumn, parent);
2335 isWrittenTo.setBit(flat);
2336 }
2337 }
2338
2339 for(int k = 0; k < newIndexes.size(); k++) {
2340 if (newIndexes.at(k).isValid())
2341 setItemData(newIndexes.at(k), data.at(k));
2342 }
2343
2344 return true;
2345}
2346
2347/*!
2348 Begins a row insertion operation.
2349
2350 When reimplementing insertRows() in a subclass, you must call this function
2351 \e before inserting data into the model's underlying data store.
2352
2353 The \a parent index corresponds to the parent into which the new rows are
2354 inserted; \a first and \a last are the row numbers that the new rows will
2355 have after they have been inserted.
2356
2357 \table 80%
2358 \row
2359 \o \inlineimage modelview-begin-insert-rows.png Inserting rows
2360 \o Specify the first and last row numbers for the span of rows you
2361 want to insert into an item in a model.
2362
2363 For example, as shown in the diagram, we insert three rows before
2364 row 2, so \a first is 2 and \a last is 4:
2365
2366 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 0
2367
2368 This inserts the three new rows as rows 2, 3, and 4.
2369 \row
2370 \o \inlineimage modelview-begin-append-rows.png Appending rows
2371 \o To append rows, insert them after the last row.
2372
2373 For example, as shown in the diagram, we append two rows to a
2374 collection of 4 existing rows (ending in row 3), so \a first is 4
2375 and \a last is 5:
2376
2377 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 1
2378
2379 This appends the two new rows as rows 4 and 5.
2380 \endtable
2381
2382 \note This function emits the rowsAboutToBeInserted() signal which
2383 connected views (or proxies) must handle before the data is inserted.
2384 Otherwise, the views may end up in an invalid state.
2385 \sa endInsertRows()
2386*/
2387void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
2388{
2389 Q_ASSERT(first >= 0);
2390 Q_ASSERT(last >= first);
2391 Q_D(QAbstractItemModel);
2392 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2393 emit rowsAboutToBeInserted(parent, first, last);
2394 d->rowsAboutToBeInserted(parent, first, last);
2395}
2396
2397/*!
2398 Ends a row insertion operation.
2399
2400 When reimplementing insertRows() in a subclass, you must call this function
2401 \e after inserting data into the model's underlying data store.
2402
2403 \sa beginInsertRows()
2404*/
2405void QAbstractItemModel::endInsertRows()
2406{
2407 Q_D(QAbstractItemModel);
2408 QAbstractItemModelPrivate::Change change = d->changes.pop();
2409 d->rowsInserted(change.parent, change.first, change.last);
2410 emit rowsInserted(change.parent, change.first, change.last);
2411}
2412
2413/*!
2414 Begins a row removal operation.
2415
2416 When reimplementing removeRows() in a subclass, you must call this
2417 function \e before removing data from the model's underlying data store.
2418
2419 The \a parent index corresponds to the parent from which the new rows are
2420 removed; \a first and \a last are the row numbers of the rows to be
2421 removed.
2422
2423 \table 80%
2424 \row
2425 \o \inlineimage modelview-begin-remove-rows.png Removing rows
2426 \o Specify the first and last row numbers for the span of rows you
2427 want to remove from an item in a model.
2428
2429 For example, as shown in the diagram, we remove the two rows from
2430 row 2 to row 3, so \a first is 2 and \a last is 3:
2431
2432 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 2
2433 \endtable
2434
2435 \note This function emits the rowsAboutToBeRemoved() signal which connected
2436 views (or proxies) must handle before the data is removed. Otherwise, the
2437 views may end up in an invalid state.
2438
2439 \sa endRemoveRows()
2440*/
2441void QAbstractItemModel::beginRemoveRows(const QModelIndex &parent, int first, int last)
2442{
2443 Q_ASSERT(first >= 0);
2444 Q_ASSERT(last >= first);
2445 Q_D(QAbstractItemModel);
2446 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2447 emit rowsAboutToBeRemoved(parent, first, last);
2448 d->rowsAboutToBeRemoved(parent, first, last);
2449}
2450
2451/*!
2452 Ends a row removal operation.
2453
2454 When reimplementing removeRows() in a subclass, you must call this function
2455 \e after removing data from the model's underlying data store.
2456
2457 \sa beginRemoveRows()
2458*/
2459void QAbstractItemModel::endRemoveRows()
2460{
2461 Q_D(QAbstractItemModel);
2462 QAbstractItemModelPrivate::Change change = d->changes.pop();
2463 d->rowsRemoved(change.parent, change.first, change.last);
2464 emit rowsRemoved(change.parent, change.first, change.last);
2465}
2466
2467/*!
2468 Returns whether a move operation is valid.
2469
2470 A move operation is not allowed if it moves a continuous range of rows to a destination within
2471 itself, or if it attempts to move a row to one of its own descendants.
2472
2473 \internal
2474*/
2475bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int start, int end, const QModelIndex &destinationParent, int destinationStart, Qt::Orientation orientation)
2476{
2477 // Don't move the range within itself.
2478 if (destinationParent == srcParent)
2479 return !(destinationStart >= start && destinationStart <= end + 1);
2480
2481 QModelIndex destinationAncestor = destinationParent;
2482 int pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
2483 forever {
2484 if (destinationAncestor == srcParent) {
2485 if (pos >= start && pos <= end)
2486 return false;
2487 break;
2488 }
2489
2490 if (!destinationAncestor.isValid())
2491 break;
2492
2493 pos = (Qt::Vertical == orientation) ? destinationAncestor.row() : destinationAncestor.column();
2494 destinationAncestor = destinationAncestor.parent();
2495 }
2496
2497 return true;
2498}
2499
2500/*!
2501 Begins a row move operation.
2502
2503 When reimplementing a subclass, this method simplifies moving
2504 entities in your model. This method is responsible for moving
2505 persistent indexes in the model, which you would otherwise be
2506 required to do yourself.
2507
2508 Using beginMoveRows and endMoveRows is an alternative to emitting
2509 layoutAboutToBeChanged and layoutChanged directly along with
2510 changePersistentIndexes. layoutAboutToBeChanged is emitted by
2511 this method for compatibility reasons.
2512
2513 The \a sourceParent index corresponds to the parent from which the
2514 rows are moved; \a sourceFirst and \a sourceLast are the row
2515 numbers of the rows to be moved. The \a destinationParent index
2516 corresponds to the parent into which the rows are moved. The \a
2517 destinationChild is the row to which the rows will be moved. That
2518 is, the index at row \a sourceFirst in \a sourceParent will become
2519 row \a destinationChild in \a destinationParent. Its siblings will
2520 be moved correspondingly.
2521
2522 Note that \a sourceParent and \a destinationParent may be the
2523 same, in which case you must ensure that the \a destinationChild is
2524 not within the range of \a sourceFirst and \a sourceLast. You
2525 must also ensure that you do not attempt to move a row to one of
2526 its own chilren or ancestors. This method returns false if either
2527 condition is true, in which case you should abort your move
2528 operation.
2529
2530 \sa endMoveRows()
2531
2532 \since 4.6
2533*/
2534bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
2535{
2536 Q_ASSERT(sourceFirst >= 0);
2537 Q_ASSERT(sourceLast >= sourceFirst);
2538 Q_ASSERT(destinationChild >= 0);
2539 Q_D(QAbstractItemModel);
2540
2541 if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical)) {
2542 return false;
2543 }
2544
2545 d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast));
2546 int destinationLast = destinationChild + (sourceLast - sourceFirst);
2547 d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast));
2548
2549 emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild);
2550 emit layoutAboutToBeChanged();
2551 d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical);
2552 return true;
2553}
2554
2555/*!
2556 Ends a row move operation.
2557
2558 When implementing a subclass, you must call this
2559 function \e after moving data within the model's underlying data
2560 store.
2561
2562 layoutChanged is emitted by this method for compatibility reasons.
2563
2564 \sa beginMoveRows()
2565
2566 \since 4.6
2567*/
2568void QAbstractItemModel::endMoveRows()
2569{
2570 Q_D(QAbstractItemModel);
2571
2572 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
2573 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
2574
2575 d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Vertical);
2576
2577 emit rowsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first);
2578 emit layoutChanged();
2579}
2580
2581/*!
2582 Begins a column insertion operation.
2583
2584 When reimplementing insertColumns() in a subclass, you must call this
2585 function \e before inserting data into the model's underlying data store.
2586
2587 The \a parent index corresponds to the parent into which the new columns
2588 are inserted; \a first and \a last are the column numbers of the new
2589 columns will have after they have been inserted.
2590
2591 \table 80%
2592 \row
2593 \o \inlineimage modelview-begin-insert-columns.png Inserting columns
2594 \o Specify the first and last column numbers for the span of columns
2595 you want to insert into an item in a model.
2596
2597 For example, as shown in the diagram, we insert three columns
2598 before column 4, so \a first is 4 and \a last is 6:
2599
2600 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 3
2601
2602 This inserts the three new columns as columns 4, 5, and 6.
2603 \row
2604 \o \inlineimage modelview-begin-append-columns.png Appending columns
2605 \o To append columns, insert them after the last column.
2606
2607 For example, as shown in the diagram, we append three columns to a
2608 collection of six existing columns (ending in column 5), so
2609 \a first is 6 and \a last is 8:
2610
2611 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 4
2612
2613 This appends the two new columns as columns 6, 7, and 8.
2614 \endtable
2615
2616 \note This function emits the columnsAboutToBeInserted() signal which
2617 connected views (or proxies) must handle before the data is inserted.
2618 Otherwise, the views may end up in an invalid state.
2619
2620 \sa endInsertColumns()
2621*/
2622void QAbstractItemModel::beginInsertColumns(const QModelIndex &parent, int first, int last)
2623{
2624 Q_ASSERT(first >= 0);
2625 Q_ASSERT(last >= first);
2626 Q_D(QAbstractItemModel);
2627 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2628 emit columnsAboutToBeInserted(parent, first, last);
2629 d->columnsAboutToBeInserted(parent, first, last);
2630}
2631
2632/*!
2633 Ends a column insertion operation.
2634
2635 When reimplementing insertColumns() in a subclass, you must call this
2636 function \e after inserting data into the model's underlying data
2637 store.
2638
2639 \sa beginInsertColumns()
2640*/
2641void QAbstractItemModel::endInsertColumns()
2642{
2643 Q_D(QAbstractItemModel);
2644 QAbstractItemModelPrivate::Change change = d->changes.pop();
2645 d->columnsInserted(change.parent, change.first, change.last);
2646 emit columnsInserted(change.parent, change.first, change.last);
2647}
2648
2649/*!
2650 Begins a column removal operation.
2651
2652 When reimplementing removeColumns() in a subclass, you must call this
2653 function \e before removing data from the model's underlying data store.
2654
2655 The \a parent index corresponds to the parent from which the new columns
2656 are removed; \a first and \a last are the column numbers of the first and
2657 last columns to be removed.
2658
2659 \table 80%
2660 \row
2661 \o \inlineimage modelview-begin-remove-columns.png Removing columns
2662 \o Specify the first and last column numbers for the span of columns
2663 you want to remove from an item in a model.
2664
2665 For example, as shown in the diagram, we remove the three columns
2666 from column 4 to column 6, so \a first is 4 and \a last is 6:
2667
2668 \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 5
2669 \endtable
2670
2671 \note This function emits the columnsAboutToBeRemoved() signal which
2672 connected views (or proxies) must handle before the data is removed.
2673 Otherwise, the views may end up in an invalid state.
2674
2675 \sa endRemoveColumns()
2676*/
2677void QAbstractItemModel::beginRemoveColumns(const QModelIndex &parent, int first, int last)
2678{
2679 Q_ASSERT(first >= 0);
2680 Q_ASSERT(last >= first);
2681 Q_D(QAbstractItemModel);
2682 d->changes.push(QAbstractItemModelPrivate::Change(parent, first, last));
2683 emit columnsAboutToBeRemoved(parent, first, last);
2684 d->columnsAboutToBeRemoved(parent, first, last);
2685}
2686
2687/*!
2688 Ends a column removal operation.
2689
2690 When reimplementing removeColumns() in a subclass, you must call this
2691 function \e after removing data from the model's underlying data store.
2692
2693 \sa beginRemoveColumns()
2694*/
2695void QAbstractItemModel::endRemoveColumns()
2696{
2697 Q_D(QAbstractItemModel);
2698 QAbstractItemModelPrivate::Change change = d->changes.pop();
2699 d->columnsRemoved(change.parent, change.first, change.last);
2700 emit columnsRemoved(change.parent, change.first, change.last);
2701}
2702
2703/*!
2704 Begins a column move operation.
2705
2706 When reimplementing a subclass, this method simplifies moving
2707 entities in your model. This method is responsible for moving
2708 persistent indexes in the model, which you would otherwise be
2709 required to do yourself.
2710
2711 Using beginMoveColumns and endMoveColumns is an alternative to
2712 emitting layoutAboutToBeChanged and layoutChanged directly along
2713 with changePersistentIndexes. layoutAboutToBeChanged is emitted
2714 by this method for compatibility reasons.
2715
2716 The \a sourceParent index corresponds to the parent from which the
2717 columns are moved; \a sourceFirst and \a sourceLast are the column
2718 numbers of the columns to be moved. The \a destinationParent index
2719 corresponds to the parent into which the columns are moved. The \a
2720 destinationChild is the column to which the columns will be
2721 moved. That is, the index at column \a sourceFirst in \a
2722 sourceParent will become column \a destinationChild in \a
2723 destinationParent. Its siblings will be moved correspondingly.
2724
2725 Note that \a sourceParent and \a destinationParent may be the
2726 same, in which case you must ensure that the \a destinationChild
2727 is not within the range of \a sourceFirst and \a sourceLast. You
2728 must also ensure that you do not attempt to move a row to one of
2729 its own chilren or ancestors. This method returns false if either
2730 condition is true, in which case you should abort your move
2731 operation.
2732
2733 \sa endMoveColumns()
2734
2735 \since 4.6
2736*/
2737bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationChild)
2738{
2739 Q_ASSERT(sourceFirst >= 0);
2740 Q_ASSERT(sourceLast >= sourceFirst);
2741 Q_ASSERT(destinationChild >= 0);
2742 Q_D(QAbstractItemModel);
2743
2744 if (!d->allowMove(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal)) {
2745 return false;
2746 }
2747
2748 d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast));
2749 int destinationLast = destinationChild + (sourceLast - sourceFirst);
2750 d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast));
2751
2752 d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal);
2753
2754 emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild);
2755 emit layoutAboutToBeChanged();
2756 return true;
2757}
2758
2759/*!
2760 Ends a column move operation.
2761
2762 When implementing a subclass, you must call this
2763 function \e after moving data within the model's underlying data
2764 store.
2765
2766 layoutChanged is emitted by this method for compatibility reasons.
2767
2768 \sa beginMoveColumns()
2769
2770 \since 4.6
2771*/
2772void QAbstractItemModel::endMoveColumns()
2773{
2774 Q_D(QAbstractItemModel);
2775
2776 QAbstractItemModelPrivate::Change insertChange = d->changes.pop();
2777 QAbstractItemModelPrivate::Change removeChange = d->changes.pop();
2778
2779 d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Horizontal);
2780
2781 emit columnsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first);
2782 emit layoutChanged();
2783}
2784
2785/*!
2786 Resets the model to its original state in any attached views.
2787
2788 \note Use beginResetModel() and endResetModel() instead whenever possible.
2789 Use this method only if there is no way to call beginResetModel() before invalidating the model.
2790 Otherwise it could lead to unexcpected behaviour, especially when used with proxy models.
2791*/
2792void QAbstractItemModel::reset()
2793{
2794 Q_D(QAbstractItemModel);
2795 emit modelAboutToBeReset();
2796 d->invalidatePersistentIndexes();
2797 emit modelReset();
2798}
2799
2800/*!
2801 Begins a model reset operation.
2802
2803 A reset operation resets the model to its current state in any attached views.
2804
2805 \note Any views attached to this model will be reset as well.
2806
2807 When a model is reset it means that any previous data reported from the
2808 model is now invalid and has to be queried for again. This also means that
2809 the current item and any selected items will become invalid.
2810
2811 When a model radically changes its data it can sometimes be easier to just
2812 call this function rather than emit dataChanged() to inform other
2813 components when the underlying data source, or its structure, has changed.
2814
2815 You must call this function before resetting any internal data structures in your model
2816 or proxy model.
2817
2818 \sa modelAboutToBeReset(), modelReset(), endResetModel()
2819 \since 4.6
2820*/
2821void QAbstractItemModel::beginResetModel()
2822{
2823 emit modelAboutToBeReset();
2824}
2825
2826/*!
2827 Completes a model reset operation.
2828
2829 You must call this function after resetting any internal data structure in your model
2830 or proxy model.
2831
2832 \sa beginResetModel()
2833 \since 4.6
2834*/
2835void QAbstractItemModel::endResetModel()
2836{
2837 Q_D(QAbstractItemModel);
2838 d->invalidatePersistentIndexes();
2839 emit modelReset();
2840}
2841
2842/*!
2843 Changes the QPersistentModelIndex that is equal to the given \a from model
2844 index to the given \a to model index.
2845
2846 If no persistent model index equal to the given \a from model index was
2847 found, nothing is changed.
2848
2849 \sa persistentIndexList(), changePersistentIndexList()
2850*/
2851void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QModelIndex &to)
2852{
2853 Q_D(QAbstractItemModel);
2854 if (d->persistent.indexes.isEmpty())
2855 return;
2856 // find the data and reinsert it sorted
2857 const QHash<QModelIndex, QPersistentModelIndexData *>::iterator it = d->persistent.indexes.find(from);
2858 if (it != d->persistent.indexes.end()) {
2859 QPersistentModelIndexData *data = *it;
2860 d->persistent.indexes.erase(it);
2861 data->index = to;
2862 if (to.isValid())
2863 d->persistent.insertMultiAtEnd(to, data);
2864 else
2865 data->model = 0;
2866 }
2867}
2868
2869/*!
2870 \since 4.1
2871
2872 Changes the QPersistentModelIndexes that is equal to the indexes in the
2873 given \a from model index list to the given \a to model index list.
2874
2875 If no persistent model indexes equal to the indexes in the given \a from
2876 model index list was found, nothing is changed.
2877
2878 \sa persistentIndexList(), changePersistentIndex()
2879*/
2880void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
2881 const QModelIndexList &to)
2882{
2883 Q_D(QAbstractItemModel);
2884 if (d->persistent.indexes.isEmpty())
2885 return;
2886 QVector<QPersistentModelIndexData *> toBeReinserted;
2887 toBeReinserted.reserve(to.count());
2888 for (int i = 0; i < from.count(); ++i) {
2889 if (from.at(i) == to.at(i))
2890 continue;
2891 const QHash<QModelIndex, QPersistentModelIndexData *>::iterator it = d->persistent.indexes.find(from.at(i));
2892 if (it != d->persistent.indexes.end()) {
2893 QPersistentModelIndexData *data = *it;
2894 d->persistent.indexes.erase(it);
2895 data->index = to.at(i);
2896 if (data->index.isValid())
2897 toBeReinserted << data;
2898 else
2899 data->model = 0;
2900 }
2901 }
2902
2903 for (QVector<QPersistentModelIndexData *>::const_iterator it = toBeReinserted.constBegin();
2904 it != toBeReinserted.constEnd() ; ++it) {
2905 QPersistentModelIndexData *data = *it;
2906 d->persistent.insertMultiAtEnd(data->index, data);
2907 }
2908}
2909
2910/*!
2911 \since 4.2
2912
2913 Returns the list of indexes stored as persistent indexes in the model.
2914*/
2915QModelIndexList QAbstractItemModel::persistentIndexList() const
2916{
2917 Q_D(const QAbstractItemModel);
2918 QModelIndexList result;
2919 for (QHash<QModelIndex, QPersistentModelIndexData *>::const_iterator it = d->persistent.indexes.constBegin();
2920 it != d->persistent.indexes.constEnd(); ++it) {
2921 QPersistentModelIndexData *data = *it;
2922 result.append(data->index);
2923 }
2924 return result;
2925}
2926
2927
2928/*!
2929 \class QAbstractTableModel
2930 \brief The QAbstractTableModel class provides an abstract model that can be
2931 subclassed to create table models.
2932
2933 \ingroup model-view
2934
2935 QAbstractTableModel provides a standard interface for models that represent
2936 their data as a two-dimensional array of items. It is not used directly,
2937 but must be subclassed.
2938
2939 Since the model provides a more specialized interface than
2940 QAbstractItemModel, it is not suitable for use with tree views, although it
2941 can be used to provide data to a QListView. If you need to represent a
2942 simple list of items, and only need a model to contain a single column of
2943 data, subclassing the QAbstractListModel may be more appropriate.
2944
2945 The rowCount() and columnCount() functions return the dimensions of the
2946 table. To retrieve a model index corresponding to an item in the model, use
2947 index() and provide only the row and column numbers.
2948
2949 \section1 Subclassing
2950
2951 When subclassing QAbstractTableModel, you must implement rowCount(),
2952 columnCount(), and data(). Default implementations of the index() and
2953 parent() functions are provided by QAbstractTableModel.
2954 Well behaved models will also implement headerData().
2955
2956 Editable models need to implement setData(), and implement flags() to
2957 return a value containing
2958 \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
2959
2960 Models that provide interfaces to resizable data structures can
2961 provide implementations of insertRows(), removeRows(), insertColumns(),
2962 and removeColumns(). When implementing these functions, it is
2963 important to call the appropriate functions so that all connected views
2964 are aware of any changes:
2965
2966 \list
2967 \o An insertRows() implementation must call beginInsertRows()
2968 \e before inserting new rows into the data structure, and it must
2969 call endInsertRows() \e{immediately afterwards}.
2970 \o An insertColumns() implementation must call beginInsertColumns()
2971 \e before inserting new columns into the data structure, and it must
2972 call endInsertColumns() \e{immediately afterwards}.
2973 \o A removeRows() implementation must call beginRemoveRows()
2974 \e before the rows are removed from the data structure, and it must
2975 call endRemoveRows() \e{immediately afterwards}.
2976 \o A removeColumns() implementation must call beginRemoveColumns()
2977 \e before the columns are removed from the data structure, and it must
2978 call endRemoveColumns() \e{immediately afterwards}.
2979 \endlist
2980
2981 \note Some general guidelines for subclassing models are available in the
2982 \l{Model Subclassing Reference}.
2983
2984 \note
2985
2986 \sa {Model Classes}, QAbstractItemModel, QAbstractListModel,
2987 {Pixelator Example}
2988*/
2989
2990/*!
2991 Constructs an abstract table model for the given \a parent.
2992*/
2993
2994QAbstractTableModel::QAbstractTableModel(QObject *parent)
2995 : QAbstractItemModel(parent)
2996{
2997
2998}
2999
3000/*!
3001 \internal
3002
3003 Constructs an abstract table model with \a dd and the given \a parent.
3004*/
3005
3006QAbstractTableModel::QAbstractTableModel(QAbstractItemModelPrivate &dd, QObject *parent)
3007 : QAbstractItemModel(dd, parent)
3008{
3009
3010}
3011
3012/*!
3013 Destroys the abstract table model.
3014*/
3015
3016QAbstractTableModel::~QAbstractTableModel()
3017{
3018
3019}
3020
3021/*!
3022 \fn QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
3023
3024 Returns the index of the data in \a row and \a column with \a parent.
3025
3026 \sa parent()
3027*/
3028
3029QModelIndex QAbstractTableModel::index(int row, int column, const QModelIndex &parent) const
3030{
3031 return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex();
3032}
3033
3034/*!
3035 \fn QModelIndex QAbstractTableModel::parent(const QModelIndex &index) const
3036
3037 Returns the parent of the model item with the given \a index.
3038
3039 \sa index() hasChildren()
3040*/
3041
3042QModelIndex QAbstractTableModel::parent(const QModelIndex &) const
3043{
3044 return QModelIndex();
3045}
3046
3047bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
3048{
3049 if (parent.model() == this || !parent.isValid())
3050 return rowCount(parent) > 0 && columnCount(parent) > 0;
3051 return false;
3052}
3053
3054/*!
3055 \class QAbstractListModel
3056 \brief The QAbstractListModel class provides an abstract model that can be
3057 subclassed to create one-dimensional list models.
3058
3059 \ingroup model-view
3060
3061 QAbstractListModel provides a standard interface for models that represent
3062 their data as a simple non-hierarchical sequence of items. It is not used
3063 directly, but must be subclassed.
3064
3065 Since the model provides a more specialized interface than
3066 QAbstractItemModel, it is not suitable for use with tree views; you will
3067 need to subclass QAbstractItemModel if you want to provide a model for
3068 that purpose. If you need to use a number of list models to manage data,
3069 it may be more appropriate to subclass QAbstractTableModel class instead.
3070
3071 Simple models can be created by subclassing this class and implementing
3072 the minimum number of required functions. For example, we could implement
3073 a simple read-only QStringList-based model that provides a list of strings
3074 to a QListView widget. In such a case, we only need to implement the
3075 rowCount() function to return the number of items in the list, and the
3076 data() function to retrieve items from the list.
3077
3078 Since the model represents a one-dimensional structure, the rowCount()
3079 function returns the total number of items in the model. The columnCount()
3080 function is implemented for interoperability with all kinds of views, but
3081 by default informs views that the model contains only one column.
3082
3083 \section1 Subclassing
3084
3085 When subclassing QAbstractListModel, you must provide implementations
3086 of the rowCount() and data() functions. Well behaved models also provide
3087 a headerData() implementation.
3088
3089 For editable list models, you must also provide an implementation of
3090 setData(), implement the flags() function so that it returns a value
3091 containing \l{Qt::ItemFlags}{Qt::ItemIsEditable}.
3092
3093 Note that QAbstractListModel provides a default implementation of
3094 columnCount() that informs views that there is only a single column
3095 of items in this model.
3096
3097 Models that provide interfaces to resizable list-like data structures
3098 can provide implementations of insertRows() and removeRows(). When
3099 implementing these functions, it is important to call the appropriate
3100 functions so that all connected views are aware of any changes:
3101
3102 \list
3103 \o An insertRows() implementation must call beginInsertRows()
3104 \e before inserting new rows into the data structure, and it must
3105 call endInsertRows() \e{immediately afterwards}.
3106 \o A removeRows() implementation must call beginRemoveRows()
3107 \e before the rows are removed from the data structure, and it must
3108 call endRemoveRows() \e{immediately afterwards}.
3109 \endlist
3110
3111 \note Some general guidelines for subclassing models are available in the
3112 \l{Model Subclassing Reference}.
3113
3114 \sa {Model Classes}, {Model Subclassing Reference}, QAbstractItemView,
3115 QAbstractTableModel, {Item Views Puzzle Example}
3116*/
3117
3118/*!
3119 Constructs an abstract list model with the given \a parent.
3120*/
3121
3122QAbstractListModel::QAbstractListModel(QObject *parent)
3123 : QAbstractItemModel(parent)
3124{
3125
3126}
3127
3128/*!
3129 \internal
3130
3131 Constructs an abstract list model with \a dd and the given \a parent.
3132*/
3133
3134QAbstractListModel::QAbstractListModel(QAbstractItemModelPrivate &dd, QObject *parent)
3135 : QAbstractItemModel(dd, parent)
3136{
3137
3138}
3139
3140/*!
3141 Destroys the abstract list model.
3142*/
3143
3144QAbstractListModel::~QAbstractListModel()
3145{
3146
3147}
3148
3149/*!
3150 \fn QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
3151
3152 Returns the index of the data in \a row and \a column with \a parent.
3153
3154 \sa parent()
3155*/
3156
3157QModelIndex QAbstractListModel::index(int row, int column, const QModelIndex &parent) const
3158{
3159 return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex();
3160}
3161
3162/*!
3163 Returns the parent of the model item with the given \a index.
3164
3165 \sa index() hasChildren()
3166*/
3167
3168QModelIndex QAbstractListModel::parent(const QModelIndex & /* index */) const
3169{
3170 return QModelIndex();
3171}
3172
3173/*!
3174 \internal
3175
3176 Returns the number of columns in the list with the given \a parent.
3177
3178 \sa rowCount()
3179*/
3180
3181int QAbstractListModel::columnCount(const QModelIndex &parent) const
3182{
3183 return parent.isValid() ? 0 : 1;
3184}
3185
3186bool QAbstractListModel::hasChildren(const QModelIndex &parent) const
3187{
3188 return parent.isValid() ? false : (rowCount() > 0);
3189}
3190
3191/*!
3192 \typedef QModelIndexList
3193 \relates QModelIndex
3194
3195 Synonym for QList<QModelIndex>.
3196*/
3197
3198/*!
3199 \reimp
3200*/
3201bool QAbstractTableModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
3202 int row, int column, const QModelIndex &parent)
3203{
3204 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
3205 return false;
3206
3207 QStringList types = mimeTypes();
3208 if (types.isEmpty())
3209 return false;
3210 QString format = types.at(0);
3211 if (!data->hasFormat(format))
3212 return false;
3213
3214 QByteArray encoded = data->data(format);
3215 QDataStream stream(&encoded, QIODevice::ReadOnly);
3216
3217 // if the drop is on an item, replace the data in the items
3218 if (parent.isValid() && row == -1 && column == -1) {
3219 int top = INT_MAX;
3220 int left = INT_MAX;
3221 QVector<int> rows, columns;
3222 QVector<QMap<int, QVariant> > data;
3223
3224 while (!stream.atEnd()) {
3225 int r, c;
3226 QMap<int, QVariant> v;
3227 stream >> r >> c >> v;
3228 rows.append(r);
3229 columns.append(c);
3230 data.append(v);
3231 top = qMin(r, top);
3232 left = qMin(c, left);
3233 }
3234
3235 for (int i = 0; i < data.size(); ++i) {
3236 int r = (rows.at(i) - top) + parent.row();
3237 int c = (columns.at(i) - left) + parent.column();
3238 if (hasIndex(r, c))
3239 setItemData(index(r, c), data.at(i));
3240 }
3241
3242 return true;
3243 }
3244
3245 // otherwise insert new rows for the data
3246 return decodeData(row, column, parent, stream);
3247}
3248
3249/*!
3250 \reimp
3251*/
3252bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
3253 int row, int column, const QModelIndex &parent)
3254{
3255 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
3256 return false;
3257
3258 QStringList types = mimeTypes();
3259 if (types.isEmpty())
3260 return false;
3261 QString format = types.at(0);
3262 if (!data->hasFormat(format))
3263 return false;
3264
3265 QByteArray encoded = data->data(format);
3266 QDataStream stream(&encoded, QIODevice::ReadOnly);
3267
3268 // if the drop is on an item, replace the data in the items
3269 if (parent.isValid() && row == -1 && column == -1) {
3270 int top = INT_MAX;
3271 int left = INT_MAX;
3272 QVector<int> rows, columns;
3273 QVector<QMap<int, QVariant> > data;
3274
3275 while (!stream.atEnd()) {
3276 int r, c;
3277 QMap<int, QVariant> v;
3278 stream >> r >> c >> v;
3279 rows.append(r);
3280 columns.append(c);
3281 data.append(v);
3282 top = qMin(r, top);
3283 left = qMin(c, left);
3284 }
3285
3286 for (int i = 0; i < data.size(); ++i) {
3287 int r = (rows.at(i) - top) + parent.row();
3288 if (columns.at(i) == left && hasIndex(r, 0))
3289 setItemData(index(r), data.at(i));
3290 }
3291
3292 return true;
3293 }
3294
3295 if (row == -1)
3296 row = rowCount(parent);
3297
3298 // otherwise insert new rows for the data
3299 return decodeData(row, column, parent, stream);
3300}
3301
3302/*!
3303 \fn QAbstractItemModel::modelAboutToBeReset()
3304 \since 4.2
3305
3306 This signal is emitted when reset() is called, before the model's internal
3307 state (e.g. persistent model indexes) has been invalidated.
3308
3309 \sa beginResetModel(), modelReset()
3310*/
3311
3312/*!
3313 \fn QAbstractItemModel::modelReset()
3314 \since 4.1
3315
3316 This signal is emitted when reset() is called, after the model's internal
3317 state (e.g. persistent model indexes) has been invalidated.
3318
3319 \sa endResetModel(), modelAboutToBeReset()
3320*/
3321
3322/*!
3323 \fn bool QModelIndex::operator<(const QModelIndex &other) const
3324 \since 4.1
3325
3326 Returns true if this model index is smaller than the \a other
3327 model index; otherwise returns false.
3328*/
3329
3330/*!
3331 \fn uint qHash(const QPersistentModelIndex &index)
3332 \since 4.5
3333
3334 Returns a hash of the QPersistentModelIndex
3335 */
3336
3337
3338/*!
3339 \internal
3340 QHash::insertMulti insert the value before the old value. and find() return the new value.
3341 We need insertMultiAtEnd because we don't want to overwrite the old one, which should be removed later
3342
3343 There should be only one instance QPersistentModelIndexData per index, but in some intermediate state there may be
3344 severals of PersistantModelIndex pointing to the same index, but one is already updated, and the other one is not.
3345 This make sure than when updating the first one we don't overwrite the second one in the hash, and the second one
3346 will be updated right later.
3347 */
3348void QAbstractItemModelPrivate::Persistent::insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data)
3349{
3350 QHash<QModelIndex,QPersistentModelIndexData *>::iterator newIt =
3351 indexes.insertMulti(key, data);
3352 QHash<QModelIndex,QPersistentModelIndexData *>::iterator it = newIt + 1;
3353 while (it != indexes.end() && it.key() == key) {
3354 qSwap(*newIt,*it);
3355 newIt = it;
3356 ++it;
3357 }
3358}
3359
3360QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.