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