Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qstandarditemmodel.cpp
Go to the documentation of this file.
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
5
6#include <QtCore/qdatetime.h>
7#include <QtCore/qlist.h>
8#include <QtCore/qmap.h>
9#include <QtCore/qpair.h>
10#include <QtCore/qvariant.h>
11#include <QtCore/qstringlist.h>
12#include <QtCore/qbitarray.h>
13#include <QtCore/qmimedata.h>
14#include <QtCore/qiodevice.h>
15#include <private/qduplicatetracker_p.h>
16#include <private/qstandarditemmodel_p.h>
17#include <qdebug.h>
18#include <algorithm>
19
21
23{
24 return QStringLiteral("application/x-qstandarditemmodeldatalist");
25}
29public:
31 { }
32
34 const QPair<QStandardItem*, int> &r) const
35 {
36 return *(l.first) < *(r.first);
37 }
38};
39
41{
42public:
44 { }
45
47 const QPair<QStandardItem*, int> &r) const
48 {
49 return *(r.first) < *(l.first);
50 }
51};
52
57{
58 if (QStandardItem *par = parent) {
59 int idx = par->d_func()->childIndex(q_func());
60 if (idx == -1)
61 return QPair<int, int>(-1, -1);
62 return QPair<int, int>(idx / par->columnCount(), idx % par->columnCount());
63 }
64 // ### support header items?
65 return QPair<int, int>(-1, -1);
66}
67
72 bool emitChanged)
73{
74 Q_Q(QStandardItem);
75 if (item == q) {
76 qWarning("QStandardItem::setChild: Can't make an item a child of itself %p",
77 item);
78 return;
79 }
80 if ((row < 0) || (column < 0))
81 return;
82 if (rows <= row)
83 q->setRowCount(row + 1);
84 if (columns <= column)
85 q->setColumnCount(column + 1);
86 int index = childIndex(row, column);
87 Q_ASSERT(index != -1);
88 QStandardItem *oldItem = children.at(index);
89 if (item == oldItem)
90 return;
91
92 if (model && emitChanged) {
94 }
95
96 if (item) {
97 if (item->d_func()->parent == nullptr) {
98 item->d_func()->setParentAndModel(q, model);
99 } else {
100 qWarning("QStandardItem::setChild: Ignoring duplicate insertion of item %p",
101 item);
102 return;
103 }
104 }
105
106 // setting the model to nullptr invalidates the persistent index which we want to avoid
107 if (!item && oldItem)
108 oldItem->d_func()->setModel(nullptr);
109
111
112 // since now indexFromItem() does no longer return a valid index, the persistent index
113 // will not be invalidated anymore
114 if (oldItem)
115 oldItem->d_func()->setModel(nullptr);
116 delete oldItem;
117
118 if (item)
119 item->d_func()->lastKnownIndex = index;
120
121 if (model && emitChanged)
123
124 if (emitChanged && model) {
125 if (item) {
126 model->d_func()->itemChanged(item);
127 } else {
128 const QModelIndex idx = model->index(row, column, q->index());
129 emit model->dataChanged(idx, idx);
130 }
131 }
132}
133
134
139{
140 Q_Q(QStandardItem);
141 Qt::ItemFlags flags = q->flags();
142 if (enable)
143 flags |= f;
144 else
145 flags &= ~f;
146 q->setFlags(flags);
147}
148
153{
154 int index = childIndex(child);
155 Q_ASSERT(index != -1);
156 const auto modelIndex = child->index();
157 children.replace(index, nullptr);
158 emit model->dataChanged(modelIndex, modelIndex);
159}
160
161namespace {
162
163 struct ByNormalizedRole
164 {
165 static int normalizedRole(int role)
166 {
167 return role == Qt::EditRole ? Qt::DisplayRole : role;
168 }
169
170 bool operator()(const QStandardItemData& standardItemData, const std::pair<const int &, const QVariant&>& roleMapIt) const
171 {
172 return standardItemData.role < normalizedRole(roleMapIt.first);
173 }
174 bool operator()(const std::pair<const int&, const QVariant &>& roleMapIt, const QStandardItemData& standardItemData) const
175 {
176 return normalizedRole(roleMapIt.first) < standardItemData.role;
177 }
178
179 };
180
181 /*
182 Based on std::transform with a twist. The inputs are iterators of <int, QVariant> pair.
183 The variant is checked for validity and if not valid, that element is not taken into account
184 which means that the resulting output might be shorter than the input.
185 */
186 template<class Input, class OutputIt>
187 OutputIt roleMapStandardItemDataTransform(Input first1, Input last1, OutputIt d_first)
188 {
189 while (first1 != last1) {
190 if ((*first1).second.isValid())
191 *d_first++ = QStandardItemData(*first1);
192 ++first1;
193 }
194 return d_first;
195 }
196
197
198 /*
199 Based on std::set_union with a twist. The idea is to create a union of both inputs
200 with an additional constraint: if an input contains an invalid variant, it means
201 that this one should not be taken into account for generating the output.
202 */
203 template<class Input1, class Input2,
204 class OutputIt, class Compare>
205 OutputIt roleMapStandardItemDataUnion(Input1 first1, Input1 last1,
206 Input2 first2, Input2 last2,
207 OutputIt d_first, Compare comp)
208 {
209 for (; first1 != last1; ++d_first) {
210 if (first2 == last2) {
211 return roleMapStandardItemDataTransform(first1, last1, d_first);
212 }
213 if (comp(*first2, *first1)) {
214 *d_first = *first2++;
215 } else {
216 if ((*first1).second.isValid())
217 *d_first = QStandardItemData(*first1);
218 if (!comp(*first1, *first2))
219 ++first2;
220 ++first1;
221 }
222 }
223 return std::copy(first2, last2, d_first);
224 }
225}
226
231{
232 Q_Q(QStandardItem);
233
234 auto byRole = [](const QStandardItemData& item1, const QStandardItemData& item2) {
235 return item1.role < item2.role;
236 };
237
238 std::sort(values.begin(), values.end(), byRole);
239
240 /*
241 Create a list of QStandardItemData that will contain the original values
242 if the matching role is not contained in roles, the new value if it is and
243 if the new value is an invalid QVariant, it will be removed.
244 */
245 QList<QStandardItemData> newValues;
246 newValues.reserve(values.size());
247 roleMapStandardItemDataUnion(roles.keyValueBegin(),
248 roles.keyValueEnd(),
249 values.cbegin(), values.cend(),
250 std::back_inserter(newValues), ByNormalizedRole());
251
252 if (newValues != values) {
253 values.swap(newValues);
254 if (model) {
255 QList<int> roleKeys;
256 roleKeys.reserve(roles.size() + 1);
257 bool hasEditRole = false;
258 bool hasDisplayRole = false;
259 for (auto it = roles.keyBegin(); it != roles.keyEnd(); ++it) {
260 roleKeys.push_back(*it);
261 if (*it == Qt::EditRole)
262 hasEditRole = true;
263 else if (*it == Qt::DisplayRole)
264 hasDisplayRole = true;
265 }
266 if (hasEditRole && !hasDisplayRole)
267 roleKeys.push_back(Qt::DisplayRole);
268 else if (!hasEditRole && hasDisplayRole)
269 roleKeys.push_back(Qt::EditRole);
270 model->d_func()->itemChanged(q, roleKeys);
271 }
272 }
273}
274
279{
281 for (const auto &data : values) {
282 // Qt::UserRole - 1 is used internally to store the flags
283 if (data.role != Qt::UserRole - 1)
284 result.insert(data.role, data.value);
285 }
286 return result;
287}
288
293{
294 Q_Q(QStandardItem);
295 if (column >= columnCount())
296 return;
297
299 QList<int> unsortable;
300
301 sortable.reserve(rowCount());
302 unsortable.reserve(rowCount());
303
304 for (int row = 0; row < rowCount(); ++row) {
305 QStandardItem *itm = q->child(row, column);
306 if (itm)
307 sortable.append(QPair<QStandardItem*,int>(itm, row));
308 else
309 unsortable.append(row);
310 }
311
312 if (order == Qt::AscendingOrder) {
314 std::stable_sort(sortable.begin(), sortable.end(), lt);
315 } else {
317 std::stable_sort(sortable.begin(), sortable.end(), gt);
318 }
319
320 QModelIndexList changedPersistentIndexesFrom, changedPersistentIndexesTo;
321 QList<QStandardItem*> sorted_children(children.size());
322 for (int i = 0; i < rowCount(); ++i) {
323 int r = (i < sortable.size()
324 ? sortable.at(i).second
325 : unsortable.at(i - sortable.size()));
326 for (int c = 0; c < columnCount(); ++c) {
327 QStandardItem *itm = q->child(r, c);
328 sorted_children[childIndex(i, c)] = itm;
329 if (model) {
330 QModelIndex from = model->createIndex(r, c, q);
331 if (model->d_func()->persistent.indexes.contains(from)) {
332 QModelIndex to = model->createIndex(i, c, q);
333 changedPersistentIndexesFrom.append(from);
334 changedPersistentIndexesTo.append(to);
335 }
336 }
337 }
338 }
339
340 children = sorted_children;
341
342 if (model) {
343 model->changePersistentIndexList(changedPersistentIndexesFrom, changedPersistentIndexesTo);
344 }
345
347 for (it = children.begin(); it != children.end(); ++it) {
348 if (*it)
349 (*it)->d_func()->sortChildren(column, order);
350 }
351}
352
358{
359 if (children.isEmpty()) {
360 if (model)
361 model->d_func()->invalidatePersistentIndex(model->indexFromItem(q_ptr));
362 model = mod;
363 } else {
365 stack.push(q_ptr);
366 while (!stack.isEmpty()) {
367 QStandardItem *itm = stack.pop();
368 if (itm->d_func()->model) {
369 itm->d_func()->model->d_func()->invalidatePersistentIndex(itm->d_func()->model->indexFromItem(itm));
370 }
371 itm->d_func()->model = mod;
372 const QList<QStandardItem*> &childList = itm->d_func()->children;
373 for (int i = 0; i < childList.size(); ++i) {
374 QStandardItem *chi = childList.at(i);
375 if (chi)
376 stack.push(chi);
377 }
378 }
379 }
380}
381
386 : root(new QStandardItem), itemPrototype(nullptr)
387{
389}
390
395{
396}
397
402{
407}
408
413 const QModelIndex &bottomRight)
414{
416 QModelIndex parent = topLeft.parent();
417 for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {
418 for (int column = topLeft.column(); column <= bottomRight.column(); ++column) {
419 QModelIndex index = q->index(row, column, parent);
421 emit q->itemChanged(item);
422 }
423 }
424}
425
430{
431 Q_Q(QStandardItem);
432 if ((row < 0) || (row > rowCount()) || items.isEmpty())
433 return false;
434 int count = items.size();
435 if (model)
436 model->d_func()->rowsAboutToBeInserted(q, row, row + count - 1);
437 if (rowCount() == 0) {
438 if (columnCount() == 0)
439 q->setColumnCount(1);
441 rows = count;
442 } else {
443 rows += count;
444 int index = childIndex(row, 0);
445 if (index != -1)
446 children.insert(index, columnCount() * count, nullptr);
447 }
448 for (int i = 0; i < items.size(); ++i) {
450 item->d_func()->model = model;
451 item->d_func()->parent = q;
452 int index = childIndex(i + row, 0);
454 if (item)
455 item->d_func()->lastKnownIndex = index;
456 }
457 if (model)
458 model->d_func()->rowsInserted(q, row, count);
459 return true;
460}
461
463{
464 Q_Q(QStandardItem);
465 if ((count < 1) || (row < 0) || (row > rowCount()) || count == 0)
466 return false;
467 if (model)
468 model->d_func()->rowsAboutToBeInserted(q, row, row + count - 1);
469 if (rowCount() == 0) {
471 rows = count;
472 } else {
473 rows += count;
474 int index = childIndex(row, 0);
475 if (index != -1)
476 children.insert(index, columnCount() * count, nullptr);
477 }
478 if (!items.isEmpty()) {
479 int index = childIndex(row, 0);
480 int limit = qMin(items.size(), columnCount() * count);
481 for (int i = 0; i < limit; ++i) {
483 if (item) {
484 if (item->d_func()->parent == nullptr) {
485 item->d_func()->setParentAndModel(q, model);
486 } else {
487 qWarning("QStandardItem::insertRows: Ignoring duplicate insertion of item %p",
488 item);
489 item = nullptr;
490 }
491 }
493 if (item)
494 item->d_func()->lastKnownIndex = index;
495 ++index;
496 }
497 }
498 if (model)
499 model->d_func()->rowsInserted(q, row, count);
500 return true;
501}
502
507{
508 Q_Q(QStandardItem);
509 if ((count < 1) || (column < 0) || (column > columnCount()) || count == 0)
510 return false;
511 if (model)
513 if (columnCount() == 0) {
515 columns = count;
516 } else {
517 columns += count;
518 int index = childIndex(0, column);
519 for (int row = 0; row < rowCount(); ++row) {
520 children.insert(index, count, nullptr);
521 index += columnCount();
522 }
523 }
524 if (!items.isEmpty()) {
525 int limit = qMin(items.size(), rowCount() * count);
526 for (int i = 0; i < limit; ++i) {
528 if (item) {
529 if (item->d_func()->parent == nullptr) {
530 item->d_func()->setParentAndModel(q, model);
531 } else {
532 qWarning("QStandardItem::insertColumns: Ignoring duplicate insertion of item %p",
533 item);
534 item = nullptr;
535 }
536 }
537 int r = i / count;
538 int c = column + (i % count);
539 int index = childIndex(r, c);
541 if (item)
542 item->d_func()->lastKnownIndex = index;
543 }
544 }
545 if (model)
546 model->d_func()->columnsInserted(q, column, count);
547 return true;
548}
549
554{
556 Q_ASSERT(item);
557 if (item->d_func()->parent == nullptr) {
558 // Header item
559 int idx = columnHeaderItems.indexOf(item);
560 if (idx != -1) {
561 emit q->headerDataChanged(Qt::Horizontal, idx, idx);
562 } else {
564 if (idx != -1)
565 emit q->headerDataChanged(Qt::Vertical, idx, idx);
566 }
567 } else {
568 // Normal item
569 const QModelIndex index = q->indexFromItem(item);
570 emit q->dataChanged(index, index, roles);
571 }
572}
573
578 int start, int end)
579{
581 QModelIndex index = q->indexFromItem(parent);
582 q->beginInsertRows(index, start, end);
583}
584
589 int start, int end)
590{
592 QModelIndex index = q->indexFromItem(parent);
593 q->beginInsertColumns(index, start, end);
594}
595
600 int start, int end)
601{
603 QModelIndex index = q->indexFromItem(parent);
604 q->beginRemoveRows(index, start, end);
605}
606
611 int start, int end)
612{
614 QModelIndex index = q->indexFromItem(parent);
615 q->beginRemoveColumns(index, start, end);
616}
617
622 int row, int count)
623{
625 if (parent == root.data())
626 rowHeaderItems.insert(row, count, nullptr);
627 q->endInsertRows();
628}
629
634 int column, int count)
635{
637 if (parent == root.data())
639 q->endInsertColumns();
640}
641
646 int row, int count)
647{
649 if (parent == root.data()) {
650 for (int i = row; i < row + count; ++i) {
651 QStandardItem *oldItem = rowHeaderItems.at(i);
652 if (oldItem)
653 oldItem->d_func()->setModel(nullptr);
654 delete oldItem;
655 }
657 }
658 q->endRemoveRows();
659}
660
665 int column, int count)
666{
668 if (parent == root.data()) {
669 for (int i = column; i < column + count; ++i) {
671 if (oldItem)
672 oldItem->d_func()->setModel(nullptr);
673 delete oldItem;
674 }
676 }
677 q->endRemoveColumns();
678}
679
767{
768}
769
775{
776 setText(text);
777}
778
784{
785 setIcon(icon);
786}
787
791QStandardItem::QStandardItem(int rows, int columns)
793{
794 setRowCount(rows);
795 setColumnCount(columns);
796}
797
802 : d_ptr(&dd)
803{
804 Q_D(QStandardItem);
805 d->q_ptr = this;
806}
807
815 : d_ptr(new QStandardItemPrivate)
816{
817 Q_D(QStandardItem);
818 d->q_ptr = this;
820}
821
829{
830 Q_D(QStandardItem);
831 d->values = other.d_func()->values;
832 return *this;
833}
834
840{
841 Q_D(QStandardItem);
842 for (QStandardItem *child : std::as_const(d->children)) {
843 if (child)
844 child->d_func()->setModel(nullptr);
845 delete child;
846 }
847 d->children.clear();
848 if (d->parent && d->model)
849 d->parent->d_func()->childDeleted(this);
850}
851
860{
861 Q_D(const QStandardItem);
862 if (!d->model || (d->model->d_func()->root.data() != d->parent))
863 return d->parent;
864 return nullptr;
865}
866
881{
882 Q_D(QStandardItem);
883 role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
884 const QList<int> roles((role == Qt::DisplayRole) ?
886 QList<int>({role}));
887 for (auto it = d->values.begin(); it != d->values.end(); ++it) {
888 if ((*it).role == role) {
889 if (value.isValid()) {
890 if ((*it).value.userType() == value.userType() && (*it).value == value)
891 return;
892 (*it).value = value;
893 } else {
894 // Don't need to assign proper it after erase() since we
895 // return unconditionally in this code path.
896 d->values.erase(it);
897 }
898 if (d->model)
899 d->model->d_func()->itemChanged(this, roles);
900 return;
901 }
902 }
903 d->values.append(QStandardItemData(role, value));
904 if (d->model)
905 d->model->d_func()->itemChanged(this, roles);
906}
907
914{
915 Q_D(QStandardItem);
916 if (d->values.isEmpty())
917 return;
918 d->values.clear();
919 if (d->model)
920 d->model->d_func()->itemChanged(this, QList<int>{});
921}
922
931{
932 Q_D(const QStandardItem);
933 const int r = (role == Qt::EditRole) ? Qt::DisplayRole : role;
934 for (const auto &value : d->values) {
935 if (value.role == r)
936 return value.value;
937 }
938 return QVariant();
939}
940
952{
953 for (auto &roleData : roleDataSpan)
954 roleData.setData(data(roleData.role()));
955}
956
970{
971 Q_D(QStandardItem);
972 if (d->model)
973 d->model->d_func()->itemChanged(this);
974}
975
985{
986 setData((int)flags, Qt::UserRole - 1);
987}
988
999Qt::ItemFlags QStandardItem::flags() const
1000{
1001 QVariant v = data(Qt::UserRole - 1);
1002 if (!v.isValid())
1005 return Qt::ItemFlags(v.toInt());
1006}
1007
1246{
1247 Q_D(QStandardItem);
1248 d->changeFlags(enabled, Qt::ItemIsEnabled);
1249}
1250
1275{
1276 Q_D(QStandardItem);
1277 d->changeFlags(editable, Qt::ItemIsEditable);
1278}
1279
1304void QStandardItem::setSelectable(bool selectable)
1305{
1306 Q_D(QStandardItem);
1307 d->changeFlags(selectable, Qt::ItemIsSelectable);
1308}
1309
1331{
1332 Q_D(QStandardItem);
1333 if (checkable && !isCheckable()) {
1334 // make sure there's data for the checkstate role
1335 if (!data(Qt::CheckStateRole).isValid())
1337 }
1338 d->changeFlags(checkable, Qt::ItemIsUserCheckable);
1339}
1340
1362{
1363 Q_D(QStandardItem);
1364 d->changeFlags(tristate, Qt::ItemIsAutoTristate);
1365}
1366
1388{
1389 Q_D(QStandardItem);
1390 d->changeFlags(tristate, Qt::ItemIsUserTristate);
1391}
1392
1405#if QT_CONFIG(draganddrop)
1406
1416void QStandardItem::setDragEnabled(bool dragEnabled)
1417{
1418 Q_D(QStandardItem);
1419 d->changeFlags(dragEnabled, Qt::ItemIsDragEnabled);
1420}
1421
1446void QStandardItem::setDropEnabled(bool dropEnabled)
1447{
1448 Q_D(QStandardItem);
1449 d->changeFlags(dropEnabled, Qt::ItemIsDropEnabled);
1450}
1451
1463#endif // QT_CONFIG(draganddrop)
1464
1472{
1473 Q_D(const QStandardItem);
1474 QPair<int, int> pos = d->position();
1475 return pos.first;
1476}
1477
1485{
1486 Q_D(const QStandardItem);
1487 QPair<int, int> pos = d->position();
1488 return pos.second;
1489}
1490
1504{
1505 Q_D(const QStandardItem);
1506 return d->model ? d->model->indexFromItem(this) : QModelIndex();
1507}
1508
1518{
1519 Q_D(const QStandardItem);
1520 return d->model;
1521}
1522
1530{
1531 int rc = rowCount();
1532 if (rc == rows)
1533 return;
1534 if (rc < rows)
1535 insertRows(qMax(rc, 0), rows - rc);
1536 else
1537 removeRows(qMax(rows, 0), rc - rows);
1538}
1539
1546{
1547 Q_D(const QStandardItem);
1548 return d->rowCount();
1549}
1550
1558{
1559 int cc = columnCount();
1560 if (cc == columns)
1561 return;
1562 if (cc < columns)
1563 insertColumns(qMax(cc, 0), columns - cc);
1564 else
1565 removeColumns(qMax(columns, 0), cc - columns);
1566}
1567
1574{
1575 Q_D(const QStandardItem);
1576 return d->columnCount();
1577}
1578
1586{
1587 Q_D(QStandardItem);
1588 if (row < 0)
1589 return;
1590 if (columnCount() < items.size())
1592 d->insertRows(row, 1, items);
1593}
1594
1601{
1602 Q_D(QStandardItem);
1603 if (row < 0)
1604 return;
1605 d->insertRows(row, items);
1606}
1607
1615{
1616 Q_D(QStandardItem);
1617 if (column < 0)
1618 return;
1619 if (rowCount() < items.size())
1621 d->insertColumns(column, 1, items);
1622}
1623
1630{
1631 Q_D(QStandardItem);
1632 if (rowCount() < row) {
1633 count += row - rowCount();
1634 row = rowCount();
1635 }
1636 d->insertRows(row, count, QList<QStandardItem*>());
1637}
1638
1645{
1646 Q_D(QStandardItem);
1647 if (columnCount() < column) {
1648 count += column - columnCount();
1649 column = columnCount();
1650 }
1651 d->insertColumns(column, count, QList<QStandardItem*>());
1652}
1653
1726{
1727 removeRows(row, 1);
1728}
1729
1737{
1739}
1740
1748{
1749 Q_D(QStandardItem);
1750 if ((count < 1) || (row < 0) || ((row + count) > rowCount()))
1751 return;
1752 if (d->model)
1753 d->model->d_func()->rowsAboutToBeRemoved(this, row, row + count - 1);
1754 int i = d->childIndex(row, 0);
1755 int n = count * d->columnCount();
1756 for (int j = i; j < n+i; ++j) {
1757 QStandardItem *oldItem = d->children.at(j);
1758 if (oldItem)
1759 oldItem->d_func()->setModel(nullptr);
1760 delete oldItem;
1761 }
1762 d->children.remove(qMax(i, 0), n);
1763 d->rows -= count;
1764 if (d->model)
1765 d->model->d_func()->rowsRemoved(this, row, count);
1766}
1767
1775{
1776 Q_D(QStandardItem);
1777 if ((count < 1) || (column < 0) || ((column + count) > columnCount()))
1778 return;
1779 if (d->model)
1780 d->model->d_func()->columnsAboutToBeRemoved(this, column, column + count - 1);
1781 for (int row = d->rowCount() - 1; row >= 0; --row) {
1782 int i = d->childIndex(row, column);
1783 for (int j=i; j<i+count; ++j) {
1784 QStandardItem *oldItem = d->children.at(j);
1785 if (oldItem)
1786 oldItem->d_func()->setModel(nullptr);
1787 delete oldItem;
1788 }
1789 d->children.remove(i, count);
1790 }
1791 d->columns -= count;
1792 if (d->model)
1793 d->model->d_func()->columnsRemoved(this, column, count);
1794}
1795
1802{
1803 return (rowCount() > 0) && (columnCount() > 0);
1804}
1805
1816{
1817 Q_D(QStandardItem);
1818 d->setChild(row, column, item, true);
1819}
1820
1835{
1836 Q_D(const QStandardItem);
1837 int index = d->childIndex(row, column);
1838 if (index == -1)
1839 return nullptr;
1840 return d->children.at(index);
1841}
1842
1854{
1855 Q_D(QStandardItem);
1856 QStandardItem *item = nullptr;
1857 int index = d->childIndex(row, column);
1858 if (index != -1) {
1859 QModelIndex changedIdx;
1860 item = d->children.at(index);
1861 if (item && d->model) {
1862 QStandardItemPrivate *const item_d = item->d_func();
1863 const int savedRows = item_d->rows;
1864 const int savedCols = item_d->columns;
1865 const QVector<QStandardItem*> savedChildren = item_d->children;
1866 if (savedRows > 0) {
1867 d->model->d_func()->rowsAboutToBeRemoved(item, 0, savedRows - 1);
1868 item_d->rows = 0;
1869 item_d->children = QVector<QStandardItem*>(); //slightly faster than clear
1870 d->model->d_func()->rowsRemoved(item, 0, savedRows);
1871 }
1872 if (savedCols > 0) {
1873 d->model->d_func()->columnsAboutToBeRemoved(item, 0, savedCols - 1);
1874 item_d->columns = 0;
1875 if (!item_d->children.isEmpty())
1876 item_d->children = QVector<QStandardItem*>(); //slightly faster than clear
1877 d->model->d_func()->columnsRemoved(item, 0, savedCols);
1878 }
1879 item_d->rows = savedRows;
1880 item_d->columns = savedCols;
1881 item_d->children = savedChildren;
1882 changedIdx = d->model->indexFromItem(item);
1883 item_d->setParentAndModel(nullptr, nullptr);
1884 }
1885 d->children.replace(index, nullptr);
1886 if (changedIdx.isValid())
1887 d->model->dataChanged(changedIdx, changedIdx);
1888 }
1889 return item;
1890}
1891
1900{
1901 Q_D(QStandardItem);
1903 if ((row < 0) || (row >= rowCount()))
1904 return items;
1905 if (d->model)
1906 d->model->d_func()->rowsAboutToBeRemoved(this, row, row);
1907
1908 int index = d->childIndex(row, 0); // Will return -1 if there are no columns
1909 if (index != -1) {
1910 int col_count = d->columnCount();
1911 items.reserve(col_count);
1912 for (int column = 0; column < col_count; ++column) {
1913 QStandardItem *ch = d->children.at(index + column);
1914 if (ch)
1915 ch->d_func()->setParentAndModel(nullptr, nullptr);
1916 items.append(ch);
1917 }
1918 d->children.remove(index, col_count);
1919 }
1920 d->rows--;
1921 if (d->model)
1922 d->model->d_func()->rowsRemoved(this, row, 1);
1923 return items;
1924}
1925
1934{
1935 Q_D(QStandardItem);
1937 if ((column < 0) || (column >= columnCount()))
1938 return items;
1939 if (d->model)
1940 d->model->d_func()->columnsAboutToBeRemoved(this, column, column);
1941
1942 const int rowCount = d->rowCount();
1944 for (int row = rowCount - 1; row >= 0; --row) {
1945 int index = d->childIndex(row, column);
1946 QStandardItem *ch = d->children.at(index);
1947 if (ch)
1948 ch->d_func()->setParentAndModel(nullptr, nullptr);
1949 d->children.remove(index);
1950 items.prepend(ch);
1951 }
1952 d->columns--;
1953 if (d->model)
1954 d->model->d_func()->columnsRemoved(this, column, 1);
1955 return items;
1956}
1957
1971{
1972 const int role = model() ? model()->sortRole() : Qt::DisplayRole;
1973 const QVariant l = data(role), r = other.data(role);
1975}
1976
1987{
1988 Q_D(QStandardItem);
1989 if ((column < 0) || (rowCount() == 0))
1990 return;
1991
1993 if (d->model) {
1994 parents << index();
1995 emit d->model->layoutAboutToBeChanged(parents, QAbstractItemModel::VerticalSortHint);
1996 }
1997 d->sortChildren(column, order);
1998 if (d->model)
1999 emit d->model->layoutChanged(parents, QAbstractItemModel::VerticalSortHint);
2000}
2001
2012{
2013 return new QStandardItem(*this);
2014}
2015
2025{
2026 return Type;
2027}
2028
2029#ifndef QT_NO_DATASTREAM
2030
2038{
2039 Q_D(QStandardItem);
2040 in >> d->values;
2041 qint32 flags;
2042 in >> flags;
2043 setFlags(Qt::ItemFlags(flags));
2044}
2045
2053{
2054 Q_D(const QStandardItem);
2055 out << d->values;
2056 out << flags();
2057}
2058
2070{
2071 item.read(in);
2072 return in;
2073}
2074
2086{
2087 item.write(out);
2088 return out;
2089}
2090
2091#endif // QT_NO_DATASTREAM
2092
2185{
2186 Q_D(QStandardItemModel);
2187 d->init();
2188 d->root->d_func()->setModel(this);
2189}
2190
2197{
2198 Q_D(QStandardItemModel);
2199 d->init();
2200 d->root->insertColumns(0, columns);
2201 d->columnHeaderItems.insert(0, columns, nullptr);
2202 d->root->insertRows(0, rows);
2203 d->rowHeaderItems.insert(0, rows, nullptr);
2204 d->root->d_func()->setModel(this);
2205}
2206
2212{
2213 Q_D(QStandardItemModel);
2214 d->init();
2215}
2216
2221{
2222 Q_D(QStandardItemModel);
2223 delete d->itemPrototype;
2224 qDeleteAll(d->columnHeaderItems);
2225 qDeleteAll(d->rowHeaderItems);
2226 d->root.reset();
2227}
2228
2233{
2234 Q_D(QStandardItemModel);
2235 d->roleNames = roleNames;
2236}
2237
2242{
2243 Q_D(const QStandardItemModel);
2244 return d->roleNames;
2245}
2246
2254{
2255 Q_D(QStandardItemModel);
2257 d->root.reset(new QStandardItem);
2258 d->root->setFlags(Qt::ItemIsDropEnabled);
2259 d->root->d_func()->setModel(this);
2260 qDeleteAll(d->columnHeaderItems);
2261 d->columnHeaderItems.clear();
2262 qDeleteAll(d->rowHeaderItems);
2263 d->rowHeaderItems.clear();
2264 endResetModel();
2265}
2266
2287{
2288 Q_D(const QStandardItemModel);
2289 if ((index.row() < 0) || (index.column() < 0) || (index.model() != this))
2290 return nullptr;
2291 QStandardItem *parent = static_cast<QStandardItem*>(index.internalPointer());
2292 if (parent == nullptr)
2293 return nullptr;
2294 QStandardItem *item = parent->child(index.row(), index.column());
2295 // lazy part
2296 if (item == nullptr) {
2297 item = d->createItem();
2298 parent->d_func()->setChild(index.row(), index.column(), item);
2299 }
2300 return item;
2301}
2302
2316{
2317 if (item && item->d_func()->parent) {
2318 QPair<int, int> pos = item->d_func()->position();
2319 return createIndex(pos.first, pos.second, item->d_func()->parent);
2320 }
2321 return QModelIndex();
2322}
2323
2334{
2335 Q_D(QStandardItemModel);
2336 d->root->setRowCount(rows);
2337}
2338
2349{
2350 Q_D(QStandardItemModel);
2351 d->root->setColumnCount(columns);
2352}
2353
2365{
2366 Q_D(QStandardItemModel);
2367 d->root->d_func()->setChild(row, column, item, true);
2368}
2369
2384{
2385 Q_D(const QStandardItemModel);
2386 return d->root->child(row, column);
2387}
2388
2403{
2404 Q_D(const QStandardItemModel);
2405 return d->root.data();
2406}
2407
2419{
2420 Q_D(QStandardItemModel);
2421 if (column < 0)
2422 return;
2423 if (columnCount() <= column)
2425
2426 QStandardItem *oldItem = d->columnHeaderItems.at(column);
2427 if (item == oldItem)
2428 return;
2429
2430 if (item) {
2431 if (item->model() == nullptr) {
2432 item->d_func()->setModel(this);
2433 } else {
2434 qWarning("QStandardItem::setHorizontalHeaderItem: Ignoring duplicate insertion of item %p",
2435 item);
2436 return;
2437 }
2438 }
2439
2440 if (oldItem)
2441 oldItem->d_func()->setModel(nullptr);
2442 delete oldItem;
2443
2444 d->columnHeaderItems.replace(column, item);
2446}
2447
2457{
2458 Q_D(const QStandardItemModel);
2459 if ((column < 0) || (column >= columnCount()))
2460 return nullptr;
2461 return d->columnHeaderItems.at(column);
2462}
2463
2475{
2476 Q_D(QStandardItemModel);
2477 if (row < 0)
2478 return;
2479 if (rowCount() <= row)
2480 setRowCount(row + 1);
2481
2482 QStandardItem *oldItem = d->rowHeaderItems.at(row);
2483 if (item == oldItem)
2484 return;
2485
2486 if (item) {
2487 if (item->model() == nullptr) {
2488 item->d_func()->setModel(this);
2489 } else {
2490 qWarning("QStandardItem::setVerticalHeaderItem: Ignoring duplicate insertion of item %p",
2491 item);
2492 return;
2493 }
2494 }
2495
2496 if (oldItem)
2497 oldItem->d_func()->setModel(nullptr);
2498 delete oldItem;
2499
2500 d->rowHeaderItems.replace(row, item);
2502}
2503
2513{
2514 Q_D(const QStandardItemModel);
2515 if ((row < 0) || (row >= rowCount()))
2516 return nullptr;
2517 return d->rowHeaderItems.at(row);
2518}
2519
2529{
2530 Q_D(QStandardItemModel);
2531 if (columnCount() < labels.size())
2532 setColumnCount(labels.size());
2533 for (int i = 0; i < labels.size(); ++i) {
2535 if (!item) {
2536 item = d->createItem();
2538 }
2539 item->setText(labels.at(i));
2540 }
2541}
2542
2552{
2553 Q_D(QStandardItemModel);
2554 if (rowCount() < labels.size())
2555 setRowCount(labels.size());
2556 for (int i = 0; i < labels.size(); ++i) {
2558 if (!item) {
2559 item = d->createItem();
2561 }
2562 item->setText(labels.at(i));
2563 }
2564}
2565
2582{
2583 Q_D(QStandardItemModel);
2584 if (d->itemPrototype != item) {
2585 delete d->itemPrototype;
2586 d->itemPrototype = item;
2587 }
2588}
2589
2600{
2601 Q_D(const QStandardItemModel);
2602 return d->itemPrototype;
2603}
2604
2612 Qt::MatchFlags flags, int column) const
2613{
2614 QModelIndexList indexes = match(index(0, column, QModelIndex()),
2615 Qt::DisplayRole, text, -1, flags);
2617 const int numIndexes = indexes.size();
2618 items.reserve(numIndexes);
2619 for (int i = 0; i < numIndexes; ++i)
2620 items.append(itemFromIndex(indexes.at(i)));
2621 return items;
2622}
2623
2633{
2635}
2636
2646{
2648}
2649
2668{
2670}
2671
2693{
2695}
2696
2706{
2707 Q_D(QStandardItemModel);
2708 return d->root->takeChild(row, column);
2709}
2710
2722{
2723 Q_D(QStandardItemModel);
2724 return d->root->takeRow(row);
2725}
2726
2738{
2739 Q_D(QStandardItemModel);
2740 return d->root->takeColumn(column);
2741}
2742
2753{
2754 Q_D(QStandardItemModel);
2755 if ((column < 0) || (column >= columnCount()))
2756 return nullptr;
2757 QStandardItem *headerItem = d->columnHeaderItems.at(column);
2758 if (headerItem) {
2759 headerItem->d_func()->setParentAndModel(nullptr, nullptr);
2760 d->columnHeaderItems.replace(column, nullptr);
2761 }
2762 return headerItem;
2763}
2764
2775{
2776 Q_D(QStandardItemModel);
2777 if ((row < 0) || (row >= rowCount()))
2778 return nullptr;
2779 QStandardItem *headerItem = d->rowHeaderItems.at(row);
2780 if (headerItem) {
2781 headerItem->d_func()->setParentAndModel(nullptr, nullptr);
2782 d->rowHeaderItems.replace(row, nullptr);
2783 }
2784 return headerItem;
2785}
2786
2797{
2798 Q_D(const QStandardItemModel);
2799 return d->sortRole;
2800}
2801
2803{
2804 Q_D(QStandardItemModel);
2805 d->sortRole = role;
2806}
2807
2809{
2810 Q_D(QStandardItemModel);
2811 return &d->sortRole;
2812}
2813
2818{
2819 Q_D(const QStandardItemModel);
2820 QStandardItem *item = d->itemFromIndex(parent);
2821 return item ? item->columnCount() : 0;
2822}
2823
2828{
2829 Q_D(const QStandardItemModel);
2830 QStandardItem *item = d->itemFromIndex(index);
2831 return item ? item->data(role) : QVariant();
2832}
2833
2838{
2839 // Cannot offer a better implementation; users may be overriding
2840 // data(), and thus multiData() may fall out of sync for them.
2841 // The base class' implementation will simply call data() in a loop,
2842 // so it's fine.
2843 QAbstractItemModel::multiData(index, roleDataSpan);
2844}
2845
2850{
2851 Q_D(const QStandardItemModel);
2852 if (!d->indexValid(index))
2853 return d->root->flags();
2854 QStandardItem *item = d->itemFromIndex(index);
2855 if (item)
2856 return item->flags();
2862}
2863
2868{
2869 Q_D(const QStandardItemModel);
2870 QStandardItem *item = d->itemFromIndex(parent);
2871 return item ? item->hasChildren() : false;
2872}
2873
2877QVariant QStandardItemModel::headerData(int section, Qt::Orientation orientation, int role) const
2878{
2879 Q_D(const QStandardItemModel);
2880 if ((section < 0)
2881 || ((orientation == Qt::Horizontal) && (section >= columnCount()))
2882 || ((orientation == Qt::Vertical) && (section >= rowCount()))) {
2883 return QVariant();
2884 }
2885 QStandardItem *headerItem = nullptr;
2886 if (orientation == Qt::Horizontal)
2887 headerItem = d->columnHeaderItems.at(section);
2888 else if (orientation == Qt::Vertical)
2889 headerItem = d->rowHeaderItems.at(section);
2890 return headerItem ? headerItem->data(role)
2891 : QAbstractItemModel::headerData(section, orientation, role);
2892}
2893
2900{
2902}
2903
2908{
2909 Q_D(const QStandardItemModel);
2910 QStandardItem *parentItem = d->itemFromIndex(parent);
2911 if ((parentItem == nullptr)
2912 || (row < 0)
2913 || (column < 0)
2914 || (row >= parentItem->rowCount())
2915 || (column >= parentItem->columnCount())) {
2916 return QModelIndex();
2917 }
2918 return createIndex(row, column, parentItem);
2919}
2920
2925{
2926 Q_D(QStandardItemModel);
2927 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root.data();
2928 if (item == nullptr)
2929 return false;
2930 return item->d_func()->insertColumns(column, count, QList<QStandardItem*>());
2931}
2932
2937{
2938 Q_D(QStandardItemModel);
2939 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root.data();
2940 if (item == nullptr)
2941 return false;
2942 return item->d_func()->insertRows(row, count, QList<QStandardItem*>());
2943}
2944
2949{
2950 Q_D(const QStandardItemModel);
2951 const QStandardItem *const item = d->itemFromIndex(index);
2952 if (!item || item == d->root.data())
2953 return QMap<int, QVariant>();
2954 return item->d_func()->itemData();
2955}
2956
2961{
2962 Q_D(const QStandardItemModel);
2963 if (!d->indexValid(child))
2964 return QModelIndex();
2965 QStandardItem *parentItem = static_cast<QStandardItem*>(child.internalPointer());
2966 return indexFromItem(parentItem);
2967}
2968
2973{
2974 Q_D(QStandardItemModel);
2975 QStandardItem *item = d->itemFromIndex(parent);
2976 if ((item == nullptr) || (count < 1) || (column < 0) || ((column + count) > item->columnCount()))
2977 return false;
2978 item->removeColumns(column, count);
2979 return true;
2980}
2981
2986{
2987 Q_D(QStandardItemModel);
2988 QStandardItem *item = d->itemFromIndex(parent);
2989 if ((item == nullptr) || (count < 1) || (row < 0) || ((row + count) > item->rowCount()))
2990 return false;
2991 item->removeRows(row, count);
2992 return true;
2993}
2994
2999{
3000 Q_D(const QStandardItemModel);
3001 QStandardItem *item = d->itemFromIndex(parent);
3002 return item ? item->rowCount() : 0;
3003}
3004
3009{
3010 if (!index.isValid())
3011 return false;
3013 if (item == nullptr)
3014 return false;
3015 item->setData(value, role);
3016 return true;
3017}
3018
3023{
3025 return false;
3026 Q_D(QStandardItemModel);
3027 QStandardItem *item = d->itemFromIndex(index);
3028 if (!item)
3029 return false;
3030 item->clearData();
3031 return true;
3032}
3033
3037bool QStandardItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
3038{
3039 Q_D(QStandardItemModel);
3040 if ((section < 0)
3041 || ((orientation == Qt::Horizontal) && (section >= columnCount()))
3042 || ((orientation == Qt::Vertical) && (section >= rowCount()))) {
3043 return false;
3044 }
3045 QStandardItem *headerItem = nullptr;
3046 if (orientation == Qt::Horizontal) {
3047 headerItem = d->columnHeaderItems.at(section);
3048 if (headerItem == nullptr) {
3049 headerItem = d->createItem();
3050 headerItem->d_func()->setModel(this);
3051 d->columnHeaderItems.replace(section, headerItem);
3052 }
3053 } else if (orientation == Qt::Vertical) {
3054 headerItem = d->rowHeaderItems.at(section);
3055 if (headerItem == nullptr) {
3056 headerItem = d->createItem();
3057 headerItem->d_func()->setModel(this);
3058 d->rowHeaderItems.replace(section, headerItem);
3059 }
3060 }
3061 if (headerItem) {
3062 headerItem->setData(value, role);
3063 return true;
3064 }
3065 return false;
3066}
3067
3072{
3074 if (item == nullptr)
3075 return false;
3076 item->d_func()->setItemData(roles);
3077 return true;
3078}
3079
3084{
3085 Q_D(QStandardItemModel);
3086 d->root->sortChildren(column, order);
3087}
3088
3093{
3095}
3096
3101{
3103 if (!data)
3104 return nullptr;
3105
3107 if (!mimeTypes().contains(format))
3108 return data;
3111
3112 QSet<QStandardItem*> itemsSet;
3114 itemsSet.reserve(indexes.size());
3115 stack.reserve(indexes.size());
3116 for (int i = 0; i < indexes.size(); ++i) {
3117 if (QStandardItem *item = itemFromIndex(indexes.at(i))) {
3118 itemsSet << item;
3119 stack.push(item);
3120 } else {
3121 qWarning("QStandardItemModel::mimeData: No item associated with invalid index");
3122 return nullptr;
3123 }
3124 }
3125
3126 //remove duplicates children
3127 {
3129 while (!stack.isEmpty()) {
3130 QStandardItem *itm = stack.pop();
3131 if (seen.hasSeen(itm))
3132 continue;
3133
3134 const QList<QStandardItem*> &childList = itm->d_func()->children;
3135 for (int i = 0; i < childList.size(); ++i) {
3136 QStandardItem *chi = childList.at(i);
3137 if (chi) {
3138 itemsSet.remove(chi);
3139 stack.push(chi);
3140 }
3141 }
3142 }
3143 }
3144
3145 stack.reserve(itemsSet.size());
3146 for (QStandardItem *item : std::as_const(itemsSet))
3147 stack.push(item);
3148
3149 //stream everything recursively
3150 while (!stack.isEmpty()) {
3151 QStandardItem *item = stack.pop();
3152 if (itemsSet.contains(item)) //if the item is selection 'top-level', stream its position
3153 stream << item->row() << item->column();
3154
3155 stream << *item << item->columnCount() << int(item->d_ptr->children.size());
3156 stack += item->d_ptr->children;
3157 }
3158
3159 data->setData(format, encoded);
3160 return data;
3161}
3162
3163
3164/* \internal
3165 Used by QStandardItemModel::dropMimeData
3166 stream out an item and his children
3167 */
3169{
3170 int colCount, childCount;
3171 stream >> *item;
3172 stream >> colCount >> childCount;
3173 item->setColumnCount(colCount);
3174
3175 int childPos = childCount;
3176
3177 while(childPos > 0) {
3178 childPos--;
3181 item->setChild( childPos / colCount, childPos % colCount, child);
3182 }
3183}
3184
3185
3190 int row, int column, const QModelIndex &parent)
3191{
3192 Q_D(QStandardItemModel);
3193 // check if the action is supported
3194 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
3195 return false;
3196 // check if the format is supported
3198 if (!data->hasFormat(format))
3200
3201 if (row > rowCount(parent))
3202 row = rowCount(parent);
3203 if (row == -1)
3204 row = rowCount(parent);
3205 if (column == -1)
3206 column = 0;
3207
3208 // decode and insert
3211
3212
3213 //code based on QAbstractItemModel::decodeData
3214 // adapted to work with QStandardItem
3215 int top = INT_MAX;
3216 int left = INT_MAX;
3217 int bottom = 0;
3218 int right = 0;
3219 QList<int> rows, columns;
3221
3222 while (!stream.atEnd()) {
3223 int r, c;
3224 QStandardItem *item = d->createItem();
3225 stream >> r >> c;
3226 d->decodeDataRecursive(stream, item);
3227
3228 rows.append(r);
3229 columns.append(c);
3230 items.append(item);
3231 top = qMin(r, top);
3232 left = qMin(c, left);
3233 bottom = qMax(r, bottom);
3234 right = qMax(c, right);
3235 }
3236
3237 // insert the dragged items into the table, use a bit array to avoid overwriting items,
3238 // since items from different tables can have the same row and column
3239 int dragRowCount = 0;
3240 int dragColumnCount = right - left + 1;
3241
3242 // Compute the number of continuous rows upon insertion and modify the rows to match
3243 QList<int> rowsToInsert(bottom + 1);
3244 for (int i = 0; i < rows.size(); ++i)
3245 rowsToInsert[rows.at(i)] = 1;
3246 for (int i = 0; i < rowsToInsert.size(); ++i) {
3247 if (rowsToInsert.at(i) == 1){
3248 rowsToInsert[i] = dragRowCount;
3249 ++dragRowCount;
3250 }
3251 }
3252 for (int i = 0; i < rows.size(); ++i)
3253 rows[i] = top + rowsToInsert.at(rows.at(i));
3254
3255 QBitArray isWrittenTo(dragRowCount * dragColumnCount);
3256
3257 // make space in the table for the dropped data
3258 int colCount = columnCount(parent);
3259 if (colCount < dragColumnCount + column) {
3260 insertColumns(colCount, dragColumnCount + column - colCount, parent);
3261 colCount = columnCount(parent);
3262 }
3263 insertRows(row, dragRowCount, parent);
3264
3265 row = qMax(0, row);
3266 column = qMax(0, column);
3267
3268 QStandardItem *parentItem = itemFromIndex (parent);
3269 if (!parentItem)
3270 parentItem = invisibleRootItem();
3271
3273 // set the data in the table
3274 for (int j = 0; j < items.size(); ++j) {
3275 int relativeRow = rows.at(j) - top;
3276 int relativeColumn = columns.at(j) - left;
3277 int destinationRow = relativeRow + row;
3278 int destinationColumn = relativeColumn + column;
3279 int flat = (relativeRow * dragColumnCount) + relativeColumn;
3280 // if the item was already written to, or we just can't fit it in the table, create a new row
3281 if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) {
3282 destinationColumn = qBound(column, destinationColumn, colCount - 1);
3283 destinationRow = row + dragRowCount;
3284 insertRows(row + dragRowCount, 1, parent);
3285 flat = (dragRowCount * dragColumnCount) + relativeColumn;
3286 isWrittenTo.resize(++dragRowCount * dragColumnCount);
3287 }
3288 if (!isWrittenTo.testBit(flat)) {
3289 newIndexes[j] = index(destinationRow, destinationColumn, parentItem->index());
3290 isWrittenTo.setBit(flat);
3291 }
3292 }
3293
3294 for(int k = 0; k < newIndexes.size(); k++) {
3295 if (newIndexes.at(k).isValid()) {
3296 parentItem->setChild(newIndexes.at(k).row(), newIndexes.at(k).column(), items.at(k));
3297 } else {
3298 delete items.at(k);
3299 }
3300 }
3301
3302 return true;
3303}
3304
3306
3307#include "moc_qstandarditemmodel.cpp"
static const QHash< int, QByteArray > & defaultRoleNames()
static bool isVariantLessThan(const QVariant &left, const QVariant &right, Qt::CaseSensitivity cs=Qt::CaseSensitive, bool isLocaleAware=false)
void endResetModel()
Completes a model reset operation.
virtual Q_INVOKABLE QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits=1, Qt::MatchFlags flags=Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const
Returns a list of indexes for the items in the column of the start index where data stored under the ...
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted just before rows are inserted into the model.
virtual Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
Returns the data for the given role and section in the header with the specified orientation.
void columnsAboutToBeInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted just before columns are inserted into the model.
void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to)
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Handles the data supplied by a drag and drop operation that ended with the given action.
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
virtual QMimeData * mimeData(const QModelIndexList &indexes) const
Returns an object that contains serialized items of data corresponding to the list of indexes specifi...
void layoutChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
bool checkIndex(const QModelIndex &index, CheckIndexOptions options=CheckIndexOption::NoOption) const
void headerDataChanged(Qt::Orientation orientation, int first, int last)
This signal is emitted whenever a header is changed.
void beginResetModel()
Begins a model reset operation.
void rowsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been inserted into the model.
virtual QStringList mimeTypes() const
Returns the list of allowed MIME types.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
void columnsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after columns have been inserted into the model.
virtual void multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const
\inmodule QtCore
Definition qproperty.h:809
\inmodule QtCore
Definition qbitarray.h:13
bool testBit(qsizetype i) const
Returns true if the bit at index position i is 1; otherwise returns false.
Definition qbitarray.h:84
void resize(qsizetype size)
Resizes the bit array to size bits.
void setBit(qsizetype i)
Sets the bit at index position i to 1.
Definition qbitarray.h:88
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:534
\inmodule QtCore\reentrant
Definition qdatastream.h:30
bool hasSeen(const T &s)
QList< QGraphicsItem * > children
void setData(int key, const QVariant &value)
Sets this item's custom data for the key key to value.
QScopedPointer< QGraphicsItemPrivate > d_ptr
QVariant data(int key) const
Returns this item's custom data for the key key as a QVariant.
GraphicsItemFlags flags() const
Returns this item's flags.
\inmodule QtCore
Definition qhash.h:818
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:471
void push_back(parameter_type t)
Definition qlist.h:672
iterator end()
Definition qlist.h:609
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void remove(qsizetype i, qsizetype n=1)
Definition qlist.h:787
void prepend(rvalue_ref t)
Definition qlist.h:456
iterator begin()
Definition qlist.h:608
void reserve(qsizetype size)
Definition qlist.h:746
void replace(qsizetype i, parameter_type t)
Definition qlist.h:526
void resize(qsizetype size)
Definition qlist.h:392
void append(parameter_type t)
Definition qlist.h:441
Definition qmap.h:186
key_value_iterator keyValueEnd()
Definition qmap.h:608
size_type size() const
Definition qmap.h:266
key_iterator keyBegin() const
Definition qmap.h:605
key_value_iterator keyValueBegin()
Definition qmap.h:607
key_iterator keyEnd() const
Definition qmap.h:606
\inmodule QtCore
Definition qmimedata.h:16
\inmodule QtCore
constexpr int row() const noexcept
Returns the row this model index refers to.
QModelIndex parent() const
Returns the parent of the model index, or QModelIndex() if it has no parent.
constexpr int column() const noexcept
Returns the column this model index refers to.
constexpr bool isValid() const noexcept
Returns {true} if this model index is valid; otherwise returns {false}.
QObject * parent
Definition qobject.h:61
\inmodule QtCore
Definition qobject.h:90
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
T * data() const noexcept
Returns the value of the pointer referenced by this object.
Definition qset.h:18
qsizetype size() const
Definition qset.h:50
bool remove(const T &value)
Definition qset.h:63
void reserve(qsizetype size)
Definition qset.h:222
bool contains(const T &value) const
Definition qset.h:71
\inmodule QtCore
Definition qstack.h:13
T pop()
Removes the top item from the stack and returns it.
Definition qstack.h:18
void push(const T &t)
Adds element t to the top of the stack.
Definition qstack.h:17
bool operator()(const QPair< QStandardItem *, int > &l, const QPair< QStandardItem *, int > &r) const
bool operator()(const QPair< QStandardItem *, int > &l, const QPair< QStandardItem *, int > &r) const
QList< QStandardItem * > rowHeaderItems
void rowsAboutToBeRemoved(QStandardItem *parent, int start, int end)
QStandardItem * createItem() const
void columnsAboutToBeRemoved(QStandardItem *parent, int start, int end)
void columnsRemoved(QStandardItem *parent, int column, int count)
QStandardItem * itemFromIndex(const QModelIndex &index) const
void columnsInserted(QStandardItem *parent, int column, int count)
void columnsAboutToBeInserted(QStandardItem *parent, int start, int end)
void itemChanged(QStandardItem *item, const QList< int > &roles=QList< int >())
void decodeDataRecursive(QDataStream &stream, QStandardItem *item)
QHash< int, QByteArray > roleNames
void rowsAboutToBeInserted(QStandardItem *parent, int start, int end)
void _q_emitItemChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
void rowsRemoved(QStandardItem *parent, int row, int count)
QScopedPointer< QStandardItem > root
QList< QStandardItem * > columnHeaderItems
void rowsInserted(QStandardItem *parent, int row, int count)
The QStandardItemModel class provides a generic model for storing custom data.
bool removeColumns(int column, int count, const QModelIndex &parent=QModelIndex()) override
\reimp
QList< QStandardItem * > takeRow(int row)
~QStandardItemModel()
Destructs the model.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
\reimp
bool clearItemData(const QModelIndex &index) override
\reimp
void clear()
Removes all items (including header items) from the model and sets the number of rows and columns to ...
QList< QStandardItem * > takeColumn(int column)
void multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const override
\reimp
void insertRow(int row, const QList< QStandardItem * > &items)
int columnCount(const QModelIndex &parent=QModelIndex()) const override
\reimp
QStringList mimeTypes() const override
\reimp
QMap< int, QVariant > itemData(const QModelIndex &index) const override
\reimp
QStandardItem * takeVerticalHeaderItem(int row)
bool hasChildren(const QModelIndex &parent=QModelIndex()) const override
\reimp
void setHorizontalHeaderLabels(const QStringList &labels)
void itemChanged(QStandardItem *item)
void insertColumn(int column, const QList< QStandardItem * > &items)
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
QMimeData * mimeData(const QModelIndexList &indexes) const override
\reimp
QBindable< int > bindableSortRole()
const QStandardItem * itemPrototype() const
QStandardItem * item(int row, int column=0) const
int sortRole
the item role that is used to query the model's data when sorting items
bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
\reimp
QList< QStandardItem * > findItems(const QString &text, Qt::MatchFlags flags=Qt::MatchExactly, int column=0) const
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
\reimp
void appendRow(const QList< QStandardItem * > &items)
bool setItemData(const QModelIndex &index, const QMap< int, QVariant > &roles) override
\reimp
void setItemRoleNames(const QHash< int, QByteArray > &roleNames)
Sets the item role names to roleNames.
void setItem(int row, int column, QStandardItem *item)
void sort(int column, Qt::SortOrder order=Qt::AscendingOrder) override
\reimp
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
\reimp
QStandardItem * takeHorizontalHeaderItem(int column)
QHash< int, QByteArray > roleNames() const override
reimp
bool insertColumns(int column, int count, const QModelIndex &parent=QModelIndex()) override
\reimp
Qt::ItemFlags flags(const QModelIndex &index) const override
\reimp
QStandardItemModel(QObject *parent=nullptr)
Constructs a new item model with the given parent.
QModelIndex indexFromItem(const QStandardItem *item) const
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
\reimp
int rowCount(const QModelIndex &parent=QModelIndex()) const override
\reimp
QStandardItem * verticalHeaderItem(int row) const
QStandardItem * takeItem(int row, int column=0)
void setVerticalHeaderItem(int row, QStandardItem *item)
void setColumnCount(int columns)
Qt::DropActions supportedDropActions() const override
\reimp
void appendColumn(const QList< QStandardItem * > &items)
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
\reimp
QStandardItem * invisibleRootItem() const
QStandardItem * itemFromIndex(const QModelIndex &index) const
void setItemPrototype(const QStandardItem *item)
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role=Qt::EditRole) override
\reimp
void setHorizontalHeaderItem(int column, QStandardItem *item)
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
\reimp
QStandardItem * horizontalHeaderItem(int column) const
void setVerticalHeaderLabels(const QStringList &labels)
void setModel(QStandardItemModel *mod)
bool insertColumns(int column, int count, const QList< QStandardItem * > &items)
QList< QStandardItemData > values
QPair< int, int > position() const
void setItemData(const QMap< int, QVariant > &roles)
int childIndex(int row, int column) const
void setChild(int row, int column, QStandardItem *item, bool emitChanged=false)
QMap< int, QVariant > itemData() const
void childDeleted(QStandardItem *child)
void setParentAndModel(QStandardItem *par, QStandardItemModel *mod)
bool insertRows(int row, int count, const QList< QStandardItem * > &items)
QStandardItemModel * model
void sortChildren(int column, Qt::SortOrder order)
QList< QStandardItem * > children
void changeFlags(bool enable, Qt::ItemFlags f)
The QStandardItem class provides an item for use with the QStandardItemModel class.
QStandardItem * child(int row, int column=0) const
Returns the child item at (row, column) if one has been set; otherwise returns \nullptr.
Qt::ItemFlags flags() const
Returns the item flags for the item.
void setText(const QString &text)
Sets the item's text to the text specified.
void insertColumns(int column, int count)
Inserts count columns of child items at column column.
void insertRows(int row, const QList< QStandardItem * > &items)
Inserts items at row.
void setEnabled(bool enabled)
Sets whether the item is enabled.
QDataStream & operator<<(QDataStream &out, const QStandardItem &item)
virtual void setData(const QVariant &value, int role=Qt::UserRole+1)
Sets the item's data for the given role to the specified value.
bool isCheckable() const
Returns whether the item is user-checkable.
int rowCount() const
Returns the number of child item rows that the item has.
void setUserTristate(bool tristate)
Sets whether the item is tristate and controlled by the user.
void setIcon(const QIcon &icon)
Sets the item's icon to the icon specified.
virtual QVariant data(int role=Qt::UserRole+1) const
Returns the item's data for the given role, or an invalid QVariant if there is no data for the role.
void sortChildren(int column, Qt::SortOrder order=Qt::AscendingOrder)
Sorts the children of the item using the given order, by the values in the given column.
int column() const
Returns the column where the item is located in its parent's child table, or -1 if the item has no pa...
QIcon icon() const
Returns the item's icon.
void setColumnCount(int columns)
Sets the number of child item columns to columns.
void removeColumns(int column, int count)
Removes count columns at column column.
QStandardItem * parent() const
Returns the item's parent item, or \nullptr if the item has no parent.
void setRowCount(int rows)
Sets the number of child item rows to rows.
virtual void multiData(QModelRoleDataSpan roleDataSpan) const
void setEditable(bool editable)
Sets whether the item is editable.
void insertColumn(int column, const QList< QStandardItem * > &items)
Inserts a column at column containing items.
void removeColumn(int column)
Removes the given column.
virtual bool operator<(const QStandardItem &other) const
Returns true if this item is less than other; otherwise returns false.
void setChild(int row, int column, QStandardItem *item)
Sets the child item at (row, column) to item.
QStandardItem()
Constructs an item.
QList< QStandardItem * > takeRow(int row)
Removes row without deleting the row items, and returns a list of pointers to the removed items.
QString text() const
Returns the item's text.
void setCheckable(bool checkable)
Sets whether the item is user-checkable.
virtual void read(QDataStream &in)
Reads the item from stream in.
QDataStream & operator>>(QDataStream &in, QStandardItem &item)
QStandardItem & operator=(const QStandardItem &other)
Assigns other's data and flags to this item.
int row() const
Returns the row where the item is located in its parent's child table, or -1 if the item has no paren...
int columnCount() const
Returns the number of child item columns that the item has.
QStandardItem * takeChild(int row, int column=0)
Removes the child item at (row, column) without deleting it, and returns a pointer to the item.
void removeRows(int row, int count)
Removes count rows at row row.
QList< QStandardItem * > takeColumn(int column)
Removes column without deleting the column items, and returns a list of pointers to the removed items...
virtual ~QStandardItem()
Destructs the item.
void setFlags(Qt::ItemFlags flags)
Sets the item flags for the item to flags.
void appendColumn(const QList< QStandardItem * > &items)
Appends a column containing items.
virtual void write(QDataStream &out) const
Writes the item to stream out.
void removeRow(int row)
Removes the given row.
void setSelectable(bool selectable)
Sets whether the item is selectable.
void appendRow(const QList< QStandardItem * > &items)
Appends a row containing items.
virtual int type() const
Returns the type of this item.
QModelIndex index() const
Returns the QModelIndex associated with this item.
virtual QStandardItem * clone() const
Returns a copy of this item.
QStandardItemModel * model() const
Returns the QStandardItemModel that this item belongs to.
bool hasChildren() const
Returns true if this item has any children; otherwise returns false.
void setAutoTristate(bool tristate)
Determines that the item is tristate and controlled by QTreeWidget if tristate is true.
void insertRow(int row, const QList< QStandardItem * > &items)
Inserts a row at row containing items.
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qvariant.h:64
QString text
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
@ Unchecked
Orientation
Definition qnamespace.h:97
@ Horizontal
Definition qnamespace.h:98
@ Vertical
Definition qnamespace.h:99
@ UserRole
@ EditRole
@ CheckStateRole
@ DisplayRole
SortOrder
Definition qnamespace.h:120
@ AscendingOrder
Definition qnamespace.h:121
DropAction
@ CopyAction
@ MoveAction
@ ItemIsEditable
@ ItemIsDragEnabled
@ ItemIsUserTristate
@ ItemIsUserCheckable
@ ItemIsSelectable
@ ItemIsEnabled
@ ItemIsDropEnabled
@ ItemIsAutoTristate
std::pair< T1, T2 > QPair
EGLStreamKHR stream
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
static bool contains(const QJsonArray &haystack, unsigned needle)
Definition qopengl.cpp:116
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
GLuint index
[2]
GLboolean r
[2]
GLuint GLuint end
GLdouble GLdouble GLdouble GLdouble top
GLenum GLenum GLsizei count
GLdouble GLdouble right
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
GLint left
GLint GLint bottom
GLbitfield flags
GLboolean enable
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLfloat n
GLint GLsizei GLsizei GLenum format
GLenum GLenum GLsizei void GLsizei void * column
const GLubyte * c
GLint limit
GLuint in
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLenum GLenum GLsizei void * row
GLuint64EXT * result
[6]
GLfixed GLfixed GLint GLint order
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QString qStandardItemModelDataListMimeType()
#define QStringLiteral(str)
#define emit
int qint32
Definition qtypes.h:44
QTextStream out(stdout)
[7]
std::array< QModelRoleData, 3 > roleData
[13]
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
QList< QTreeWidgetItem * > items
QLayoutItem * child
[0]
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:955
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent
virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt ITextRangeProvider *range, __RPC__out BOOL *pRetVal)=0