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