1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QSTANDARDITEMMODEL_P_H
5#define QSTANDARDITEMMODEL_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of other Qt classes. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/qstandarditemmodel.h>
19
20#include <QtGui/private/qtguiglobal_p.h>
21#include "private/qabstractitemmodel_p.h"
22
23#include <QtCore/qlist.h>
24#include <QtCore/qstack.h>
25#include <QtCore/qvariant.h>
26#include <QtCore/qdebug.h>
27
28QT_REQUIRE_CONFIG(standarditemmodel);
29
30QT_BEGIN_NAMESPACE
31
32class QStandardItemData
33{
34public:
35 inline QStandardItemData() : role(-1) {}
36 inline QStandardItemData(int r, const QVariant &v) :
37 role(r == Qt::EditRole ? Qt::DisplayRole : r), value(v) {}
38 inline QStandardItemData(const std::pair<const int&, const QVariant&> &p) :
39 role(p.first == Qt::EditRole ? Qt::DisplayRole : p.first), value(p.second) {}
40 int role;
41 QVariant value;
42 inline bool operator==(const QStandardItemData &other) const { return role == other.role && value == other.value; }
43};
44Q_DECLARE_TYPEINFO(QStandardItemData, Q_RELOCATABLE_TYPE);
45
46#ifndef QT_NO_DATASTREAM
47
48inline QDataStream &operator>>(QDataStream &in, QStandardItemData &data)
49{
50 in >> data.role;
51 in >> data.value;
52 return in;
53}
54
55inline QDataStream &operator<<(QDataStream &out, const QStandardItemData &data)
56{
57 out << data.role;
58 out << data.value;
59 return out;
60}
61
62inline QDebug &operator<<(QDebug &debug, const QStandardItemData &data)
63{
64 QDebugStateSaver saver(debug);
65 debug.nospace() << data.role
66 << " "
67 << data.value;
68 return debug.space();
69}
70
71#endif // QT_NO_DATASTREAM
72
73class QStandardItemPrivate
74{
75 Q_DECLARE_PUBLIC(QStandardItem)
76public:
77 inline QStandardItemPrivate()
78 : model(nullptr),
79 parent(nullptr),
80 rows(0),
81 columns(0),
82 q_ptr(nullptr),
83 lastKnownIndex(-1)
84 { }
85
86 inline int childIndex(int row, int column) const {
87 if ((row < 0) || (column < 0)
88 || (row >= rowCount()) || (column >= columnCount())) {
89 return -1;
90 }
91 return (row * columnCount()) + column;
92 }
93 inline int childIndex(const QStandardItem *child) const {
94 const int lastChild = children.size() - 1;
95 int &childsLastIndexInParent = child->d_func()->lastKnownIndex;
96 if (childsLastIndexInParent != -1 && childsLastIndexInParent <= lastChild) {
97 if (children.at(i: childsLastIndexInParent) == child)
98 return childsLastIndexInParent;
99 } else {
100 childsLastIndexInParent = lastChild / 2;
101 }
102
103 // assuming the item is in the vicinity of the previous index, iterate forwards and
104 // backwards through the children
105 int backwardIter = childsLastIndexInParent - 1;
106 int forwardIter = childsLastIndexInParent;
107 for (;;) {
108 if (forwardIter <= lastChild) {
109 if (children.at(i: forwardIter) == child) {
110 childsLastIndexInParent = forwardIter;
111 break;
112 }
113 ++forwardIter;
114 } else if (backwardIter < 0) {
115 childsLastIndexInParent = -1;
116 break;
117 }
118 if (backwardIter >= 0) {
119 if (children.at(i: backwardIter) == child) {
120 childsLastIndexInParent = backwardIter;
121 break;
122 }
123 --backwardIter;
124 }
125 }
126 return childsLastIndexInParent;
127 }
128 std::pair<int, int> position() const;
129 void setChild(int row, int column, QStandardItem *item,
130 bool emitChanged = false);
131 inline int rowCount() const {
132 return rows;
133 }
134 inline int columnCount() const {
135 return columns;
136 }
137 void childDeleted(QStandardItem *child);
138
139 void setModel(QStandardItemModel *mod);
140
141 inline void setParentAndModel(
142 QStandardItem *par,
143 QStandardItemModel *mod) {
144 setModel(mod);
145 parent = par;
146 }
147
148 void changeFlags(bool enable, Qt::ItemFlags f);
149 void setItemData(const QMap<int, QVariant> &roles);
150 QMap<int, QVariant> itemData() const;
151
152 bool insertRows(int row, int count, const QList<QStandardItem*> &items);
153 bool insertRows(int row, const QList<QStandardItem*> &items);
154 bool insertColumns(int column, int count, const QList<QStandardItem*> &items);
155
156 void sortChildren(int column, Qt::SortOrder order);
157
158 QStandardItemModel *model;
159 QStandardItem *parent;
160 QList<QStandardItemData> values;
161 QList<QStandardItem *> children;
162 int rows;
163 int columns;
164
165 QStandardItem *q_ptr;
166
167 mutable int lastKnownIndex; // this is a cached value
168};
169
170class QStandardItemModelPrivate : public QAbstractItemModelPrivate
171{
172 Q_DECLARE_PUBLIC(QStandardItemModel)
173
174public:
175 QStandardItemModelPrivate();
176 ~QStandardItemModelPrivate();
177
178 void init();
179
180 inline QStandardItem *createItem() const {
181 return itemPrototype ? itemPrototype->clone() : new QStandardItem;
182 }
183
184 inline QStandardItem *itemFromIndex(const QModelIndex &index) const {
185 Q_Q(const QStandardItemModel);
186 if (!index.isValid())
187 return root.data();
188 if (index.model() != q)
189 return nullptr;
190 QStandardItem *parent = static_cast<QStandardItem*>(index.internalPointer());
191 if (parent == nullptr)
192 return nullptr;
193 return parent->child(row: index.row(), column: index.column());
194 }
195
196 void sort(QStandardItem *parent, int column, Qt::SortOrder order);
197 void itemChanged(QStandardItem *item, const QList<int> &roles = QList<int>());
198 void rowsAboutToBeInserted(QStandardItem *parent, int start, int end);
199 void columnsAboutToBeInserted(QStandardItem *parent, int start, int end);
200 void rowsAboutToBeRemoved(QStandardItem *parent, int start, int end);
201 void columnsAboutToBeRemoved(QStandardItem *parent, int start, int end);
202 void rowsInserted(QStandardItem *parent, int row, int count);
203 void columnsInserted(QStandardItem *parent, int column, int count);
204 void rowsRemoved(QStandardItem *parent, int row, int count);
205 void columnsRemoved(QStandardItem *parent, int column, int count);
206
207 void _q_emitItemChanged(const QModelIndex &topLeft,
208 const QModelIndex &bottomRight);
209
210 void decodeDataRecursive(QDataStream &stream, QStandardItem *item);
211
212 QList<QStandardItem *> columnHeaderItems;
213 QList<QStandardItem *> rowHeaderItems;
214 QHash<int, QByteArray> roleNames;
215 QScopedPointer<QStandardItem> root;
216 const QStandardItem *itemPrototype;
217 Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QStandardItemModelPrivate, int, sortRole, Qt::DisplayRole)
218};
219
220QT_END_NAMESPACE
221
222#endif // QSTANDARDITEMMODEL_P_H
223

source code of qtbase/src/gui/itemmodels/qstandarditemmodel_p.h