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

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