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

source code of qtbase/src/gui/itemmodels/qstandarditemmodel.cpp