source: trunk/src/gui/itemviews/qstandarditemmodel.cpp@ 104

Last change on this file since 104 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 85.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qstandarditemmodel.h"
43
44#ifndef QT_NO_STANDARDITEMMODEL
45
46#include <QtCore/qdatetime.h>
47#include <QtCore/qlist.h>
48#include <QtCore/qmap.h>
49#include <QtCore/qpair.h>
50#include <QtCore/qvariant.h>
51#include <QtCore/qvector.h>
52#include <QtCore/qstringlist.h>
53#include <QtCore/qbitarray.h>
54#include <QtCore/qmimedata.h>
55
56#include <private/qstandarditemmodel_p.h>
57#include <qdebug.h>
58
59QT_BEGIN_NAMESPACE
60
61class QStandardItemModelLessThan
62{
63public:
64 inline QStandardItemModelLessThan()
65 { }
66
67 inline bool operator()(const QPair<QStandardItem*, int> &l,
68 const QPair<QStandardItem*, int> &r) const
69 {
70 return *(l.first) < *(r.first);
71 }
72};
73
74class QStandardItemModelGreaterThan
75{
76public:
77 inline QStandardItemModelGreaterThan()
78 { }
79
80 inline bool operator()(const QPair<QStandardItem*, int> &l,
81 const QPair<QStandardItem*, int> &r) const
82 {
83 return *(r.first) < *(l.first);
84 }
85};
86
87/*!
88 \internal
89*/
90QStandardItemPrivate::~QStandardItemPrivate()
91{
92 QVector<QStandardItem*>::const_iterator it;
93 for (it = children.constBegin(); it != children.constEnd(); ++it) {
94 QStandardItem *child = *it;
95 if (child)
96 child->d_func()->setModel(0);
97 delete child;
98 }
99 children.clear();
100 if (parent && model)
101 parent->d_func()->childDeleted(q_func());
102}
103
104/*!
105 \internal
106*/
107QPair<int, int> QStandardItemPrivate::position() const
108{
109 if (QStandardItem *par = parent) {
110 int idx = par->d_func()->childIndex(q_func());
111 if (idx == -1)
112 return QPair<int, int>(-1, -1);
113 return QPair<int, int>(idx / par->columnCount(), idx % par->columnCount());
114 }
115 // ### support header items?
116 return QPair<int, int>(-1, -1);
117}
118
119/*!
120 \internal
121*/
122void QStandardItemPrivate::setChild(int row, int column, QStandardItem *item,
123 bool emitChanged)
124{
125 Q_Q(QStandardItem);
126 if (item == q) {
127 qWarning("QStandardItem::setChild: Can't make an item a child of itself %p",
128 item);
129 return;
130 }
131 if ((row < 0) || (column < 0))
132 return;
133 if (rows <= row)
134 q->setRowCount(row + 1);
135 if (columns <= column)
136 q->setColumnCount(column + 1);
137 int index = childIndex(row, column);
138 Q_ASSERT(index != -1);
139 QStandardItem *oldItem = children.at(index);
140 if (item == oldItem)
141 return;
142 if (item) {
143 if (item->d_func()->parent == 0) {
144 item->d_func()->setParentAndModel(q, model);
145 } else {
146 qWarning("QStandardItem::setChild: Ignoring duplicate insertion of item %p",
147 item);
148 return;
149 }
150 }
151 if (oldItem)
152 oldItem->d_func()->setModel(0);
153 delete oldItem;
154 children.replace(index, item);
155 if (emitChanged && model)
156 model->d_func()->itemChanged(item);
157}
158
159
160/*!
161 \internal
162*/
163void QStandardItemPrivate::changeFlags(bool enable, Qt::ItemFlags f)
164{
165 Q_Q(QStandardItem);
166 Qt::ItemFlags flags = q->flags();
167 if (enable)
168 flags |= f;
169 else
170 flags &= ~f;
171 q->setFlags(flags);
172}
173
174/*!
175 \internal
176*/
177void QStandardItemPrivate::childDeleted(QStandardItem *child)
178{
179 int index = childIndex(child);
180 Q_ASSERT(index != -1);
181 children.replace(index, 0);
182}
183
184/*!
185 \internal
186*/
187void QStandardItemPrivate::setItemData(const QMap<int, QVariant> &roles)
188{
189 Q_Q(QStandardItem);
190
191 //let's build the vector of new values
192 QVector<QWidgetItemData> newValues;
193 QMap<int, QVariant>::const_iterator it;
194 for (it = roles.begin(); it != roles.end(); ++it) {
195 QVariant value = it.value();
196 if (value.isValid()) {
197 int role = it.key();
198 role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
199 QWidgetItemData wid(role,it.value());
200 newValues.append(wid);
201 }
202 }
203
204 if (values!=newValues) {
205 values=newValues;
206 if (model)
207 model->d_func()->itemChanged(q);
208 }
209}
210
211/*!
212 \internal
213*/
214const QMap<int, QVariant> QStandardItemPrivate::itemData() const
215{
216 QMap<int, QVariant> result;
217 QVector<QWidgetItemData>::const_iterator it;
218 for (it = values.begin(); it != values.end(); ++it)
219 result.insert((*it).role, (*it).value);
220 return result;
221}
222
223/*!
224 \internal
225*/
226void QStandardItemPrivate::sortChildren(int column, Qt::SortOrder order)
227{
228 Q_Q(QStandardItem);
229 if (column >= columnCount())
230 return;
231
232 QVector<QPair<QStandardItem*, int> > sortable;
233 QVector<int> unsortable;
234
235 sortable.reserve(rowCount());
236 unsortable.reserve(rowCount());
237
238 for (int row = 0; row < rowCount(); ++row) {
239 QStandardItem *itm = q->child(row, column);
240 if (itm)
241 sortable.append(QPair<QStandardItem*,int>(itm, row));
242 else
243 unsortable.append(row);
244 }
245
246 if (order == Qt::AscendingOrder) {
247 QStandardItemModelLessThan lt;
248 qStableSort(sortable.begin(), sortable.end(), lt);
249 } else {
250 QStandardItemModelGreaterThan gt;
251 qStableSort(sortable.begin(), sortable.end(), gt);
252 }
253
254 QModelIndexList changedPersistentIndexesFrom, changedPersistentIndexesTo;
255 QVector<QStandardItem*> sorted_children(children.count());
256 for (int i = 0; i < rowCount(); ++i) {
257 int r = (i < sortable.count()
258 ? sortable.at(i).second
259 : unsortable.at(i - sortable.count()));
260 for (int c = 0; c < columnCount(); ++c) {
261 QStandardItem *itm = q->child(r, c);
262 sorted_children[childIndex(i, c)] = itm;
263 if (model) {
264 QModelIndex from = model->createIndex(r, c, q);
265 if (model->d_func()->persistent.indexes.contains(from)) {
266 QModelIndex to = model->createIndex(i, c, q);
267 changedPersistentIndexesFrom.append(from);
268 changedPersistentIndexesTo.append(to);
269 }
270 }
271 }
272 }
273
274 children = sorted_children;
275
276 if (model) {
277 model->changePersistentIndexList(changedPersistentIndexesFrom, changedPersistentIndexesTo);
278 }
279
280 QVector<QStandardItem*>::iterator it;
281 for (it = children.begin(); it != children.end(); ++it) {
282 if (*it)
283 (*it)->d_func()->sortChildren(column, order);
284 }
285}
286
287/*!
288 \internal
289 set the model of this item and all its children
290 */
291void QStandardItemPrivate::setModel(QStandardItemModel *mod)
292{
293 if (children.isEmpty()) {
294 if (model)
295 model->d_func()->invalidatePersistentIndex(model->indexFromItem(q_ptr));
296 model = mod;
297 } else {
298 QStack<QStandardItem*> stack;
299 stack.push(q_ptr);
300 while (!stack.isEmpty()) {
301 QStandardItem *itm = stack.pop();
302 if (itm->d_func()->model) {
303 itm->d_func()->model->d_func()->invalidatePersistentIndex(itm->d_func()->model->indexFromItem(itm));
304 }
305 itm->d_func()->model = mod;
306 const QVector<QStandardItem*> &childList = itm->d_func()->children;
307 for (int i = 0; i < childList.count(); ++i) {
308 QStandardItem *chi = childList.at(i);
309 if (chi)
310 stack.push(chi);
311 }
312 }
313 }
314}
315
316/*!
317 \internal
318*/
319QStandardItemModelPrivate::QStandardItemModelPrivate()
320 : root(new QStandardItem),
321 itemPrototype(0),
322 sortRole(Qt::DisplayRole)
323{
324 root->setFlags(Qt::ItemIsDropEnabled);
325}
326
327/*!
328 \internal
329*/
330QStandardItemModelPrivate::~QStandardItemModelPrivate()
331{
332 delete root;
333 delete itemPrototype;
334 qDeleteAll(columnHeaderItems);
335 qDeleteAll(rowHeaderItems);
336}
337
338/*!
339 \internal
340*/
341void QStandardItemModelPrivate::init()
342{
343 Q_Q(QStandardItemModel);
344 QObject::connect(q, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
345 q, SLOT(_q_emitItemChanged(QModelIndex,QModelIndex)));
346}
347
348/*!
349 \internal
350*/
351void QStandardItemModelPrivate::_q_emitItemChanged(const QModelIndex &topLeft,
352 const QModelIndex &bottomRight)
353{
354 Q_Q(QStandardItemModel);
355 QModelIndex parent = topLeft.parent();
356 for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
357 for (int column = topLeft.column(); column <= bottomRight.column(); ++column) {
358 QModelIndex index = q->index(row, column, parent);
359 if (QStandardItem *item = itemFromIndex(index))
360 emit q->itemChanged(item);
361 }
362 }
363}
364
365/*!
366 \internal
367*/
368bool QStandardItemPrivate::insertRows(int row, const QList<QStandardItem*> &items)
369{
370 Q_Q(QStandardItem);
371 if ((row < 0) || (row > rowCount()))
372 return false;
373 int count = items.count();
374 if (model)
375 model->d_func()->rowsAboutToBeInserted(q, row, row + count - 1);
376 if (rowCount() == 0) {
377 if (columnCount() == 0)
378 q->setColumnCount(1);
379 children.resize(columnCount() * count);
380 rows = count;
381 } else {
382 rows += count;
383 int index = childIndex(row, 0);
384 if (index != -1)
385 children.insert(index, columnCount() * count, 0);
386 }
387 for (int i = 0; i < items.count(); ++i) {
388 QStandardItem *item = items.at(i);
389 item->d_func()->model = model;
390 item->d_func()->parent = q;
391 int index = childIndex(i + row, 0);
392 children.replace(index, item);
393 }
394 if (model)
395 model->d_func()->rowsInserted(q, row, count);
396 return true;
397}
398
399bool QStandardItemPrivate::insertRows(int row, int count, const QList<QStandardItem*> &items)
400{
401 Q_Q(QStandardItem);
402 if ((count < 1) || (row < 0) || (row > rowCount()))
403 return false;
404 if (model)
405 model->d_func()->rowsAboutToBeInserted(q, row, row + count - 1);
406 if (rowCount() == 0) {
407 children.resize(columnCount() * count);
408 rows = count;
409 } else {
410 rows += count;
411 int index = childIndex(row, 0);
412 if (index != -1)
413 children.insert(index, columnCount() * count, 0);
414 }
415 if (!items.isEmpty()) {
416 int index = childIndex(row, 0);
417 int limit = qMin(items.count(), columnCount() * count);
418 for (int i = 0; i < limit; ++i) {
419 QStandardItem *item = items.at(i);
420 if (item) {
421 if (item->d_func()->parent == 0) {
422 item->d_func()->setParentAndModel(q, model);
423 } else {
424 qWarning("QStandardItem::insertRows: Ignoring duplicate insertion of item %p",
425 item);
426 item = 0;
427 }
428 }
429 children.replace(index, item);
430 ++index;
431 }
432 }
433 if (model)
434 model->d_func()->rowsInserted(q, row, count);
435 return true;
436}
437
438/*!
439 \internal
440*/
441bool QStandardItemPrivate::insertColumns(int column, int count, const QList<QStandardItem*> &items)
442{
443 Q_Q(QStandardItem);
444 if ((count < 1) || (column < 0) || (column > columnCount()))
445 return false;
446 if (model)
447 model->d_func()->columnsAboutToBeInserted(q, column, column + count - 1);
448 if (columnCount() == 0) {
449 children.resize(rowCount() * count);
450 columns = count;
451 } else {
452 columns += count;
453 int index = childIndex(0, column);
454 for (int row = 0; row < rowCount(); ++row) {
455 children.insert(index, count, 0);
456 index += columnCount();
457 }
458 }
459 if (!items.isEmpty()) {
460 int limit = qMin(items.count(), rowCount() * count);
461 for (int i = 0; i < limit; ++i) {
462 QStandardItem *item = items.at(i);
463 if (item) {
464 if (item->d_func()->parent == 0) {
465 item->d_func()->setParentAndModel(q, model);
466 } else {
467 qWarning("QStandardItem::insertColumns: Ignoring duplicate insertion of item %p",
468 item);
469 item = 0;
470 }
471 }
472 int r = i / count;
473 int c = column + (i % count);
474 int index = childIndex(r, c);
475 children.replace(index, item);
476 }
477 }
478 if (model)
479 model->d_func()->columnsInserted(q, column, count);
480 return true;
481}
482
483/*!
484 \internal
485*/
486void QStandardItemModelPrivate::itemChanged(QStandardItem *item)
487{
488 Q_Q(QStandardItemModel);
489 if (item->d_func()->parent == 0) {
490 // Header item
491 int idx = columnHeaderItems.indexOf(item);
492 if (idx != -1) {
493 emit q->headerDataChanged(Qt::Horizontal, idx, idx);
494 } else {
495 idx = rowHeaderItems.indexOf(item);
496 if (idx != -1)
497 emit q->headerDataChanged(Qt::Vertical, idx, idx);
498 }
499 } else {
500 // Normal item
501 QModelIndex index = q->indexFromItem(item);
502 emit q->dataChanged(index, index);
503 }
504}
505
506/*!
507 \internal
508*/
509void QStandardItemModelPrivate::rowsAboutToBeInserted(QStandardItem *parent,
510 int start, int end)
511{
512 Q_Q(QStandardItemModel);
513 QModelIndex index = q->indexFromItem(parent);
514 q->beginInsertRows(index, start, end);
515}
516
517/*!
518 \internal
519*/
520void QStandardItemModelPrivate::columnsAboutToBeInserted(QStandardItem *parent,
521 int start, int end)
522{
523 Q_Q(QStandardItemModel);
524 QModelIndex index = q->indexFromItem(parent);
525 q->beginInsertColumns(index, start, end);
526}
527
528/*!
529 \internal
530*/
531void QStandardItemModelPrivate::rowsAboutToBeRemoved(QStandardItem *parent,
532 int start, int end)
533{
534 Q_Q(QStandardItemModel);
535 QModelIndex index = q->indexFromItem(parent);
536 q->beginRemoveRows(index, start, end);
537}
538
539/*!
540 \internal
541*/
542void QStandardItemModelPrivate::columnsAboutToBeRemoved(QStandardItem *parent,
543 int start, int end)
544{
545 Q_Q(QStandardItemModel);
546 QModelIndex index = q->indexFromItem(parent);
547 q->beginRemoveColumns(index, start, end);
548}
549
550/*!
551 \internal
552*/
553void QStandardItemModelPrivate::rowsInserted(QStandardItem *parent,
554 int row, int count)
555{
556 Q_Q(QStandardItemModel);
557 if (parent == root)
558 rowHeaderItems.insert(row, count, 0);
559 q->endInsertRows();
560}
561
562/*!
563 \internal
564*/
565void QStandardItemModelPrivate::columnsInserted(QStandardItem *parent,
566 int column, int count)
567{
568 Q_Q(QStandardItemModel);
569 if (parent == root)
570 columnHeaderItems.insert(column, count, 0);
571 q->endInsertColumns();
572}
573
574/*!
575 \internal
576*/
577void QStandardItemModelPrivate::rowsRemoved(QStandardItem *parent,
578 int row, int count)
579{
580 Q_Q(QStandardItemModel);
581 if (parent == root) {
582 for (int i = row; i < row + count; ++i) {
583 QStandardItem *oldItem = rowHeaderItems.at(i);
584 if (oldItem)
585 oldItem->d_func()->setModel(0);
586 delete oldItem;
587 }
588 rowHeaderItems.remove(row, count);
589 }
590 q->endRemoveRows();
591}
592
593/*!
594 \internal
595*/
596void QStandardItemModelPrivate::columnsRemoved(QStandardItem *parent,
597 int column, int count)
598{
599 Q_Q(QStandardItemModel);
600 if (parent == root) {
601 for (int i = column; i < column + count; ++i) {
602 QStandardItem *oldItem = columnHeaderItems.at(i);
603 if (oldItem)
604 oldItem->d_func()->setModel(0);
605 delete oldItem;
606 }
607 columnHeaderItems.remove(column, count);
608 }
609 q->endRemoveColumns();
610}
611
612/*!
613 \class QStandardItem
614 \brief The QStandardItem class provides an item for use with the
615 QStandardItemModel class.
616 \since 4.2
617 \ingroup model-view
618
619 Items usually contain text, icons, or checkboxes.
620
621 Each item can have its own background brush which is set with the
622 setBackground() function. The current background brush can be found with
623 background(). The text label for each item can be rendered with its own
624 font and brush. These are specified with the setFont() and setForeground()
625 functions, and read with font() and foreground().
626
627 By default, items are enabled, editable, selectable, checkable, and can be
628 used both as the source of a drag and drop operation and as a drop target.
629 Each item's flags can be changed by calling setFlags(). Checkable items
630 can be checked and unchecked with the setCheckState() function. The
631 corresponding checkState() function indicates whether the item is
632 currently checked.
633
634 You can store application-specific data in an item by calling setData().
635
636 Each item can have a two-dimensional table of child items. This makes it
637 possible to build hierarchies of items. The typical hierarchy is the tree,
638 in which case the child table is a table with a single column (a list).
639
640 The dimensions of the child table can be set with setRowCount() and
641 setColumnCount(). Items can be positioned in the child table with
642 setChild(). Get a pointer to a child item with child(). New rows and
643 columns of children can also be inserted with insertRow() and
644 insertColumn(), or appended with appendRow() and appendColumn(). When
645 using the append and insert functions, the dimensions of the child table
646 will grow as needed.
647
648 An existing row of children can be removed with removeRow() or takeRow();
649 correspondingly, a column can be removed with removeColumn() or
650 takeColumn().
651
652 An item's children can be sorted by calling sortChildren().
653
654 \section1 Subclassing
655
656 When subclassing QStandardItem to provide custom items, it is possible to
657 define new types for them so that they can be distinguished from the base
658 class. The type() function should be reimplemented to return a new type
659 value equal to or greater than \l UserType.
660
661 Reimplement data() and setData() if you want to perform custom handling of
662 data queries and/or control how an item's data is represented.
663
664 Reimplement clone() if you want QStandardItemModel to be able to create
665 instances of your custom item class on demand (see
666 QStandardItemModel::setItemPrototype()).
667
668 Reimplement read() and write() if you want to control how items are
669 represented in their serialized form.
670
671 Reimplement \l{operator<()} if you want to control the semantics of item
672 comparison. \l{operator<()} determines the sorted order when sorting items
673 with sortChildren() or with QStandardItemModel::sort().
674
675 \sa QStandardItemModel, {Item View Convenience Classes}, {Model/View Programming}
676*/
677
678/*!
679 \enum QStandardItem::ItemType
680
681 This enum describes the types that are used to describe standard items.
682
683 \value Type The default type for standard items.
684 \value UserType The minimum value for custom types. Values below UserType are
685 reserved by Qt.
686
687 You can define new user types in QStandardItem subclasses to ensure that
688 custom items are treated specially; for example, when items are sorted.
689
690 \sa type()
691*/
692
693/*!
694 Constructs an item.
695*/
696QStandardItem::QStandardItem()
697 : d_ptr(new QStandardItemPrivate)
698{
699 Q_D(QStandardItem);
700 d->q_ptr = this;
701}
702
703/*!
704 Constructs an item with the given \a text.
705*/
706QStandardItem::QStandardItem(const QString &text)
707 : d_ptr(new QStandardItemPrivate)
708{
709 Q_D(QStandardItem);
710 d->q_ptr = this;
711 setText(text);
712}
713
714/*!
715 Constructs an item with the given \a icon and \a text.
716*/
717QStandardItem::QStandardItem(const QIcon &icon, const QString &text)
718 : d_ptr(new QStandardItemPrivate)
719{
720 Q_D(QStandardItem);
721 d->q_ptr = this;
722 setIcon(icon);
723 setText(text);
724}
725
726/*!
727 Constructs an item with \a rows rows and \a columns columns of child items.
728*/
729QStandardItem::QStandardItem(int rows, int columns)
730 : d_ptr(new QStandardItemPrivate)
731{
732 Q_D(QStandardItem);
733 d->q_ptr = this;
734 setRowCount(rows);
735 setColumnCount(columns);
736}
737
738/*!
739 \internal
740*/
741QStandardItem::QStandardItem(QStandardItemPrivate &dd)
742 : d_ptr(&dd)
743{
744 Q_D(QStandardItem);
745 d->q_ptr = this;
746}
747
748/*!
749 Constructs a copy of \a other. Note that model() is
750 not copied.
751
752 This function is useful when reimplementing clone().
753*/
754QStandardItem::QStandardItem(const QStandardItem &other)
755 : d_ptr(new QStandardItemPrivate)
756{
757 Q_D(QStandardItem);
758 d->q_ptr = this;
759 operator=(other);
760}
761
762/*!
763 Assigns \a other's data and flags to this item. Note that
764 type() and model() are not copied.
765
766 This function is useful when reimplementing clone().
767*/
768QStandardItem &QStandardItem::operator=(const QStandardItem &other)
769{
770 Q_D(QStandardItem);
771 d->values = other.d_func()->values;
772 return *this;
773}
774
775/*!
776 Destructs the item.
777 This causes the item's children to be destructed as well.
778*/
779QStandardItem::~QStandardItem()
780{
781 Q_D(QStandardItem);
782 delete d;
783}
784
785/*!
786 Returns the item's parent item, or 0 if the item has no parent.
787
788 \sa child()
789*/
790QStandardItem *QStandardItem::parent() const
791{
792 Q_D(const QStandardItem);
793 if (!d->model || (d->model->d_func()->root != d->parent))
794 return d->parent;
795 return 0;
796}
797
798/*!
799 Sets the item's data for the given \a role to the specified \a value.
800
801 If you subclass QStandardItem and reimplement this function, your
802 reimplementation should call emitDataChanged() if you do not call
803 the base implementation of setData(). This will ensure that e.g.
804 views using the model are notified of the changes.
805
806 \note The default implementation treats Qt::EditRole and Qt::DisplayRole
807 as referring to the same data.
808
809 \sa Qt::ItemDataRole, data(), setFlags()
810*/
811void QStandardItem::setData(const QVariant &value, int role)
812{
813 Q_D(QStandardItem);
814 role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
815 QVector<QWidgetItemData>::iterator it;
816 for (it = d->values.begin(); it != d->values.end(); ++it) {
817 if ((*it).role == role) {
818 if (value.isValid()) {
819 if ((*it).value.type() == value.type() && (*it).value == value)
820 return;
821 (*it).value = value;
822 } else {
823 d->values.erase(it);
824 }
825 if (d->model)
826 d->model->d_func()->itemChanged(this);
827 return;
828 }
829 }
830 d->values.append(QWidgetItemData(role, value));
831 if (d->model)
832 d->model->d_func()->itemChanged(this);
833}
834
835/*!
836 Returns the item's data for the given \a role, or an invalid
837 QVariant if there is no data for the role.
838
839 \note The default implementation treats Qt::EditRole and Qt::DisplayRole
840 as referring to the same data.
841*/
842QVariant QStandardItem::data(int role) const
843{
844 Q_D(const QStandardItem);
845 role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
846 QVector<QWidgetItemData>::const_iterator it;
847 for (it = d->values.begin(); it != d->values.end(); ++it) {
848 if ((*it).role == role)
849 return (*it).value;
850 }
851 return QVariant();
852}
853
854/*!
855 \since 4.4
856
857 Causes the model associated with this item to emit a
858 \l{QAbstractItemModel::dataChanged()}{dataChanged}() signal for this
859 item.
860
861 You normally only need to call this function if you have subclassed
862 QStandardItem and reimplemented data() and/or setData().
863
864 \sa setData()
865*/
866void QStandardItem::emitDataChanged()
867{
868 Q_D(QStandardItem);
869 if (d->model)
870 d->model->d_func()->itemChanged(this);
871}
872
873/*!
874 Sets the item flags for the item to \a flags.
875
876 The item flags determine how the user can interact with the item.
877 This is often used to disable an item.
878
879 \sa flags(), setData()
880*/
881void QStandardItem::setFlags(Qt::ItemFlags flags)
882{
883 setData((int)flags, Qt::UserRole - 1);
884}
885
886/*!
887 Returns the item flags for the item.
888
889 The item flags determine how the user can interact with the item.
890
891 By default, items are enabled, editable, selectable, checkable, and can be
892 used both as the source of a drag and drop operation and as a drop target.
893
894 \sa setFlags()
895*/
896Qt::ItemFlags QStandardItem::flags() const
897{
898 QVariant v = data(Qt::UserRole - 1);
899 if (!v.isValid())
900 return (Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable
901 |Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled);
902 return ((Qt::ItemFlags)(v.toInt()));
903}
904
905/*!
906 \fn QString QStandardItem::text() const
907
908 Returns the item's text. This is the text that's presented to the user
909 in a view.
910
911 \sa setText()
912*/
913
914/*!
915 \fn void QStandardItem::setText(const QString &text)
916
917 Sets the item's text to the \a text specified.
918
919 \sa text(), setFont(), setForeground()
920*/
921
922/*!
923 \fn QIcon QStandardItem::icon() const
924
925 Returns the item's icon.
926
927 \sa setIcon(), {QAbstractItemView::iconSize}{iconSize}
928*/
929
930/*!
931 \fn void QStandardItem::setIcon(const QIcon &icon)
932
933 Sets the item's icon to the \a icon specified.
934*/
935
936/*!
937 \fn QString QStandardItem::statusTip() const
938
939 Returns the item's status tip.
940
941 \sa setStatusTip(), toolTip(), whatsThis()
942*/
943
944/*!
945 \fn void QStandardItem::setStatusTip(const QString &statusTip)
946
947 Sets the item's status tip to the string specified by \a statusTip.
948
949 \sa statusTip(), setToolTip(), setWhatsThis()
950*/
951
952/*!
953 \fn QString QStandardItem::toolTip() const
954
955 Returns the item's tooltip.
956
957 \sa setToolTip(), statusTip(), whatsThis()
958*/
959
960/*!
961 \fn void QStandardItem::setToolTip(const QString &toolTip)
962
963 Sets the item's tooltip to the string specified by \a toolTip.
964
965 \sa toolTip(), setStatusTip(), setWhatsThis()
966*/
967
968/*!
969 \fn QString QStandardItem::whatsThis() const
970
971 Returns the item's "What's This?" help.
972
973 \sa setWhatsThis(), toolTip(), statusTip()
974*/
975
976/*!
977 \fn void QStandardItem::setWhatsThis(const QString &whatsThis)
978
979 Sets the item's "What's This?" help to the string specified by \a whatsThis.
980
981 \sa whatsThis(), setStatusTip(), setToolTip()
982*/
983
984/*!
985 \fn QFont QStandardItem::font() const
986
987 Returns the font used to render the item's text.
988
989 \sa setFont()
990*/
991
992/*!
993 \fn void QStandardItem::setFont(const QFont &font)
994
995 Sets the font used to display the item's text to the given \a font.
996
997 \sa font() setText() setForeground()
998*/
999
1000/*!
1001 \fn QBrush QStandardItem::background() const
1002
1003 Returns the brush used to render the item's background.
1004
1005 \sa foreground() setBackground()
1006*/
1007
1008/*!
1009 \fn void QStandardItem::setBackground(const QBrush &brush)
1010
1011 Sets the item's background brush to the specified \a brush.
1012
1013 \sa background() setForeground()
1014*/
1015
1016/*!
1017 \fn QBrush QStandardItem::foreground() const
1018
1019 Returns the brush used to render the item's foreground (e.g. text).
1020
1021 \sa setForeground() background()
1022*/
1023
1024/*!
1025 \fn void QStandardItem::setForeground(const QBrush &brush)
1026
1027 Sets the brush used to display the item's foreground (e.g. text) to the
1028 given \a brush.
1029
1030 \sa foreground() setBackground() setFont()
1031*/
1032
1033/*!
1034 \fn int QStandardItem::textAlignment() const
1035
1036 Returns the text alignment for the item's text.
1037*/
1038
1039/*!
1040 \fn void QStandardItem::setTextAlignment(Qt::Alignment alignment)
1041
1042 Sets the text alignment for the item's text to the \a alignment
1043 specified.
1044
1045 \sa textAlignment()
1046*/
1047
1048/*!
1049 \fn QSize QStandardItem::sizeHint() const
1050
1051 Returns the size hint set for the item, or an invalid QSize if no
1052 size hint has been set.
1053
1054 If no size hint has been set, the item delegate will compute the
1055 size hint based on the item data.
1056
1057 \sa setSizeHint()
1058*/
1059
1060/*!
1061 \fn void QStandardItem::setSizeHint(const QSize &size)
1062
1063 Sets the size hint for the item to be \a size.
1064 If no size hint is set, the item delegate will compute the
1065 size hint based on the item data.
1066
1067 \sa sizeHint()
1068*/
1069
1070/*!
1071 \fn Qt::CheckState QStandardItem::checkState() const
1072
1073 Returns the checked state of the item.
1074
1075 \sa setCheckState(), isCheckable()
1076*/
1077
1078/*!
1079 \fn void QStandardItem::setCheckState(Qt::CheckState state)
1080
1081 Sets the check state of the item to be \a state.
1082
1083 \sa checkState(), setCheckable()
1084*/
1085
1086/*!
1087 \fn QString QStandardItem::accessibleText() const
1088
1089 Returns the item's accessible text.
1090
1091 The accessible text is used by assistive technologies (i.e. for users who
1092 cannot use conventional means of interaction).
1093
1094 \sa setAccessibleText(), accessibleDescription()
1095*/
1096
1097/*!
1098 \fn void QStandardItem::setAccessibleText(const QString &accessibleText)
1099
1100 Sets the item's accessible text to the string specified by \a accessibleText.
1101
1102 The accessible text is used by assistive technologies (i.e. for users who
1103 cannot use conventional means of interaction).
1104
1105 \sa accessibleText(), setAccessibleDescription()
1106*/
1107
1108/*!
1109 \fn QString QStandardItem::accessibleDescription() const
1110
1111 Returns the item's accessible description.
1112
1113 The accessible description is used by assistive technologies (i.e. for
1114 users who cannot use conventional means of interaction).
1115
1116 \sa setAccessibleDescription(), accessibleText()
1117*/
1118
1119/*!
1120 \fn void QStandardItem::setAccessibleDescription(const QString &accessibleDescription)
1121
1122 Sets the item's accessible description to the string specified by \a
1123 accessibleDescription.
1124
1125 The accessible description is used by assistive technologies (i.e. for
1126 users who cannot use conventional means of interaction).
1127
1128 \sa accessibleDescription(), setAccessibleText()
1129*/
1130
1131/*!
1132 Sets whether the item is enabled. If \a enabled is true, the item is enabled,
1133 meaning that the user can interact with the item; if \a enabled is false, the
1134 user cannot interact with the item.
1135
1136 This flag takes presedence over the other item flags; e.g. if an item is not
1137 enabled, it cannot be selected by the user, even if the Qt::ItemIsSelectable
1138 flag has been set.
1139
1140 \sa isEnabled(), Qt::ItemIsEnabled, setFlags()
1141*/
1142void QStandardItem::setEnabled(bool enabled)
1143{
1144 Q_D(QStandardItem);
1145 d->changeFlags(enabled, Qt::ItemIsEnabled);
1146}
1147
1148/*!
1149 \fn bool QStandardItem::isEnabled() const
1150
1151 Returns whether the item is enabled.
1152
1153 When an item is enabled, the user can interact with it. The possible
1154 types of interaction are specified by the other item flags, such as
1155 isEditable() and isSelectable().
1156
1157 The default value is true.
1158
1159 \sa setEnabled(), flags()
1160*/
1161
1162/*!
1163 Sets whether the item is editable. If \a editable is true, the item can be
1164 edited by the user; otherwise, the user cannot edit the item.
1165
1166 How the user can edit items in a view is determined by the view's edit
1167 triggers; see QAbstractItemView::editTriggers.
1168
1169 \sa isEditable(), setFlags()
1170*/
1171void QStandardItem::setEditable(bool editable)
1172{
1173 Q_D(QStandardItem);
1174 d->changeFlags(editable, Qt::ItemIsEditable);
1175}
1176
1177/*!
1178 \fn bool QStandardItem::isEditable() const
1179
1180 Returns whether the item can be edited by the user.
1181
1182 When an item is editable (and enabled), the user can edit the item by
1183 invoking one of the view's edit triggers; see
1184 QAbstractItemView::editTriggers.
1185
1186 The default value is true.
1187
1188 \sa setEditable(), flags()
1189*/
1190
1191/*!
1192 Sets whether the item is selectable. If \a selectable is true, the item
1193 can be selected by the user; otherwise, the user cannot select the item.
1194
1195 You can control the selection behavior and mode by manipulating their
1196 view properties; see QAbstractItemView::selectionMode and
1197 QAbstractItemView::selectionBehavior.
1198
1199 \sa isSelectable(), setFlags()
1200*/
1201void QStandardItem::setSelectable(bool selectable)
1202{
1203 Q_D(QStandardItem);
1204 d->changeFlags(selectable, Qt::ItemIsSelectable);
1205}
1206
1207/*!
1208 \fn bool QStandardItem::isSelectable() const
1209
1210 Returns whether the item is selectable by the user.
1211
1212 The default value is true.
1213
1214 \sa setSelectable(), flags()
1215*/
1216
1217/*!
1218 Sets whether the item is user-checkable. If \a checkable is true, the
1219 item can be checked by the user; otherwise, the user cannot check
1220 the item.
1221
1222 The item delegate will render a checkable item with a check box next to the
1223 item's text.
1224
1225 \sa isCheckable(), setCheckState(), setTristate()
1226*/
1227void QStandardItem::setCheckable(bool checkable)
1228{
1229 Q_D(QStandardItem);
1230 if (checkable && !isCheckable()) {
1231 // make sure there's data for the checkstate role
1232 if (!data(Qt::CheckStateRole).isValid())
1233 setData(Qt::Unchecked, Qt::CheckStateRole);
1234 }
1235 d->changeFlags(checkable, Qt::ItemIsUserCheckable);
1236}
1237
1238/*!
1239 \fn bool QStandardItem::isCheckable() const
1240
1241 Returns whether the item is user-checkable.
1242
1243 The default value is false.
1244
1245 \sa setCheckable(), checkState(), isTristate()
1246*/
1247
1248/*!
1249 Sets whether the item is tristate. If \a tristate is true, the
1250 item is checkable with three separate states; otherwise, the item
1251 is checkable with two states. (Note that this also requires that
1252 the item is checkable; see isCheckable().)
1253
1254 \sa isTristate(), setCheckable(), setCheckState()
1255*/
1256void QStandardItem::setTristate(bool tristate)
1257{
1258 Q_D(QStandardItem);
1259 d->changeFlags(tristate, Qt::ItemIsTristate);
1260}
1261
1262/*!
1263 \fn bool QStandardItem::isTristate() const
1264
1265 Returns whether the item is tristate; that is, if it's checkable with three
1266 separate states.
1267
1268 The default value is false.
1269
1270 \sa setTristate(), isCheckable(), checkState()
1271*/
1272
1273#ifndef QT_NO_DRAGANDDROP
1274
1275/*!
1276 Sets whether the item is drag enabled. If \a dragEnabled is true, the item
1277 can be dragged by the user; otherwise, the user cannot drag the item.
1278
1279 Note that you also need to ensure that item dragging is enabled in the view;
1280 see QAbstractItemView::dragEnabled.
1281
1282 \sa isDragEnabled(), setDropEnabled(), setFlags()
1283*/
1284void QStandardItem::setDragEnabled(bool dragEnabled)
1285{
1286 Q_D(QStandardItem);
1287 d->changeFlags(dragEnabled, Qt::ItemIsDragEnabled);
1288}
1289
1290/*!
1291 \fn bool QStandardItem::isDragEnabled() const
1292
1293 Returns whether the item is drag enabled. An item that is drag enabled can
1294 be dragged by the user.
1295
1296 The default value is true.
1297
1298 Note that item dragging must be enabled in the view for dragging to work;
1299 see QAbstractItemView::dragEnabled.
1300
1301 \sa setDragEnabled(), isDropEnabled(), flags()
1302*/
1303
1304/*!
1305 Sets whether the item is drop enabled. If \a dropEnabled is true, the item
1306 can be used as a drop target; otherwise, it cannot.
1307
1308 Note that you also need to ensure that drops are enabled in the view; see
1309 QWidget::acceptDrops(); and that the model supports the desired drop actions;
1310 see QAbstractItemModel::supportedDropActions().
1311
1312 \sa isDropEnabled(), setDragEnabled(), setFlags()
1313*/
1314void QStandardItem::setDropEnabled(bool dropEnabled)
1315{
1316 Q_D(QStandardItem);
1317 d->changeFlags(dropEnabled, Qt::ItemIsDropEnabled);
1318}
1319
1320/*!
1321 \fn bool QStandardItem::isDropEnabled() const
1322
1323 Returns whether the item is drop enabled. When an item is drop enabled, it
1324 can be used as a drop target.
1325
1326 The default value is true.
1327
1328 \sa setDropEnabled(), isDragEnabled(), flags()
1329*/
1330
1331#endif // QT_NO_DRAGANDDROP
1332
1333/*!
1334 Returns the row where the item is located in its parent's child table, or
1335 -1 if the item has no parent.
1336
1337 \sa column(), parent()
1338*/
1339int QStandardItem::row() const
1340{
1341 Q_D(const QStandardItem);
1342 QPair<int, int> pos = d->position();
1343 return pos.first;
1344}
1345
1346/*!
1347 Returns the column where the item is located in its parent's child table,
1348 or -1 if the item has no parent.
1349
1350 \sa row(), parent()
1351*/
1352int QStandardItem::column() const
1353{
1354 Q_D(const QStandardItem);
1355 QPair<int, int> pos = d->position();
1356 return pos.second;
1357}
1358
1359/*!
1360 Returns the QModelIndex associated with this item.
1361
1362 When you need to invoke item functionality in a QModelIndex-based API (e.g.
1363 QAbstractItemView), you can call this function to obtain an index that
1364 corresponds to the item's location in the model.
1365
1366 If the item is not associated with a model, an invalid QModelIndex is
1367 returned.
1368
1369 \sa model(), QStandardItemModel::itemFromIndex()
1370*/
1371QModelIndex QStandardItem::index() const
1372{
1373 Q_D(const QStandardItem);
1374 return d->model ? d->model->indexFromItem(this) : QModelIndex();
1375}
1376
1377/*!
1378 Returns the QStandardItemModel that this item belongs to.
1379
1380 If the item is not a child of another item that belongs to the model, this
1381 function returns 0.
1382
1383 \sa index()
1384*/
1385QStandardItemModel *QStandardItem::model() const
1386{
1387 Q_D(const QStandardItem);
1388 return d->model;
1389}
1390
1391/*!
1392 Sets the number of child item rows to \a rows. If this is less than
1393 rowCount(), the data in the unwanted rows is discarded.
1394
1395 \sa rowCount(), setColumnCount()
1396*/
1397void QStandardItem::setRowCount(int rows)
1398{
1399 int rc = rowCount();
1400 if (rc == rows)
1401 return;
1402 if (rc < rows)
1403 insertRows(qMax(rc, 0), rows - rc);
1404 else
1405 removeRows(qMax(rows, 0), rc - rows);
1406}
1407
1408/*!
1409 Returns the number of child item rows that the item has.
1410
1411 \sa setRowCount(), columnCount()
1412*/
1413int QStandardItem::rowCount() const
1414{
1415 Q_D(const QStandardItem);
1416 return d->rowCount();
1417}
1418
1419/*!
1420 Sets the number of child item columns to \a columns. If this is less than
1421 columnCount(), the data in the unwanted columns is discarded.
1422
1423 \sa columnCount(), setRowCount()
1424*/
1425void QStandardItem::setColumnCount(int columns)
1426{
1427 int cc = columnCount();
1428 if (cc == columns)
1429 return;
1430 if (cc < columns)
1431 insertColumns(qMax(cc, 0), columns - cc);
1432 else
1433 removeColumns(qMax(columns, 0), cc - columns);
1434}
1435
1436/*!
1437 Returns the number of child item columns that the item has.
1438
1439 \sa setColumnCount(), rowCount()
1440*/
1441int QStandardItem::columnCount() const
1442{
1443 Q_D(const QStandardItem);
1444 return d->columnCount();
1445}
1446
1447/*!
1448 Inserts a row at \a row containing \a items. If necessary, the column
1449 count is increased to the size of \a items.
1450
1451 \sa insertRows(), insertColumn()
1452*/
1453void QStandardItem::insertRow(int row, const QList<QStandardItem*> &items)
1454{
1455 Q_D(QStandardItem);
1456 if (row < 0)
1457 return;
1458 if (columnCount() < items.count())
1459 setColumnCount(items.count());
1460 d->insertRows(row, 1, items);
1461}
1462
1463/*!
1464 Inserts \a items at \a row. The column count wont be changed.
1465
1466 \sa insertRow(), insertColumn()
1467*/
1468void QStandardItem::insertRows(int row, const QList<QStandardItem*> &items)
1469{
1470 Q_D(QStandardItem);
1471 if (row < 0)
1472 return;
1473 d->insertRows(row, items);
1474}
1475
1476/*!
1477 Inserts a column at \a column containing \a items. If necessary,
1478 the row count is increased to the size of \a items.
1479
1480 \sa insertColumns(), insertRow()
1481*/
1482void QStandardItem::insertColumn(int column, const QList<QStandardItem*> &items)
1483{
1484 Q_D(QStandardItem);
1485 if (column < 0)
1486 return;
1487 if (rowCount() < items.count())
1488 setRowCount(items.count());
1489 d->insertColumns(column, 1, items);
1490}
1491
1492/*!
1493 Inserts \a count rows of child items at row \a row.
1494
1495 \sa insertRow(), insertColumns()
1496*/
1497void QStandardItem::insertRows(int row, int count)
1498{
1499 Q_D(QStandardItem);
1500 if (rowCount() < row) {
1501 count += row - rowCount();
1502 row = rowCount();
1503 }
1504 d->insertRows(row, count, QList<QStandardItem*>());
1505}
1506
1507/*!
1508 Inserts \a count columns of child items at column \a column.
1509
1510 \sa insertColumn(), insertRows()
1511*/
1512void QStandardItem::insertColumns(int column, int count)
1513{
1514 Q_D(QStandardItem);
1515 if (columnCount() < column) {
1516 count += column - columnCount();
1517 column = columnCount();
1518 }
1519 d->insertColumns(column, count, QList<QStandardItem*>());
1520}
1521
1522/*!
1523 \fn void QStandardItem::appendRow(const QList<QStandardItem*> &items)
1524
1525 Appends a row containing \a items. If necessary, the column count is
1526 increased to the size of \a items.
1527
1528 \sa insertRow()
1529*/
1530
1531/*!
1532 \fn void QStandardItem::appendRows(const QList<QStandardItem*> &items)
1533
1534 Appends rows containing \a items. The column count will not change.
1535
1536 \sa insertRow()
1537*/
1538
1539/*!
1540 \fn void QStandardItem::appendColumn(const QList<QStandardItem*> &items)
1541
1542 Appends a column containing \a items. If necessary, the row count is
1543 increased to the size of \a items.
1544
1545 \sa insertColumn()
1546*/
1547
1548/*!
1549 \fn bool QStandardItemModel::insertRow(int row, const QModelIndex &parent)
1550
1551 Inserts a single row before the given \a row in the child items of the
1552 \a parent specified. Returns true if the row is inserted; otherwise
1553 returns false.
1554
1555 \sa insertRows(), insertColumn(), removeRow()
1556*/
1557
1558/*!
1559 \fn bool QStandardItemModel::insertColumn(int column, const QModelIndex &parent)
1560
1561 Inserts a single column before the given \a column in the child items of
1562 the \a parent specified. Returns true if the column is inserted; otherwise
1563 returns false.
1564
1565 \sa insertColumns(), insertRow(), removeColumn()
1566*/
1567
1568/*!
1569 \fn QStandardItem::insertRow(int row, QStandardItem *item)
1570 \overload
1571
1572 Inserts a row at \a row containing \a item.
1573
1574 When building a list or a tree that has only one column, this function
1575 provides a convenient way to insert a single new item.
1576*/
1577
1578/*!
1579 \fn QStandardItem::appendRow(QStandardItem *item)
1580 \overload
1581
1582 Appends a row containing \a item.
1583
1584 When building a list or a tree that has only one column, this function
1585 provides a convenient way to append a single new item.
1586*/
1587
1588/*!
1589 Removes the given \a row. The items that were in the row are deleted.
1590
1591 \sa takeRow(), removeRows(), removeColumn()
1592*/
1593void QStandardItem::removeRow(int row)
1594{
1595 removeRows(row, 1);
1596}
1597
1598/*!
1599 Removes the given \a column. The items that were in the
1600 column are deleted.
1601
1602 \sa takeColumn(), removeColumns(), removeRow()
1603*/
1604void QStandardItem::removeColumn(int column)
1605{
1606 removeColumns(column, 1);
1607}
1608
1609/*!
1610 Removes \a count rows at row \a row. The items that were in those rows are
1611 deleted.
1612
1613 \sa removeRow(), removeColumn()
1614*/
1615void QStandardItem::removeRows(int row, int count)
1616{
1617 Q_D(QStandardItem);
1618 if ((count < 1) || (row < 0) || ((row + count) > rowCount()))
1619 return;
1620 if (d->model)
1621 d->model->d_func()->rowsAboutToBeRemoved(this, row, row + count - 1);
1622 int i = d->childIndex(row, 0);
1623 int n = count * d->columnCount();
1624 for (int j = i; j < n+i; ++j) {
1625 QStandardItem *oldItem = d->children.at(j);
1626 if (oldItem)
1627 oldItem->d_func()->setModel(0);
1628 delete oldItem;
1629 }
1630 d->children.remove(qMax(i, 0), n);
1631 d->rows -= count;
1632 if (d->model)
1633 d->model->d_func()->rowsRemoved(this, row, count);
1634}
1635
1636/*!
1637 Removes \a count columns at column \a column. The items that were in those
1638 columns are deleted.
1639
1640 \sa removeColumn(), removeRows()
1641*/
1642void QStandardItem::removeColumns(int column, int count)
1643{
1644 Q_D(QStandardItem);
1645 if ((count < 1) || (column < 0) || ((column + count) > columnCount()))
1646 return;
1647 if (d->model)
1648 d->model->d_func()->columnsAboutToBeRemoved(this, column, column + count - 1);
1649 for (int row = d->rowCount() - 1; row >= 0; --row) {
1650 int i = d->childIndex(row, column);
1651 for (int j=i; j<i+count; ++j) {
1652 QStandardItem *oldItem = d->children.at(j);
1653 if (oldItem)
1654 oldItem->d_func()->setModel(0);
1655 delete oldItem;
1656 }
1657 d->children.remove(i, count);
1658 }
1659 d->columns -= count;
1660 if (d->model)
1661 d->model->d_func()->columnsRemoved(this, column, count);
1662}
1663
1664/*!
1665 Returns true if this item has any children; otherwise returns false.
1666
1667 \sa rowCount(), columnCount(), child()
1668*/
1669bool QStandardItem::hasChildren() const
1670{
1671 return (rowCount() > 0) && (columnCount() > 0);
1672}
1673
1674/*!
1675 Sets the child item at (\a row, \a column) to \a item. This item (the parent
1676 item) takes ownership of \a item. If necessary, the row count and column
1677 count are increased to fit the item.
1678
1679 \sa child()
1680*/
1681void QStandardItem::setChild(int row, int column, QStandardItem *item)
1682{
1683 Q_D(QStandardItem);
1684 d->setChild(row, column, item, true);
1685}
1686
1687/*!
1688 \fn QStandardItem::setChild(int row, QStandardItem *item)
1689 \overload
1690
1691 Sets the child at \a row to \a item.
1692*/
1693
1694/*!
1695 Returns the child item at (\a row, \a column) if one has been set; otherwise
1696 returns 0.
1697
1698 \sa setChild(), takeChild(), parent()
1699*/
1700QStandardItem *QStandardItem::child(int row, int column) const
1701{
1702 Q_D(const QStandardItem);
1703 int index = d->childIndex(row, column);
1704 if (index == -1)
1705 return 0;
1706 return d->children.at(index);
1707}
1708
1709/*!
1710 Removes the child item at (\a row, \a column) without deleting it, and returns
1711 a pointer to the item. If there was no child at the given location, then
1712 this function returns 0.
1713
1714 Note that this function, unlike takeRow() and takeColumn(), does not affect
1715 the dimensions of the child table.
1716
1717 \sa child(), takeRow(), takeColumn()
1718*/
1719QStandardItem *QStandardItem::takeChild(int row, int column)
1720{
1721 Q_D(QStandardItem);
1722 QStandardItem *item = 0;
1723 int index = d->childIndex(row, column);
1724 if (index != -1) {
1725 item = d->children.at(index);
1726 if (item)
1727 item->d_func()->setParentAndModel(0, 0);
1728 d->children.replace(index, 0);
1729 }
1730 return item;
1731}
1732
1733/*!
1734 Removes \a row without deleting the row items, and returns a list of
1735 pointers to the removed items. For items in the row that have not been
1736 set, the corresponding pointers in the list will be 0.
1737
1738 \sa removeRow(), insertRow(), takeColumn()
1739*/
1740QList<QStandardItem*> QStandardItem::takeRow(int row)
1741{
1742 Q_D(QStandardItem);
1743 if ((row < 0) || (row >= rowCount()))
1744 return QList<QStandardItem*>();
1745 QList<QStandardItem*> items;
1746 int index = d->childIndex(row, 0);
1747 for (int column = 0; column < d->columnCount(); ++column) {
1748 QStandardItem *ch = d->children.at(index);
1749 if (ch) {
1750 ch->d_func()->setParentAndModel(0, 0);
1751 d->children.replace(index, 0);
1752 }
1753 items.append(ch);
1754 ++index;
1755 }
1756 removeRow(row);
1757 return items;
1758}
1759
1760/*!
1761 Removes \a column without deleting the column items, and returns a list of
1762 pointers to the removed items. For items in the column that have not been
1763 set, the corresponding pointers in the list will be 0.
1764
1765 \sa removeColumn(), insertColumn(), takeRow()
1766*/
1767QList<QStandardItem*> QStandardItem::takeColumn(int column)
1768{
1769 Q_D(QStandardItem);
1770 if ((column < 0) || (column >= columnCount()))
1771 return QList<QStandardItem*>();
1772 QList<QStandardItem*> items;
1773 int index = d->childIndex(0, column);
1774 for (int row = 0; row < d->rowCount(); ++row) {
1775 QStandardItem *ch = d->children.at(index);
1776 if (ch) {
1777 ch->d_func()->setParentAndModel(0, 0);
1778 d->children.replace(index, 0);
1779 }
1780 items.append(ch);
1781 index += d->columnCount();
1782 }
1783 removeColumn(column);
1784 return items;
1785}
1786
1787/*!
1788 Returns true if this item is less than \a other; otherwise returns false.
1789
1790 The default implementation uses the data for the item's sort role (see
1791 QStandardItemModel::sortRole) to perform the comparison if the item
1792 belongs to a model; otherwise, the data for the item's Qt::DisplayRole
1793 (text()) is used to perform the comparison.
1794
1795 sortChildren() and QStandardItemModel::sort() use this function when
1796 sorting items. If you want custom sorting, you can subclass QStandardItem
1797 and reimplement this function.
1798*/
1799bool QStandardItem::operator<(const QStandardItem &other) const
1800{
1801 const int role = model() ? model()->sortRole() : Qt::DisplayRole;
1802 const QVariant l = data(role), r = other.data(role);
1803 // this code is copied from QSortFilterProxyModel::lessThan()
1804 switch (l.type()) {
1805 case QVariant::Invalid:
1806 return (r.type() == QVariant::Invalid);
1807 case QVariant::Int:
1808 return l.toInt() < r.toInt();
1809 case QVariant::UInt:
1810 return l.toUInt() < r.toUInt();
1811 case QVariant::LongLong:
1812 return l.toLongLong() < r.toLongLong();
1813 case QVariant::ULongLong:
1814 return l.toULongLong() < r.toULongLong();
1815 case QVariant::Double:
1816 return l.toDouble() < r.toDouble();
1817 case QVariant::Char:
1818 return l.toChar() < r.toChar();
1819 case QVariant::Date:
1820 return l.toDate() < r.toDate();
1821 case QVariant::Time:
1822 return l.toTime() < r.toTime();
1823 case QVariant::DateTime:
1824 return l.toDateTime() < r.toDateTime();
1825 case QVariant::String:
1826 default:
1827 return l.toString().compare(r.toString()) < 0;
1828 }
1829}
1830
1831/*!
1832 Sorts the children of the item using the given \a order, by the values in
1833 the given \a column.
1834
1835 \note This function is recursive, therefore it sorts the children of the
1836 item, its grandchildren, etc.
1837
1838 \sa {operator<()}
1839*/
1840void QStandardItem::sortChildren(int column, Qt::SortOrder order)
1841{
1842 Q_D(QStandardItem);
1843 if ((column < 0) || (rowCount() == 0))
1844 return;
1845 if (d->model)
1846 emit d->model->layoutAboutToBeChanged();
1847 d->sortChildren(column, order);
1848 if (d->model)
1849 emit d->model->layoutChanged();
1850}
1851
1852/*!
1853 Returns a copy of this item. The item's children are not copied.
1854
1855 When subclassing QStandardItem, you can reimplement this function
1856 to provide QStandardItemModel with a factory that it can use to
1857 create new items on demand.
1858
1859 \sa QStandardItemModel::setItemPrototype(), operator=()
1860*/
1861QStandardItem *QStandardItem::clone() const
1862{
1863 return new QStandardItem(*this);
1864}
1865
1866/*!
1867 Returns the type of this item. The type is used to distinguish custom
1868 items from the base class. When subclassing QStandardItem, you should
1869 reimplement this function and return a new value greater than or equal
1870 to \l UserType.
1871
1872 \sa QStandardItem::Type
1873*/
1874int QStandardItem::type() const
1875{
1876 return Type;
1877}
1878
1879#ifndef QT_NO_DATASTREAM
1880
1881/*!
1882 Reads the item from stream \a in. Only the data and flags of the item are
1883 read, not the child items.
1884
1885 \sa write()
1886*/
1887void QStandardItem::read(QDataStream &in)
1888{
1889 Q_D(QStandardItem);
1890 in >> d->values;
1891 qint32 flags;
1892 in >> flags;
1893 setFlags((Qt::ItemFlags)flags);
1894}
1895
1896/*!
1897 Writes the item to stream \a out. Only the data and flags of the item
1898 are written, not the child items.
1899
1900 \sa read()
1901*/
1902void QStandardItem::write(QDataStream &out) const
1903{
1904 Q_D(const QStandardItem);
1905 out << d->values;
1906 out << flags();
1907}
1908
1909/*!
1910 \relates QStandardItem
1911 \since 4.2
1912
1913 Reads a QStandardItem from stream \a in into \a item.
1914
1915 This operator uses QStandardItem::read().
1916
1917 \sa {Format of the QDataStream Operators}
1918*/
1919QDataStream &operator>>(QDataStream &in, QStandardItem &item)
1920{
1921 item.read(in);
1922 return in;
1923}
1924
1925/*!
1926 \relates QStandardItem
1927 \since 4.2
1928
1929 Writes the QStandardItem \a item to stream \a out.
1930
1931 This operator uses QStandardItem::write().
1932
1933 \sa {Format of the QDataStream Operators}
1934*/
1935QDataStream &operator<<(QDataStream &out, const QStandardItem &item)
1936{
1937 item.write(out);
1938 return out;
1939}
1940
1941#endif // !QT_NO_DATASTREAM
1942
1943/*!
1944 \class QStandardItemModel
1945 \brief The QStandardItemModel class provides a generic model for storing custom data.
1946 \ingroup model-view
1947
1948 QStandardItemModel can be used as a repository for standard Qt
1949 data types. It is one of the \l {Model/View Classes} and is part
1950 of Qt's \l {Model/View Programming}{model/view} framework.
1951
1952 QStandardItemModel provides a classic item-based approach to working with
1953 the model. The items in a QStandardItemModel are provided by
1954 QStandardItem.
1955
1956 QStandardItemModel implements the QAbstractItemModel interface, which
1957 means that the model can be used to provide data in any view that supports
1958 that interface (such as QListView, QTableView and QTreeView, and your own
1959 custom views). For performance and flexibility, you may want to subclass
1960 QAbstractItemModel to provide support for different kinds of data
1961 repositories. For example, the QDirModel provides a model interface to the
1962 underlying file system.
1963
1964 When you want a list or tree, you typically create an empty
1965 QStandardItemModel and use appendRow() to add items to the model, and
1966 item() to access an item. If your model represents a table, you typically
1967 pass the dimensions of the table to the QStandardItemModel constructor and
1968 use setItem() to position items into the table. You can also use setRowCount()
1969 and setColumnCount() to alter the dimensions of the model. To insert items,
1970 use insertRow() or insertColumn(), and to remove items, use removeRow() or
1971 removeColumn().
1972
1973 You can set the header labels of your model with setHorizontalHeaderLabels()
1974 and setVerticalHeaderLabels().
1975
1976 You can search for items in the model with findItems(), and sort the model by
1977 calling sort().
1978
1979 Call clear() to remove all items from the model.
1980
1981 An example usage of QStandardItemModel to create a table:
1982
1983 \snippet doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp 0
1984
1985 An example usage of QStandardItemModel to create a tree:
1986
1987 \snippet doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp 1
1988
1989 After setting the model on a view, you typically want to react to user
1990 actions, such as an item being clicked. Since a QAbstractItemView provides
1991 QModelIndex-based signals and functions, you need a way to obtain the
1992 QStandardItem that corresponds to a given QModelIndex, and vice
1993 versa. itemFromIndex() and indexFromItem() provide this mapping. Typical
1994 usage of itemFromIndex() includes obtaining the item at the current index
1995 in a view, and obtaining the item that corresponds to an index carried by
1996 a QAbstractItemView signal, such as QAbstractItemView::clicked(). First
1997 you connect the view's signal to a slot in your class:
1998
1999 \snippet doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp 2
2000
2001 When you receive the signal, you call itemFromIndex() on the given model
2002 index to get a pointer to the item:
2003
2004 \snippet doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp 3
2005
2006 Conversely, you must obtain the QModelIndex of an item when you want to
2007 invoke a model/view function that takes an index as argument. You can
2008 obtain the index either by using the model's indexFromItem() function, or,
2009 equivalently, by calling QStandardItem::index():
2010
2011 \snippet doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp 4
2012
2013 You are, of course, not required to use the item-based approach; you could
2014 instead rely entirely on the QAbstractItemModel interface when working with
2015 the model, or use a combination of the two as appropriate.
2016
2017 \sa QStandardItem, {Model/View Programming}, QAbstractItemModel,
2018 {itemviews/simpletreemodel}{Simple Tree Model example},
2019 {Item View Convenience Classes}
2020*/
2021
2022/*!
2023 \fn void QStandardItemModel::itemChanged(QStandardItem *item)
2024 \since 4.2
2025
2026 This signal is emitted whenever the data of \a item has changed.
2027*/
2028
2029/*!
2030 Constructs a new item model with the given \a parent.
2031*/
2032QStandardItemModel::QStandardItemModel(QObject *parent)
2033 : QAbstractItemModel(*new QStandardItemModelPrivate, parent)
2034{
2035 Q_D(QStandardItemModel);
2036 d->init();
2037 d->root->d_func()->setModel(this);
2038}
2039
2040/*!
2041 Constructs a new item model that initially has \a rows rows and \a columns
2042 columns, and that has the given \a parent.
2043*/
2044QStandardItemModel::QStandardItemModel(int rows, int columns, QObject *parent)
2045 : QAbstractItemModel(*new QStandardItemModelPrivate, parent)
2046{
2047 Q_D(QStandardItemModel);
2048 d->init();
2049 d->root->insertColumns(0, columns);
2050 d->columnHeaderItems.insert(0, columns, 0);
2051 d->root->insertRows(0, rows);
2052 d->rowHeaderItems.insert(0, rows, 0);
2053 d->root->d_func()->setModel(this);
2054}
2055
2056/*!
2057 \internal
2058*/
2059QStandardItemModel::QStandardItemModel(QStandardItemModelPrivate &dd, QObject *parent)
2060 : QAbstractItemModel(dd, parent)
2061{
2062 Q_D(QStandardItemModel);
2063 d->init();
2064}
2065
2066/*!
2067 Destructs the model. The model destroys all its items.
2068*/
2069QStandardItemModel::~QStandardItemModel()
2070{
2071}
2072
2073/*!
2074 Removes all items (including header items) from the model and sets the
2075 number of rows and columns to zero.
2076
2077 \sa removeColumns(), removeRows()
2078*/
2079void QStandardItemModel::clear()
2080{
2081 Q_D(QStandardItemModel);
2082 delete d->root;
2083 d->root = new QStandardItem;
2084 d->root->d_func()->setModel(this);
2085 qDeleteAll(d->columnHeaderItems);
2086 d->columnHeaderItems.clear();
2087 qDeleteAll(d->rowHeaderItems);
2088 d->rowHeaderItems.clear();
2089 reset();
2090}
2091
2092/*!
2093 \since 4.2
2094
2095 Returns a pointer to the QStandardItem associated with the given \a index.
2096
2097 Calling this function is typically the initial step when processing
2098 QModelIndex-based signals from a view, such as
2099 QAbstractItemView::activated(). In your slot, you call itemFromIndex(),
2100 with the QModelIndex carried by the signal as argument, to obtain a
2101 pointer to the corresponding QStandardItem.
2102
2103 Note that this function will lazily create an item for the index (using
2104 itemPrototype()), and set it in the parent item's child table, if no item
2105 already exists at that index.
2106
2107 If \a index is an invalid index, this function returns 0.
2108
2109 \sa indexFromItem()
2110*/
2111QStandardItem *QStandardItemModel::itemFromIndex(const QModelIndex &index) const
2112{
2113 Q_D(const QStandardItemModel);
2114 if ((index.row() < 0) || (index.column() < 0) || (index.model() != this))
2115 return 0;
2116 QStandardItem *parent = static_cast<QStandardItem*>(index.internalPointer());
2117 if (parent == 0)
2118 return 0;
2119 QStandardItem *item = parent->child(index.row(), index.column());
2120 // lazy part
2121 if (item == 0) {
2122 item = d->createItem();
2123 parent->d_func()->setChild(index.row(), index.column(), item);
2124 }
2125 return item;
2126}
2127
2128/*!
2129 \since 4.2
2130
2131 Returns the QModelIndex associated with the given \a item.
2132
2133 Use this function when you want to perform an operation that requires the
2134 QModelIndex of the item, such as
2135 QAbstractItemView::scrollTo(). QStandardItem::index() is provided as
2136 convenience; it is equivalent to calling this function.
2137
2138 \sa itemFromIndex(), QStandardItem::index()
2139*/
2140QModelIndex QStandardItemModel::indexFromItem(const QStandardItem *item) const
2141{
2142 if (item && item->d_func()->parent) {
2143 QPair<int, int> pos = item->d_func()->position();
2144 return createIndex(pos.first, pos.second, item->d_func()->parent);
2145 }
2146 return QModelIndex();
2147}
2148
2149/*!
2150 \since 4.2
2151
2152 Sets the number of rows in this model to \a rows. If
2153 this is less than rowCount(), the data in the unwanted rows
2154 is discarded.
2155
2156 \sa setColumnCount()
2157*/
2158void QStandardItemModel::setRowCount(int rows)
2159{
2160 Q_D(QStandardItemModel);
2161 d->root->setRowCount(rows);
2162}
2163
2164/*!
2165 \since 4.2
2166
2167 Sets the number of columns in this model to \a columns. If
2168 this is less than columnCount(), the data in the unwanted columns
2169 is discarded.
2170
2171 \sa setRowCount()
2172*/
2173void QStandardItemModel::setColumnCount(int columns)
2174{
2175 Q_D(QStandardItemModel);
2176 d->root->setColumnCount(columns);
2177}
2178
2179/*!
2180 \since 4.2
2181
2182 Sets the item for the given \a row and \a column to \a item. The model
2183 takes ownership of the item. If necessary, the row count and column count
2184 are increased to fit the item. The previous item at the given location (if
2185 there was one) is deleted.
2186
2187 \sa item()
2188*/
2189void QStandardItemModel::setItem(int row, int column, QStandardItem *item)
2190{
2191 Q_D(QStandardItemModel);
2192 d->root->d_func()->setChild(row, column, item, true);
2193}
2194
2195/*!
2196 \fn QStandardItemModel::setItem(int row, QStandardItem *item)
2197 \overload
2198*/
2199
2200/*!
2201 \since 4.2
2202
2203 Returns the item for the given \a row and \a column if one has been set;
2204 otherwise returns 0.
2205
2206 \sa setItem(), takeItem(), itemFromIndex()
2207*/
2208QStandardItem *QStandardItemModel::item(int row, int column) const
2209{
2210 Q_D(const QStandardItemModel);
2211 return d->root->child(row, column);
2212}
2213
2214/*!
2215 \since 4.2
2216
2217 Returns the model's invisible root item.
2218
2219 The invisible root item provides access to the model's top-level items
2220 through the QStandardItem API, making it possible to write functions that
2221 can treat top-level items and their children in a uniform way; for
2222 example, recursive functions involving a tree model.
2223
2224 \note Calling \l{QAbstractItemModel::index()}{index()} on the QStandardItem object
2225 retrieved from this function is not valid.
2226*/
2227QStandardItem *QStandardItemModel::invisibleRootItem() const
2228{
2229 Q_D(const QStandardItemModel);
2230 return d->root;
2231}
2232
2233/*!
2234 \since 4.2
2235
2236 Sets the horizontal header item for \a column to \a item. The model takes
2237 ownership of the item. If necessary, the column count is increased to fit
2238 the item. The previous header item (if there was one) is deleted.
2239
2240 \sa horizontalHeaderItem(), setHorizontalHeaderLabels(),
2241 setVerticalHeaderItem()
2242*/
2243void QStandardItemModel::setHorizontalHeaderItem(int column, QStandardItem *item)
2244{
2245 Q_D(QStandardItemModel);
2246 if (column < 0)
2247 return;
2248 if (columnCount() <= column)
2249 setColumnCount(column + 1);
2250
2251 QStandardItem *oldItem = d->columnHeaderItems.at(column);
2252 if (item == oldItem)
2253 return;
2254
2255 if (item) {
2256 if (item->model() == 0) {
2257 item->d_func()->setModel(this);
2258 } else {
2259 qWarning("QStandardItem::setHorizontalHeaderItem: Ignoring duplicate insertion of item %p",
2260 item);
2261 return;
2262 }
2263 }
2264
2265 if (oldItem)
2266 oldItem->d_func()->setModel(0);
2267 delete oldItem;
2268
2269 d->columnHeaderItems.replace(column, item);
2270 emit headerDataChanged(Qt::Horizontal, column, column);
2271}
2272
2273/*!
2274 \since 4.2
2275
2276 Returns the horizontal header item for \a column if one has been set;
2277 otherwise returns 0.
2278
2279 \sa setHorizontalHeaderItem(), verticalHeaderItem()
2280*/
2281QStandardItem *QStandardItemModel::horizontalHeaderItem(int column) const
2282{
2283 Q_D(const QStandardItemModel);
2284 if ((column < 0) || (column >= columnCount()))
2285 return 0;
2286 return d->columnHeaderItems.at(column);
2287}
2288
2289/*!
2290 \since 4.2
2291
2292 Sets the vertical header item for \a row to \a item. The model takes
2293 ownership of the item. If necessary, the row count is increased to fit the
2294 item. The previous header item (if there was one) is deleted.
2295
2296 \sa verticalHeaderItem(), setVerticalHeaderLabels(),
2297 setHorizontalHeaderItem()
2298*/
2299void QStandardItemModel::setVerticalHeaderItem(int row, QStandardItem *item)
2300{
2301 Q_D(QStandardItemModel);
2302 if (row < 0)
2303 return;
2304 if (rowCount() <= row)
2305 setRowCount(row + 1);
2306
2307 QStandardItem *oldItem = d->rowHeaderItems.at(row);
2308 if (item == oldItem)
2309 return;
2310
2311 if (item) {
2312 if (item->model() == 0) {
2313 item->d_func()->setModel(this);
2314 } else {
2315 qWarning("QStandardItem::setVerticalHeaderItem: Ignoring duplicate insertion of item %p",
2316 item);
2317 return;
2318 }
2319 }
2320
2321 if (oldItem)
2322 oldItem->d_func()->setModel(0);
2323 delete oldItem;
2324
2325 d->rowHeaderItems.replace(row, item);
2326 emit headerDataChanged(Qt::Vertical, row, row);
2327}
2328
2329/*!
2330 \since 4.2
2331
2332 Returns the vertical header item for row \a row if one has been set;
2333 otherwise returns 0.
2334
2335 \sa setVerticalHeaderItem(), horizontalHeaderItem()
2336*/
2337QStandardItem *QStandardItemModel::verticalHeaderItem(int row) const
2338{
2339 Q_D(const QStandardItemModel);
2340 if ((row < 0) || (row >= rowCount()))
2341 return 0;
2342 return d->rowHeaderItems.at(row);
2343}
2344
2345/*!
2346 \since 4.2
2347
2348 Sets the horizontal header labels using \a labels. If necessary, the
2349 column count is increased to the size of \a labels.
2350
2351 \sa setHorizontalHeaderItem()
2352*/
2353void QStandardItemModel::setHorizontalHeaderLabels(const QStringList &labels)
2354{
2355 Q_D(QStandardItemModel);
2356 if (columnCount() < labels.count())
2357 setColumnCount(labels.count());
2358 for (int i = 0; i < labels.count(); ++i) {
2359 QStandardItem *item = horizontalHeaderItem(i);
2360 if (!item) {
2361 item = d->createItem();
2362 setHorizontalHeaderItem(i, item);
2363 }
2364 item->setText(labels.at(i));
2365 }
2366}
2367
2368/*!
2369 \since 4.2
2370
2371 Sets the vertical header labels using \a labels. If necessary, the row
2372 count is increased to the size of \a labels.
2373
2374 \sa setVerticalHeaderItem()
2375*/
2376void QStandardItemModel::setVerticalHeaderLabels(const QStringList &labels)
2377{
2378 Q_D(QStandardItemModel);
2379 if (rowCount() < labels.count())
2380 setRowCount(labels.count());
2381 for (int i = 0; i < labels.count(); ++i) {
2382 QStandardItem *item = verticalHeaderItem(i);
2383 if (!item) {
2384 item = d->createItem();
2385 setVerticalHeaderItem(i, item);
2386 }
2387 item->setText(labels.at(i));
2388 }
2389}
2390
2391/*!
2392 \since 4.2
2393
2394 Sets the item prototype for the model to the specified \a item. The model
2395 takes ownership of the prototype.
2396
2397 The item prototype acts as a QStandardItem factory, by relying on the
2398 QStandardItem::clone() function. To provide your own prototype, subclass
2399 QStandardItem, reimplement QStandardItem::clone() and set the prototype to
2400 be an instance of your custom class. Whenever QStandardItemModel needs to
2401 create an item on demand (for instance, when a view or item delegate calls
2402 setData())), the new items will be instances of your custom class.
2403
2404 \sa itemPrototype(), QStandardItem::clone()
2405*/
2406void QStandardItemModel::setItemPrototype(const QStandardItem *item)
2407{
2408 Q_D(QStandardItemModel);
2409 if (d->itemPrototype != item) {
2410 delete d->itemPrototype;
2411 d->itemPrototype = item;
2412 }
2413}
2414
2415/*!
2416 \since 4.2
2417
2418 Returns the item prototype used by the model. The model uses the item
2419 prototype as an item factory when it needs to construct new items on
2420 demand (for instance, when a view or item delegate calls setData()).
2421
2422 \sa setItemPrototype()
2423*/
2424const QStandardItem *QStandardItemModel::itemPrototype() const
2425{
2426 Q_D(const QStandardItemModel);
2427 return d->itemPrototype;
2428}
2429
2430/*!
2431 \since 4.2
2432
2433 Returns a list of items that match the given \a text, using the given \a
2434 flags, in the given \a column.
2435*/
2436QList<QStandardItem*> QStandardItemModel::findItems(const QString &text,
2437 Qt::MatchFlags flags, int column) const
2438{
2439 QModelIndexList indexes = match(index(0, column, QModelIndex()),
2440 Qt::DisplayRole, text, -1, flags);
2441 QList<QStandardItem*> items;
2442 for (int i = 0; i < indexes.size(); ++i)
2443 items.append(itemFromIndex(indexes.at(i)));
2444 return items;
2445}
2446
2447/*!
2448 \since 4.2
2449
2450 Appends a row containing \a items. If necessary, the column count is
2451 increased to the size of \a items.
2452
2453 \sa insertRow(), appendColumn()
2454*/
2455void QStandardItemModel::appendRow(const QList<QStandardItem*> &items)
2456{
2457 invisibleRootItem()->appendRow(items);
2458}
2459
2460/*!
2461 \since 4.2
2462
2463 Appends a column containing \a items. If necessary, the row count is
2464 increased to the size of \a items.
2465
2466 \sa insertColumn(), appendRow()
2467*/
2468void QStandardItemModel::appendColumn(const QList<QStandardItem*> &items)
2469{
2470 invisibleRootItem()->appendColumn(items);
2471}
2472
2473/*!
2474 \since 4.2
2475 \fn QStandardItemModel::appendRow(QStandardItem *item)
2476 \overload
2477
2478 When building a list or a tree that has only one column, this function
2479 provides a convenient way to append a single new \a item.
2480*/
2481
2482/*!
2483 \since 4.2
2484
2485 Inserts a row at \a row containing \a items. If necessary, the column
2486 count is increased to the size of \a items.
2487
2488 \sa takeRow(), appendRow(), insertColumn()
2489*/
2490void QStandardItemModel::insertRow(int row, const QList<QStandardItem*> &items)
2491{
2492 invisibleRootItem()->insertRow(row, items);
2493}
2494
2495/*!
2496 \since 4.2
2497
2498 \fn void QStandardItemModel::insertRow(int row, QStandardItem *item)
2499 \overload
2500
2501 Inserts a row at \a row containing \a item.
2502
2503 When building a list or a tree that has only one column, this function
2504 provides a convenient way to append a single new item.
2505*/
2506
2507/*!
2508 \since 4.2
2509
2510 Inserts a column at \a column containing \a items. If necessary, the row
2511 count is increased to the size of \a items.
2512
2513 \sa takeColumn(), appendColumn(), insertRow()
2514*/
2515void QStandardItemModel::insertColumn(int column, const QList<QStandardItem*> &items)
2516{
2517 invisibleRootItem()->insertColumn(column, items);
2518}
2519
2520/*!
2521 \since 4.2
2522
2523 Removes the item at (\a row, \a column) without deleting it. The model
2524 releases ownership of the item.
2525
2526 \sa item(), takeRow(), takeColumn()
2527*/
2528QStandardItem *QStandardItemModel::takeItem(int row, int column)
2529{
2530 Q_D(QStandardItemModel);
2531 return d->root->takeChild(row, column);
2532}
2533
2534/*!
2535 \since 4.2
2536
2537 Removes the given \a row without deleting the row items, and returns a
2538 list of pointers to the removed items. The model releases ownership of the
2539 items. For items in the row that have not been set, the corresponding
2540 pointers in the list will be 0.
2541
2542 \sa takeColumn()
2543*/
2544QList<QStandardItem*> QStandardItemModel::takeRow(int row)
2545{
2546 Q_D(QStandardItemModel);
2547 return d->root->takeRow(row);
2548}
2549
2550/*!
2551 \since 4.2
2552
2553 Removes the given \a column without deleting the column items, and returns
2554 a list of pointers to the removed items. The model releases ownership of
2555 the items. For items in the column that have not been set, the
2556 corresponding pointers in the list will be 0.
2557
2558 \sa takeRow()
2559*/
2560QList<QStandardItem*> QStandardItemModel::takeColumn(int column)
2561{
2562 Q_D(QStandardItemModel);
2563 return d->root->takeColumn(column);
2564}
2565
2566/*!
2567 \since 4.2
2568
2569 Removes the horizontal header item at \a column from the header without
2570 deleting it, and returns a pointer to the item. The model releases
2571 ownership of the item.
2572
2573 \sa horizontalHeaderItem(), takeVerticalHeaderItem()
2574*/
2575QStandardItem *QStandardItemModel::takeHorizontalHeaderItem(int column)
2576{
2577 Q_D(QStandardItemModel);
2578 if ((column < 0) || (column >= columnCount()))
2579 return 0;
2580 QStandardItem *headerItem = d->columnHeaderItems.at(column);
2581 if (headerItem) {
2582 headerItem->d_func()->setParentAndModel(0, 0);
2583 d->columnHeaderItems.replace(column, 0);
2584 }
2585 return headerItem;
2586}
2587
2588/*!
2589 \since 4.2
2590
2591 Removes the vertical header item at \a row from the header without
2592 deleting it, and returns a pointer to the item. The model releases
2593 ownership of the item.
2594
2595 \sa verticalHeaderItem(), takeHorizontalHeaderItem()
2596*/
2597QStandardItem *QStandardItemModel::takeVerticalHeaderItem(int row)
2598{
2599 Q_D(QStandardItemModel);
2600 if ((row < 0) || (row >= rowCount()))
2601 return 0;
2602 QStandardItem *headerItem = d->rowHeaderItems.at(row);
2603 if (headerItem) {
2604 headerItem->d_func()->setParentAndModel(0, 0);
2605 d->rowHeaderItems.replace(row, 0);
2606 }
2607 return headerItem;
2608}
2609
2610/*!
2611 \since 4.2
2612 \property QStandardItemModel::sortRole
2613 \brief the item role that is used to query the model's data when sorting items
2614
2615 The default value is Qt::DisplayRole.
2616
2617 \sa sort(), QStandardItem::sortChildren()
2618*/
2619int QStandardItemModel::sortRole() const
2620{
2621 Q_D(const QStandardItemModel);
2622 return d->sortRole;
2623}
2624
2625void QStandardItemModel::setSortRole(int role)
2626{
2627 Q_D(QStandardItemModel);
2628 d->sortRole = role;
2629}
2630
2631/*!
2632 \reimp
2633*/
2634int QStandardItemModel::columnCount(const QModelIndex &parent) const
2635{
2636 Q_D(const QStandardItemModel);
2637 QStandardItem *item = d->itemFromIndex(parent);
2638 return item ? item->columnCount() : 0;
2639}
2640
2641/*!
2642 \reimp
2643*/
2644QVariant QStandardItemModel::data(const QModelIndex &index, int role) const
2645{
2646 Q_D(const QStandardItemModel);
2647 QStandardItem *item = d->itemFromIndex(index);
2648 return item ? item->data(role) : QVariant();
2649}
2650
2651/*!
2652 \reimp
2653*/
2654Qt::ItemFlags QStandardItemModel::flags(const QModelIndex &index) const
2655{
2656 Q_D(const QStandardItemModel);
2657 if (!d->indexValid(index))
2658 return d->root->flags();
2659 QStandardItem *item = d->itemFromIndex(index);
2660 if (item)
2661 return item->flags();
2662 return Qt::ItemIsSelectable
2663 |Qt::ItemIsEnabled
2664 |Qt::ItemIsEditable
2665 |Qt::ItemIsDragEnabled
2666 |Qt::ItemIsDropEnabled;
2667}
2668
2669/*!
2670 \reimp
2671*/
2672bool QStandardItemModel::hasChildren(const QModelIndex &parent) const
2673{
2674 Q_D(const QStandardItemModel);
2675 QStandardItem *item = d->itemFromIndex(parent);
2676 return item ? item->hasChildren() : false;
2677}
2678
2679/*!
2680 \reimp
2681*/
2682QVariant QStandardItemModel::headerData(int section, Qt::Orientation orientation, int role) const
2683{
2684 Q_D(const QStandardItemModel);
2685 if ((section < 0)
2686 || ((orientation == Qt::Horizontal) && (section >= columnCount()))
2687 || ((orientation == Qt::Vertical) && (section >= rowCount()))) {
2688 return QVariant();
2689 }
2690 QStandardItem *headerItem = 0;
2691 if (orientation == Qt::Horizontal)
2692 headerItem = d->columnHeaderItems.at(section);
2693 else if (orientation == Qt::Vertical)
2694 headerItem = d->rowHeaderItems.at(section);
2695 return headerItem ? headerItem->data(role)
2696 : QAbstractItemModel::headerData(section, orientation, role);
2697}
2698
2699/*!
2700 \reimp
2701
2702 QStandardItemModel supports both copy and move.
2703*/
2704Qt::DropActions QStandardItemModel::supportedDropActions () const
2705{
2706 return Qt::CopyAction | Qt::MoveAction;
2707}
2708
2709/*!
2710 \reimp
2711*/
2712QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent) const
2713{
2714 Q_D(const QStandardItemModel);
2715 QStandardItem *parentItem = d->itemFromIndex(parent);
2716 if ((parentItem == 0)
2717 || (row < 0)
2718 || (column < 0)
2719 || (row >= parentItem->rowCount())
2720 || (column >= parentItem->columnCount())) {
2721 return QModelIndex();
2722 }
2723 return createIndex(row, column, parentItem);
2724}
2725
2726/*!
2727 \reimp
2728*/
2729bool QStandardItemModel::insertColumns(int column, int count, const QModelIndex &parent)
2730{
2731 Q_D(QStandardItemModel);
2732 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root;
2733 if (item == 0)
2734 return false;
2735 return item->d_func()->insertColumns(column, count, QList<QStandardItem*>());
2736}
2737
2738/*!
2739 \reimp
2740*/
2741bool QStandardItemModel::insertRows(int row, int count, const QModelIndex &parent)
2742{
2743 Q_D(QStandardItemModel);
2744 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root;
2745 if (item == 0)
2746 return false;
2747 return item->d_func()->insertRows(row, count, QList<QStandardItem*>());
2748}
2749
2750/*!
2751 \reimp
2752*/
2753QMap<int, QVariant> QStandardItemModel::itemData(const QModelIndex &index) const
2754{
2755 Q_D(const QStandardItemModel);
2756 QStandardItem *item = d->itemFromIndex(index);
2757 return item ? item->d_func()->itemData() : QMap<int, QVariant>();
2758}
2759
2760/*!
2761 \reimp
2762*/
2763QModelIndex QStandardItemModel::parent(const QModelIndex &child) const
2764{
2765 Q_D(const QStandardItemModel);
2766 if (!d->indexValid(child))
2767 return QModelIndex();
2768 QStandardItem *parentItem = static_cast<QStandardItem*>(child.internalPointer());
2769 return indexFromItem(parentItem);
2770}
2771
2772/*!
2773 \reimp
2774*/
2775bool QStandardItemModel::removeColumns(int column, int count, const QModelIndex &parent)
2776{
2777 Q_D(QStandardItemModel);
2778 QStandardItem *item = d->itemFromIndex(parent);
2779 if ((item == 0) || (count < 1) || (column < 0) || ((column + count) > item->columnCount()))
2780 return false;
2781 item->removeColumns(column, count);
2782 return true;
2783}
2784
2785/*!
2786 \reimp
2787*/
2788bool QStandardItemModel::removeRows(int row, int count, const QModelIndex &parent)
2789{
2790 Q_D(QStandardItemModel);
2791 QStandardItem *item = d->itemFromIndex(parent);
2792 if ((item == 0) || (count < 1) || (row < 0) || ((row + count) > item->rowCount()))
2793 return false;
2794 item->removeRows(row, count);
2795 return true;
2796}
2797
2798/*!
2799 \reimp
2800*/
2801int QStandardItemModel::rowCount(const QModelIndex &parent) const
2802{
2803 Q_D(const QStandardItemModel);
2804 QStandardItem *item = d->itemFromIndex(parent);
2805 return item ? item->rowCount() : 0;
2806}
2807
2808/*!
2809 \reimp
2810*/
2811bool QStandardItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
2812{
2813 if (!index.isValid())
2814 return false;
2815 QStandardItem *item = itemFromIndex(index);
2816 if (item == 0)
2817 return false;
2818 item->setData(value, role);
2819 return true;
2820}
2821
2822/*!
2823 \reimp
2824*/
2825bool QStandardItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
2826{
2827 Q_D(QStandardItemModel);
2828 if ((section < 0)
2829 || ((orientation == Qt::Horizontal) && (section >= columnCount()))
2830 || ((orientation == Qt::Vertical) && (section >= rowCount()))) {
2831 return false;
2832 }
2833 QStandardItem *headerItem = 0;
2834 if (orientation == Qt::Horizontal) {
2835 headerItem = d->columnHeaderItems.at(section);
2836 if (headerItem == 0) {
2837 headerItem = d->createItem();
2838 headerItem->d_func()->setModel(this);
2839 d->columnHeaderItems.replace(section, headerItem);
2840 }
2841 } else if (orientation == Qt::Vertical) {
2842 headerItem = d->rowHeaderItems.at(section);
2843 if (headerItem == 0) {
2844 headerItem = d->createItem();
2845 headerItem->d_func()->setModel(this);
2846 d->rowHeaderItems.replace(section, headerItem);
2847 }
2848 }
2849 if (headerItem) {
2850 headerItem->setData(value, role);
2851 return true;
2852 }
2853 return false;
2854}
2855
2856/*!
2857 \reimp
2858*/
2859bool QStandardItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
2860{
2861 QStandardItem *item = itemFromIndex(index);
2862 if (item == 0)
2863 return false;
2864 item->d_func()->setItemData(roles);
2865 return true;
2866}
2867
2868/*!
2869 \reimp
2870*/
2871void QStandardItemModel::sort(int column, Qt::SortOrder order)
2872{
2873 Q_D(QStandardItemModel);
2874 d->root->sortChildren(column, order);
2875}
2876
2877/*!
2878 \fn QObject *QStandardItemModel::parent() const
2879 \internal
2880*/
2881
2882
2883/*!
2884 \reimp
2885*/
2886QStringList QStandardItemModel::mimeTypes() const
2887{
2888 return QAbstractItemModel::mimeTypes() << QLatin1String("application/x-qstandarditemmodeldatalist");
2889}
2890
2891/*!
2892 \reimp
2893*/
2894QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
2895{
2896 QMimeData *data = QAbstractItemModel::mimeData(indexes);
2897 if(!data)
2898 return 0;
2899
2900 QString format = QLatin1String("application/x-qstandarditemmodeldatalist");
2901 if (!mimeTypes().contains(format))
2902 return data;
2903 QByteArray encoded;
2904 QDataStream stream(&encoded, QIODevice::WriteOnly);
2905
2906 QSet<QStandardItem*> itemsSet;
2907 QStack<QStandardItem*> stack;
2908 itemsSet.reserve(indexes.count());
2909 stack.reserve(indexes.count());
2910 foreach (const QModelIndex &index, indexes) {
2911 QStandardItem *item = itemFromIndex(index);
2912 itemsSet << item;
2913 stack.push(item);
2914 }
2915
2916 //remove duplicates childrens
2917 {
2918 QSet<QStandardItem *> seen;
2919 while (!stack.isEmpty()) {
2920 QStandardItem *itm = stack.pop();
2921 if (seen.contains(itm))
2922 continue;
2923 seen.insert(itm);
2924
2925 const QVector<QStandardItem*> &childList = itm->d_func()->children;
2926 for (int i = 0; i < childList.count(); ++i) {
2927 QStandardItem *chi = childList.at(i);
2928 if (chi) {
2929 QSet<QStandardItem *>::iterator it = itemsSet.find(chi);
2930 if (it != itemsSet.end()) {
2931 itemsSet.erase(it);
2932 }
2933 stack.push(chi);
2934 }
2935 }
2936 }
2937 }
2938
2939 stack.reserve(itemsSet.count());
2940 foreach (QStandardItem *item, itemsSet) {
2941 stack.push(item);
2942 }
2943
2944 //stream everything recursively
2945 while (!stack.isEmpty()) {
2946 QStandardItem *item = stack.pop();
2947 if(itemsSet.contains(item)) { //if the item is selection 'top-level', strem its position
2948 stream << item->row() << item->column();
2949 }
2950 if(item) {
2951 stream << *item << item->columnCount() << item->d_ptr->children.count();
2952 stack += item->d_ptr->children;
2953 } else {
2954 QStandardItem dummy;
2955 stream << dummy << 0 << 0;
2956 }
2957 }
2958
2959 data->setData(format, encoded);
2960 return data;
2961}
2962
2963
2964/* \internal
2965 Used by QStandardItemModel::dropMimeData
2966 stream out an item and his children
2967 */
2968static void decodeDataRecursive(QDataStream &stream, QStandardItem *item)
2969{
2970 int colCount, childCount;
2971 stream >> *item;
2972 stream >> colCount >> childCount;
2973 item->setColumnCount(colCount);
2974
2975 int childPos = childCount;
2976
2977 while(childPos > 0) {
2978 childPos--;
2979 QStandardItem *child = new QStandardItem;
2980 decodeDataRecursive(stream, child);
2981 item->setChild( childPos / colCount, childPos % colCount, child);
2982 }
2983}
2984
2985
2986/*!
2987 \reimp
2988*/
2989bool QStandardItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
2990 int row, int column, const QModelIndex &parent)
2991{
2992 // check if the action is supported
2993 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
2994 return false;
2995 // check if the format is supported
2996 QString format = QLatin1String("application/x-qstandarditemmodeldatalist");
2997 if (!data->hasFormat(format))
2998 return QAbstractItemModel::dropMimeData(data, action, row, column, parent);
2999
3000 if (row > rowCount(parent))
3001 row = rowCount(parent);
3002 if (row == -1)
3003 row = rowCount(parent);
3004 if (column == -1)
3005 column = 0;
3006
3007 // decode and insert
3008 QByteArray encoded = data->data(format);
3009 QDataStream stream(&encoded, QIODevice::ReadOnly);
3010
3011
3012 //code based on QAbstractItemModel::decodeData
3013 // adapted to work with QStandardItem
3014 int top = INT_MAX;
3015 int left = INT_MAX;
3016 int bottom = 0;
3017 int right = 0;
3018 QVector<int> rows, columns;
3019 QVector<QStandardItem *> items;
3020
3021 while (!stream.atEnd()) {
3022 int r, c;
3023 QStandardItem *item = new QStandardItem;
3024 stream >> r >> c;
3025 decodeDataRecursive(stream, item);
3026
3027 rows.append(r);
3028 columns.append(c);
3029 items.append(item);
3030 top = qMin(r, top);
3031 left = qMin(c, left);
3032 bottom = qMax(r, bottom);
3033 right = qMax(c, right);
3034 }
3035
3036 // insert the dragged items into the table, use a bit array to avoid overwriting items,
3037 // since items from different tables can have the same row and column
3038 int dragRowCount = 0;
3039 int dragColumnCount = right - left + 1;
3040
3041 // Compute the number of continuous rows upon insertion and modify the rows to match
3042 QVector<int> rowsToInsert(bottom + 1);
3043 for (int i = 0; i < rows.count(); ++i)
3044 rowsToInsert[rows.at(i)] = 1;
3045 for (int i = 0; i < rowsToInsert.count(); ++i) {
3046 if (rowsToInsert[i] == 1){
3047 rowsToInsert[i] = dragRowCount;
3048 ++dragRowCount;
3049 }
3050 }
3051 for (int i = 0; i < rows.count(); ++i)
3052 rows[i] = top + rowsToInsert[rows[i]];
3053
3054 QBitArray isWrittenTo(dragRowCount * dragColumnCount);
3055
3056 // make space in the table for the dropped data
3057 int colCount = columnCount(parent);
3058 if (colCount < dragColumnCount + column) {
3059 insertColumns(colCount, dragColumnCount + column - colCount, parent);
3060 colCount = columnCount(parent);
3061 }
3062 insertRows(row, dragRowCount, parent);
3063
3064 row = qMax(0, row);
3065 column = qMax(0, column);
3066
3067 QStandardItem *parentItem = itemFromIndex (parent);
3068 if (!parentItem)
3069 parentItem = invisibleRootItem();
3070
3071 QVector<QPersistentModelIndex> newIndexes(items.size());
3072 // set the data in the table
3073 for (int j = 0; j < items.size(); ++j) {
3074 int relativeRow = rows.at(j) - top;
3075 int relativeColumn = columns.at(j) - left;
3076 int destinationRow = relativeRow + row;
3077 int destinationColumn = relativeColumn + column;
3078 int flat = (relativeRow * dragColumnCount) + relativeColumn;
3079 // if the item was already written to, or we just can't fit it in the table, create a new row
3080 if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) {
3081 destinationColumn = qBound(column, destinationColumn, colCount - 1);
3082 destinationRow = row + dragRowCount;
3083 insertRows(row + dragRowCount, 1, parent);
3084 flat = (dragRowCount * dragColumnCount) + relativeColumn;
3085 isWrittenTo.resize(++dragRowCount * dragColumnCount);
3086 }
3087 if (!isWrittenTo.testBit(flat)) {
3088 newIndexes[j] = index(destinationRow, destinationColumn, parentItem->index());
3089 isWrittenTo.setBit(flat);
3090 }
3091 }
3092
3093 for(int k = 0; k < newIndexes.size(); k++) {
3094 if (newIndexes.at(k).isValid()) {
3095 parentItem->setChild(newIndexes.at(k).row(), newIndexes.at(k).column(), items.at(k));
3096 } else {
3097 delete items.at(k);
3098 }
3099 }
3100
3101 return true;
3102}
3103
3104QT_END_NAMESPACE
3105
3106#include "moc_qstandarditemmodel.cpp"
3107
3108#endif // QT_NO_STANDARDITEMMODEL
Note: See TracBrowser for help on using the repository browser.