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