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 QQMLDATAMODEL_P_H
5#define QQMLDATAMODEL_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 purely as an
12// implementation detail. 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 <private/qtqmlmodelsglobal_p.h>
19#include <private/qqmllistcompositor_p.h>
20#include <private/qqmlobjectmodel_p.h>
21#include <private/qqmlincubator_p.h>
22
23#include <QtCore/qabstractitemmodel.h>
24#include <QtCore/qstringlist.h>
25
26QT_REQUIRE_CONFIG(qml_delegate_model);
27
28QT_BEGIN_NAMESPACE
29
30class QQmlChangeSet;
31class QQuickPackage;
32class QQmlDelegateModelGroup;
33class QQmlDelegateModelAttached;
34class QQmlDelegateModelPrivate;
35
36
37class Q_QMLMODELS_EXPORT QQmlDelegateModel : public QQmlInstanceModel, public QQmlParserStatus
38{
39 Q_OBJECT
40 Q_DECLARE_PRIVATE(QQmlDelegateModel)
41
42 Q_PROPERTY(QVariant model READ model WRITE setModel)
43 Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
44 Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
45 Q_PROPERTY(QQmlDelegateModelGroup *items READ items CONSTANT) //TODO : worth renaming?
46 Q_PROPERTY(QQmlDelegateModelGroup *persistedItems READ persistedItems CONSTANT)
47 Q_PROPERTY(QQmlListProperty<QQmlDelegateModelGroup> groups READ groups CONSTANT)
48 Q_PROPERTY(QObject *parts READ parts CONSTANT)
49 Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
50 Q_PROPERTY(DelegateModelAccess delegateModelAccess READ delegateModelAccess
51 WRITE setDelegateModelAccess NOTIFY delegateModelAccessChanged REVISION(6, 10) FINAL)
52 Q_CLASSINFO("DefaultProperty", "delegate")
53 QML_NAMED_ELEMENT(DelegateModel)
54 QML_ADDED_IN_VERSION(2, 1)
55 QML_ATTACHED(QQmlDelegateModelAttached)
56 Q_INTERFACES(QQmlParserStatus)
57
58public:
59 enum DelegateModelAccess : quint8 {
60 Qt5ReadWrite,
61 ReadOnly,
62 ReadWrite
63 };
64 Q_ENUM(DelegateModelAccess)
65
66 QQmlDelegateModel();
67 QQmlDelegateModel(QQmlContext *, QObject *parent=nullptr);
68 ~QQmlDelegateModel();
69
70 void classBegin() override;
71 void componentComplete() override;
72
73 QVariant model() const;
74 void setModel(const QVariant &);
75
76 QQmlComponent *delegate() const;
77 void setDelegate(QQmlComponent *);
78
79 QVariant rootIndex() const;
80 void setRootIndex(const QVariant &root);
81
82 DelegateModelAccess delegateModelAccess() const;
83 void setDelegateModelAccess(DelegateModelAccess delegateModelAccess);
84
85 Q_INVOKABLE QVariant modelIndex(int idx) const;
86 Q_INVOKABLE QVariant parentModelIndex() const;
87
88 int count() const override;
89 bool isValid() const override { return delegate() != nullptr; }
90 QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
91 ReleaseFlags release(QObject *object, ReusableFlag reusableFlag = NotReusable) override;
92 void cancel(int index) override;
93 QVariant variantValue(int index, const QString &role) override;
94 void setWatchedRoles(const QList<QByteArray> &roles) override;
95 QQmlIncubator::Status incubationStatus(int index) override;
96
97 void drainReusableItemsPool(int maxPoolTime) override;
98 int poolSize() override;
99
100 int indexOf(QObject *object, QObject *objectContext) const override;
101
102 QString filterGroup() const;
103 void setFilterGroup(const QString &group);
104 void resetFilterGroup();
105
106 QQmlDelegateModelGroup *items();
107 QQmlDelegateModelGroup *persistedItems();
108 QQmlListProperty<QQmlDelegateModelGroup> groups();
109 QObject *parts();
110
111 const QAbstractItemModel *abstractItemModel() const override;
112
113 bool event(QEvent *) override;
114
115 static QQmlDelegateModelAttached *qmlAttachedProperties(QObject *obj);
116
117 template<typename View, typename ViewPrivate>
118 static QQmlDelegateModel *createForView(View *q, ViewPrivate *d)
119 {
120 Q_ASSERT(d->model.isNull());
121 QQmlDelegateModel *delegateModel = new QQmlDelegateModel(qmlContext(q), q);
122 d->model = delegateModel;
123 d->ownModel = true;
124 if (d->componentComplete)
125 delegateModel->componentComplete();
126 return delegateModel;
127 }
128
129 template<typename View, typename ViewPrivate>
130 static void applyDelegateModelAccessChangeOnView(View *q, ViewPrivate *d)
131 {
132 if (d->explicitDelegateModelAccess) {
133 qmlWarning(q) << "Explicitly set delegateModelAccess is externally overridden";
134 d->explicitDelegateModelAccess = false;
135 }
136
137 Q_EMIT q->delegateModelAccessChanged();
138 }
139
140 template<typename View, typename ViewPrivate>
141 static void applyDelegateChangeOnView(View *q, ViewPrivate *d)
142 {
143 if (d->explicitDelegate) {
144 qmlWarning(q) << "Explicitly set delegate is externally overridden";
145 d->explicitDelegate = false;
146 }
147
148 Q_EMIT q->delegateChanged();
149 }
150
151Q_SIGNALS:
152 void filterGroupChanged();
153 void defaultGroupsChanged();
154 void rootIndexChanged();
155 void delegateChanged();
156 Q_REVISION(6, 10) void delegateModelAccessChanged();
157
158private Q_SLOTS:
159 void _q_itemsChanged(int index, int count, const QVector<int> &roles);
160 void _q_itemsInserted(int index, int count);
161 void _q_itemsRemoved(int index, int count);
162 void _q_itemsMoved(int from, int to, int count);
163 void _q_modelAboutToBeReset();
164 void _q_rowsInserted(const QModelIndex &,int,int);
165 void _q_columnsInserted(const QModelIndex &, int, int);
166 void _q_columnsRemoved(const QModelIndex &, int, int);
167 void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
168 void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
169 void _q_rowsRemoved(const QModelIndex &,int,int);
170 void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
171 void _q_dataChanged(const QModelIndex&,const QModelIndex&,const QVector<int> &);
172 void _q_layoutChanged(const QList<QPersistentModelIndex>&, QAbstractItemModel::LayoutChangeHint);
173
174private:
175 void handleModelReset();
176 bool isDescendantOf(const QPersistentModelIndex &desc, const QList<QPersistentModelIndex> &parents) const;
177
178 Q_DISABLE_COPY(QQmlDelegateModel)
179};
180
181class QQmlDelegateModelGroupPrivate;
182class Q_QMLMODELS_EXPORT QQmlDelegateModelGroup : public QObject
183{
184 Q_OBJECT
185 Q_PROPERTY(int count READ count NOTIFY countChanged)
186 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
187 Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged)
188 QML_NAMED_ELEMENT(DelegateModelGroup)
189 QML_ADDED_IN_VERSION(2, 1)
190public:
191 QQmlDelegateModelGroup(QObject *parent = nullptr);
192 QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr);
193 ~QQmlDelegateModelGroup();
194
195 QString name() const;
196 void setName(const QString &name);
197
198 int count() const;
199
200 bool defaultInclude() const;
201 void setDefaultInclude(bool include);
202
203 Q_INVOKABLE QJSValue get(int index);
204
205public Q_SLOTS:
206 void insert(QQmlV4FunctionPtr);
207 void create(QQmlV4FunctionPtr);
208 void resolve(QQmlV4FunctionPtr);
209 void remove(QQmlV4FunctionPtr);
210 void addGroups(QQmlV4FunctionPtr);
211 void removeGroups(QQmlV4FunctionPtr);
212 void setGroups(QQmlV4FunctionPtr);
213 void move(QQmlV4FunctionPtr);
214
215Q_SIGNALS:
216 void countChanged();
217 void nameChanged();
218 void defaultIncludeChanged();
219 void changed(const QJSValue &removed, const QJSValue &inserted);
220private:
221 Q_DECLARE_PRIVATE(QQmlDelegateModelGroup)
222};
223
224class QQmlDelegateModelItem;
225class QQmlDelegateModelAttachedMetaObject;
226class QQmlDelegateModelAttached : public QObject
227{
228 Q_OBJECT
229 Q_PROPERTY(QQmlDelegateModel *model READ model CONSTANT FINAL)
230 Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged FINAL)
231 Q_PROPERTY(bool isUnresolved READ isUnresolved NOTIFY unresolvedChanged FINAL)
232 Q_PROPERTY(bool inPersistedItems READ inPersistedItems WRITE setInPersistedItems NOTIFY groupsChanged FINAL)
233 Q_PROPERTY(bool inItems READ inItems WRITE setInItems NOTIFY groupsChanged FINAL)
234 Q_PROPERTY(int persistedItemsIndex READ persistedItemsIndex NOTIFY groupsChanged FINAL)
235 Q_PROPERTY(int itemsIndex READ itemsIndex NOTIFY groupsChanged FINAL)
236
237public:
238 QQmlDelegateModelAttached(QObject *parent);
239 QQmlDelegateModelAttached(QQmlDelegateModelItem *cacheItem, QObject *parent);
240 ~QQmlDelegateModelAttached();
241
242 void resetCurrentIndex();
243 void setCacheItem(QQmlDelegateModelItem *item);
244
245 void setInPersistedItems(bool inPersisted);
246 bool inPersistedItems() const;
247 int persistedItemsIndex() const;
248
249 void setInItems(bool inItems);
250 bool inItems() const;
251 int itemsIndex() const;
252
253 QQmlDelegateModel *model() const;
254
255 QStringList groups() const;
256 void setGroups(const QStringList &groups);
257
258 bool isUnresolved() const;
259
260 void emitChanges();
261
262 void emitUnresolvedChanged() { Q_EMIT unresolvedChanged(); }
263
264Q_SIGNALS:
265 void groupsChanged();
266 void unresolvedChanged();
267
268private:
269 void setInGroup(QQmlListCompositor::Group group, bool inGroup);
270
271public:
272 QQmlDelegateModelItem *m_cacheItem;
273 int m_previousGroups;
274 int m_currentIndex[QQmlListCompositor::MaximumGroupCount];
275 int m_previousIndex[QQmlListCompositor::MaximumGroupCount];
276
277 friend class QQmlDelegateModelAttachedMetaObject;
278};
279
280struct QQmlDelegateModelPointer
281{
282 QQmlDelegateModelPointer() = default;
283 QQmlDelegateModelPointer(const QQmlDelegateModelPointer &) = default;
284 QQmlDelegateModelPointer(QQmlDelegateModelPointer &&) = default;
285 QQmlDelegateModelPointer &operator=(const QQmlDelegateModelPointer &) = default;
286 QQmlDelegateModelPointer &operator=(QQmlDelegateModelPointer &&) = default;
287
288 QQmlDelegateModelPointer(QQmlInstanceModel *model)
289 : model(model)
290 , concrete(model ? Unknown : InstanceModel)
291 {}
292
293 QQmlDelegateModelPointer(QQmlDelegateModel *model)
294 : model(model)
295 , concrete(DelegateModel)
296 {}
297
298 QQmlDelegateModelPointer &operator=(QQmlInstanceModel *instanceModel)
299 {
300 model = instanceModel;
301 concrete = model ? Unknown : InstanceModel;
302 return *this;
303 }
304
305 QQmlDelegateModelPointer &operator=(QQmlDelegateModel *delegateModel)
306 {
307 model = delegateModel;
308 concrete = DelegateModel;
309 return *this;
310 }
311
312 QQmlDelegateModel *delegateModel()
313 {
314 switch (concrete) {
315 case DelegateModel:
316 return static_cast<QQmlDelegateModel *>(model);
317 case InstanceModel:
318 return nullptr;
319 case Unknown:
320 break;
321 }
322
323 QQmlDelegateModel *result = qobject_cast<QQmlDelegateModel *>(object: model);
324 concrete = result ? DelegateModel : InstanceModel;
325 return result;
326 }
327
328 QQmlInstanceModel *instanceModel() { return model; }
329
330 operator bool() const { return model != nullptr; }
331
332private:
333 enum ConcreteType {
334 Unknown,
335 InstanceModel,
336 DelegateModel
337 };
338
339 QQmlInstanceModel *model = nullptr;
340 ConcreteType concrete = InstanceModel;
341};
342
343QT_END_NAMESPACE
344
345#endif // QQMLDATAMODEL_P_H
346

source code of qtdeclarative/src/qmlmodels/qqmldelegatemodel_p.h