Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmllistmodel_p_p.h
Go to the documentation of this file.
1// Copyright (C) 2020 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// Qt-Security score:significant
4
5#ifndef QQMLLISTMODEL_P_P_H
6#define QQMLLISTMODEL_P_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
20#include <private/qtqmlmodelsglobal_p.h>
21#include <private/qqmlengine_p.h>
22#include <private/qqmlopenmetaobject_p.h>
23#include <private/qv4qobjectwrapper_p.h>
24#include <qqml.h>
25
27
28QT_BEGIN_NAMESPACE
29
30
31class DynamicRoleModelNode;
32
34{
35public:
38
40
41protected:
42 void propertyWrite(int index) override;
43 void propertyWritten(int index) override;
44
45private:
46 DynamicRoleModelNode *m_owner;
47};
48
50{
52public:
54
55 static DynamicRoleModelNode *create(const QVariantMap &obj, QQmlListModel *owner);
56
57 void updateValues(const QVariantMap &object, QVector<int> &roles);
58
59 QVariant getValue(const QString &name) const
60 {
61 return m_meta->value(name.toUtf8());
62 }
63
64 bool setValue(const QByteArray &name, const QVariant &val)
65 {
66 return m_meta->setValue(name, val);
67 }
68
69 void setNodeUpdatesEnabled(bool enable)
70 {
71 m_meta->m_enabled = enable;
72 }
73
74 int getUid() const
75 {
76 return m_uid;
77 }
78
79 static QVector<int> sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target);
80
81private:
82 QQmlListModel *m_owner;
83 int m_uid;
85
87};
88
90{
91public:
92 ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex);
94
95#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
97#else
98 QMetaObject *toDynamicMetaObject(QObject *object) override;
99#endif
100
101 static ModelNodeMetaObject *get(QObject *obj);
102
106
107 void updateValues();
108 void updateValues(const QVector<int> &roles);
109
110 bool initialized() const { return m_initialized; }
111
112protected:
113 void propertyWritten(int index) override;
114
115private:
117
118 void emitDirectNotifies(const int *changedRoles, int roleCount);
119
120 void initialize();
121 mutable bool m_initialized;
122};
123
124namespace QV4 {
125
126namespace Heap {
127
129 void init(QObject *object, QQmlListModel *model)
130 {
131 QObjectWrapper::init(object);
132 m_model = model;
133 }
134
135 void destroy()
136 {
137 m_model.destroy();
138 QObjectWrapper::destroy();
139 }
140
141 int elementIndex() const {
142 if (const QObject *o = object()) {
143 const QObjectPrivate *op = QObjectPrivate::get(o);
144 return static_cast<ModelNodeMetaObject *>(op->metaObject)->m_elementIndex;
145 }
146 return -1;
147 }
148
150};
151
152}
153
155{
156 V4_OBJECT2(ModelObject, QObjectWrapper)
158
159protected:
160 static bool virtualPut(Managed *m, PropertyKey id, const Value& value, Value *receiver);
161 static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
162 static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup);
163 static ReturnedValue lookupGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
164 static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
165};
166
167} // namespace QV4
168
170{
171public:
172 ListLayout() : currentBlock(0), currentBlockOffset(0) {}
173 ListLayout(const ListLayout *other);
174 ~ListLayout();
175
176 class Role
177 {
178 public:
179
181 explicit Role(const Role *other);
182 ~Role();
183
184 // This enum must be kept in sync with the roleTypeNames variable in qqmllistmodel.cpp
201
206 int index;
208 };
209
210 const Role *getRoleOrCreate(const QString &key, const QVariant &data);
211 const Role &getRoleOrCreate(QV4::String *key, Role::DataType type);
212 const Role &getRoleOrCreate(const QString &key, Role::DataType type);
213
214 const Role &getExistingRole(int index) const { return *roles.at(index); }
215 const Role *getExistingRole(const QString &key) const;
216 const Role *getExistingRole(QV4::String *key) const;
217
218 int roleCount() const { return roles.size(); }
219
220 static void sync(ListLayout *src, ListLayout *target);
221
222private:
223 const Role &createRole(const QString &key, Role::DataType type);
224
225 int currentBlock;
226 int currentBlockOffset;
227 QVector<Role *> roles;
228 QStringHash<Role *> roleHash;
229};
230
232{
234 bool isSet() const { return binding || arrayData; }
235 bool isTranslation() const { return binding && !arrayData; }
236 void setString(const QString &s);
237 void setTranslation(const QV4::CompiledData::Binding *binding);
238 QString toString(const QQmlListModel *owner) const;
239 QString asString() const;
240private:
241 void clear();
242
243 union {
244 char16_t *stringData = nullptr;
246 };
247
248 QTypedArrayData<char16_t> *arrayData = nullptr;
249 uint stringSize = 0;
250};
251
252/*!
253\internal
254*/
256{
257public:
259 enum { BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelNodeMetaObject *) };
260
261 ListElement();
262 ListElement(int existingUid);
263 ~ListElement();
264
265 static QVector<int> sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout);
266
267private:
268
269 void destroy(ListLayout *layout);
270
271 int setVariantProperty(const ListLayout::Role &role, const QVariant &d);
272
273 int setJsProperty(const ListLayout::Role &role, const QV4::Value &d, QV4::ExecutionEngine *eng);
274
275 int setStringProperty(const ListLayout::Role &role, const QString &s);
276 int setDoubleProperty(const ListLayout::Role &role, double n);
277 int setBoolProperty(const ListLayout::Role &role, bool b);
278 int setListProperty(const ListLayout::Role &role, ListModel *m);
279 int setQObjectProperty(const ListLayout::Role &role, QV4::QObjectWrapper *o);
280 int setVariantMapProperty(const ListLayout::Role &role, QV4::Object *o);
281 int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m);
282 int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt);
283 int setUrlProperty(const ListLayout::Role &role, const QUrl &url);
284 int setFunctionProperty(const ListLayout::Role &role, const QJSValue &f);
285 int setTranslationProperty(const ListLayout::Role &role, const QV4::CompiledData::Binding *b);
286
287 void setStringPropertyFast(const ListLayout::Role &role, const QString &s);
288 void setDoublePropertyFast(const ListLayout::Role &role, double n);
289 void setBoolPropertyFast(const ListLayout::Role &role, bool b);
290 void setQObjectPropertyFast(const ListLayout::Role &role, QV4::QObjectWrapper *o);
291 void setListPropertyFast(const ListLayout::Role &role, ListModel *m);
292 void setVariantMapFast(const ListLayout::Role &role, QV4::Object *o);
293 void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt);
294 void setUrlPropertyFast(const ListLayout::Role &role, const QUrl &url);
295 void setFunctionPropertyFast(const ListLayout::Role &role, const QJSValue &f);
296
297 void clearProperty(const ListLayout::Role &role);
298
299 QVariant getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV4::ExecutionEngine *eng);
300 ListModel *getListProperty(const ListLayout::Role &role);
301 StringOrTranslation *getStringProperty(const ListLayout::Role &role);
302 QV4::QObjectWrapper *getQObjectProperty(const ListLayout::Role &role);
303 QV4::PersistentValue *getGuardProperty(const ListLayout::Role &role);
304 QVariantMap *getVariantMapProperty(const ListLayout::Role &role);
305 QDateTime *getDateTimeProperty(const ListLayout::Role &role);
306 QUrl *getUrlProperty(const ListLayout::Role &role);
307 QJSValue *getFunctionProperty(const ListLayout::Role &role);
308
309 inline char *getPropertyMemory(const ListLayout::Role &role);
310
311 int getUid() const { return uid; }
312
313 ModelNodeMetaObject *objectCache();
314
315 char data[BLOCK_SIZE];
316 ListElement *next;
317
318 int uid;
319 QObject *m_objectCache;
320
321 friend class ListModel;
322};
323
324/*!
325\internal
326*/
328{
329public:
330
331 ListModel(ListLayout *layout, QQmlListModel *modelCache);
332
333 void destroy();
334
335 int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data);
336 int setExistingProperty(int uid, const QString &key, const QV4::Value &data, QV4::ExecutionEngine *eng);
337
338 QVariant getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng);
339 ListModel *getListProperty(int elementIndex, const ListLayout::Role &role);
340
341 void updateTranslations();
342
343 int roleCount() const
344 {
345 return m_layout->roleCount();
346 }
347
348 const ListLayout::Role &getExistingRole(int index) const
349 {
350 return m_layout->getExistingRole(index);
351 }
352
353 const ListLayout::Role *getExistingRole(QV4::String *key) const
354 {
355 return m_layout->getExistingRole(key);
356 }
357
358 const ListLayout::Role &getOrCreateListRole(const QString &name)
359 {
360 return m_layout->getRoleOrCreate(name, ListLayout::Role::List);
361 }
362
363 int elementCount() const
364 {
365 return elements.count();
366 }
367
369
370 void set(int elementIndex, QV4::Object *object, QVector<int> *roles);
371 void set(int elementIndex, QV4::Object *object, SetElement reason = SetElement::IsCurrentlyUpdated);
372
373 int append(QV4::Object *object);
374 void insert(int elementIndex, QV4::Object *object);
375
377
378 int appendElement();
379 void insertElement(int index);
380
381 void move(int from, int to, int n);
382
383 static bool sync(ListModel *src, ListModel *target);
384
385 QObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
386
387private:
388 QPODVector<ListElement *, 4> elements;
389 ListLayout *m_layout;
390
391 QQmlListModel *m_modelCache;
392
393 struct ElementSync
394 {
395 ListElement *src = nullptr;
396 ListElement *target = nullptr;
397 int srcIndex = -1;
398 int targetIndex = -1;
399 QVector<int> changedRoles;
400 };
401
402 void newElement(int index);
403
404 void updateCacheIndices(int start = 0, int end = -1);
405
406 template<typename ArrayLike>
407 ListModel *resolveSubModel(QV4::ScopedObject *o, const ListLayout::Role &r, ArrayLike *a)
408 {
409 ListModel *subModel = new ListModel(r.subLayout, nullptr);
410
411 for (qint64 j = 0, arrayLength = a->getLength(); j < arrayLength; ++j) {
412 *o = a->get(j);
413 subModel->append(*o);
414 }
415
416 return subModel;
417 }
418
419 template<typename ArrayLike>
420 void setArrayLikeFast(
421 QV4::ScopedObject *o, QV4::String *propertyName, ListElement *e, ArrayLike *a)
422 {
423 const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
425 e->setListPropertyFast(r, resolveSubModel(o, r, a));
426 }
427
428 template<typename ArrayLike>
429 int setArrayLike(
430 QV4::ScopedObject *o, QV4::String *propertyName, ListElement *e, ArrayLike *a)
431 {
432 const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
433 return e->setListProperty(r, resolveSubModel(o, r, a));
434 }
435
436 friend class ListElement;
439};
440
442
444
445#endif // QQUICKLISTMODEL_P_P_H
DynamicRoleModelNodeMetaObject(DynamicRoleModelNode *object)
void propertyWritten(int index) override
void propertyWrite(int index) override
static QVector< int > sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target)
QVariant getValue(const QString &name) const
bool setValue(const QByteArray &name, const QVariant &val)
void setNodeUpdatesEnabled(bool enable)
void updateValues(const QVariantMap &object, QVector< int > &roles)
static QVector< int > sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout)
ListElement(int existingUid)
Role(const Role *other)
ListLayout(const ListLayout *other)
int roleCount() const
const Role * getRoleOrCreate(const QString &key, const QVariant &data)
const Role * getExistingRole(QV4::String *key) const
static void sync(ListLayout *src, ListLayout *target)
const Role & getExistingRole(int index) const
const Role & getRoleOrCreate(const QString &key, Role::DataType type)
const Role & getRoleOrCreate(QV4::String *key, Role::DataType type)
const Role * getExistingRole(const QString &key) const
void set(int elementIndex, QV4::Object *object, SetElement reason=SetElement::IsCurrentlyUpdated)
static bool sync(ListModel *src, ListModel *target)
int append(QV4::Object *object)
QVariant getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng)
int elementCount() const
void move(int from, int to, int n)
const ListLayout::Role * getExistingRole(QV4::String *key) const
void insertElement(int index)
ListModel(ListLayout *layout, QQmlListModel *modelCache)
int appendElement()
void insert(int elementIndex, QV4::Object *object)
int setExistingProperty(int uid, const QString &key, const QV4::Value &data, QV4::ExecutionEngine *eng)
void updateTranslations()
QObject * getOrCreateModelObject(QQmlListModel *model, int elementIndex)
void set(int elementIndex, QV4::Object *object, QVector< int > *roles)
ListModel * getListProperty(int elementIndex, const ListLayout::Role &role)
int roleCount() const
int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data)
const ListLayout::Role & getOrCreateListRole(const QString &name)
const ListLayout::Role & getExistingRole(int index) const
QQmlListModel * m_model
void propertyWritten(int index) override
static ModelNodeMetaObject * get(QObject *obj)
ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex)
void updateValues(const QVector< int > &roles)
\inmodule QtCore
Definition qobject.h:105
void verifyBindings(const QQmlRefPointer< QV4::CompiledData::CompilationUnit > &compilationUnit, const QList< const QV4::CompiledData::Binding * > &bindings) override
Definition qjsvalue.h:23
DEFINE_OBJECT_VTABLE(ModelObject)
QT_REQUIRE_CONFIG(animation)
static QAtomicInt uidCounter(MIN_LISTMODEL_UID)
Q_DECLARE_METATYPE(const QV4::CompiledData::Binding *)
static bool isMemoryUsed(const char *mem)
static QString roleTypeName(ListLayout::Role::DataType t)
QT_END_NAMESPACE Q_DECLARE_METATYPE(ListModel *)
QT_REQUIRE_CONFIG(qml_list_model)
QV4QPointer< QQmlListModel > m_model
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
~ModelObjectOwnPropertyKeyIterator() override=default
static OwnPropertyKeyIterator * virtualOwnPropertyKeys(const Object *m, Value *target)
static ReturnedValue lookupGetter(Lookup *l, ExecutionEngine *engine, const Value &object)
static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup)
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
const QV4::CompiledData::Binding * binding
void setString(const QString &s)
QString toString(const QQmlListModel *owner) const
QString asString() const
void setTranslation(const QV4::CompiledData::Binding *binding)