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
26#include <vector>
27
29
30QT_BEGIN_NAMESPACE
31
32
33class DynamicRoleModelNode;
34
36{
37public:
40
42
43protected:
44 void propertyWrite(int index) override;
45 void propertyWritten(int index) override;
46
47private:
48 DynamicRoleModelNode *m_owner;
49};
50
52{
54public:
56
57 static DynamicRoleModelNode *create(const QVariantMap &obj, QQmlListModel *owner);
58
59 void updateValues(const QVariantMap &object, QList<int> &roles);
60
61 QVariant getValue(const QString &name) const
62 {
63 return m_meta->value(name.toUtf8());
64 }
65
66 bool setValue(const QByteArray &name, const QVariant &val)
67 {
68 return m_meta->setValue(name, val);
69 }
70
71 void setNodeUpdatesEnabled(bool enable)
72 {
73 m_meta->m_enabled = enable;
74 }
75
76 int getUid() const
77 {
78 return m_uid;
79 }
80
81 static QList<int> sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target);
82
83private:
84 QQmlListModel *m_owner;
85 int m_uid;
87
89};
90
92{
93public:
94 ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex);
96
97#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
99#else
100 QMetaObject *toDynamicMetaObject(QObject *object) override;
101#endif
102
103 static ModelNodeMetaObject *get(QObject *obj);
104
108
109 void updateValues();
110 void updateValues(const QList<int> &roles);
111
112 bool initialized() const { return m_initialized; }
113
114protected:
115 void propertyWritten(int index) override;
116
117private:
119
120 void emitDirectNotifies(const int *changedRoles, int roleCount);
121
122 void initialize();
123 mutable bool m_initialized;
124};
125
126namespace QV4 {
127
128namespace Heap {
129
131 void init(QObject *object, QQmlListModel *model)
132 {
133 QObjectWrapper::init(object);
134 m_model = model;
135 }
136
137 void destroy()
138 {
139 m_model.destroy();
140 QObjectWrapper::destroy();
141 }
142
143 int elementIndex() const {
144 if (const QObject *o = object()) {
145 const QObjectPrivate *op = QObjectPrivate::get(o);
146 return static_cast<ModelNodeMetaObject *>(op->metaObject)->m_elementIndex;
147 }
148 return -1;
149 }
150
152};
153
154}
155
157{
158 V4_OBJECT2(ModelObject, QObjectWrapper)
160
161protected:
162 static bool virtualPut(Managed *m, PropertyKey id, const Value& value, Value *receiver);
163 static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
164 static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup);
165 static ReturnedValue lookupGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
166 static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
167};
168
169} // namespace QV4
170
172{
173public:
174 ListLayout() : currentBlock(0), currentBlockOffset(0) {}
175 ListLayout(const ListLayout *other);
176 ~ListLayout();
177
178 class Role
179 {
180 public:
181
183 explicit Role(const Role *other);
184 ~Role();
185
186 // This enum must be kept in sync with the roleTypeNames variable in qqmllistmodel.cpp
203
208 int index;
210 };
211
212 const Role *getRoleOrCreate(const QString &key, const QVariant &data);
213 const Role &getRoleOrCreate(QV4::String *key, Role::DataType type);
214 const Role &getRoleOrCreate(const QString &key, Role::DataType type);
215
216 const Role &getExistingRole(int index) const { return *roles.at(index); }
217 const Role *getExistingRole(const QString &key) const;
218 const Role *getExistingRole(QV4::String *key) const;
219
220 int roleCount() const { return roles.size(); }
221
222 static void sync(ListLayout *src, ListLayout *target);
223
224private:
225 const Role &createRole(const QString &key, Role::DataType type);
226
227 int currentBlock;
228 int currentBlockOffset;
229 QList<Role *> roles;
230 QStringHash<Role *> roleHash;
231};
232
234{
236 bool isSet() const { return binding || arrayData; }
237 bool isTranslation() const { return binding && !arrayData; }
238 void setString(const QString &s);
239 void setTranslation(const QV4::CompiledData::Binding *binding);
240 QString toString(const QQmlListModel *owner) const;
241 QString asString() const;
242private:
243 void clear();
244
245 union {
246 char16_t *stringData = nullptr;
248 };
249
250 QTypedArrayData<char16_t> *arrayData = nullptr;
251 uint stringSize = 0;
252};
253
254/*!
255\internal
256*/
258{
259public:
261 enum { BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelNodeMetaObject *) };
262
263 ListElement();
264 ListElement(int existingUid);
265 ~ListElement();
266
267 static QList<int> sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout);
268
269private:
270
271 void destroy(ListLayout *layout);
272
273 int setVariantProperty(const ListLayout::Role &role, const QVariant &d);
274
275 int setJsProperty(const ListLayout::Role &role, const QV4::Value &d, QV4::ExecutionEngine *eng);
276
277 int setStringProperty(const ListLayout::Role &role, const QString &s);
278 int setDoubleProperty(const ListLayout::Role &role, double n);
279 int setBoolProperty(const ListLayout::Role &role, bool b);
280 int setListProperty(const ListLayout::Role &role, ListModel *m);
281 int setQObjectProperty(const ListLayout::Role &role, QV4::QObjectWrapper *o);
282 int setVariantMapProperty(const ListLayout::Role &role, QV4::Object *o);
283 int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m);
284 int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt);
285 int setUrlProperty(const ListLayout::Role &role, const QUrl &url);
286 int setFunctionProperty(const ListLayout::Role &role, const QJSValue &f);
287 int setTranslationProperty(const ListLayout::Role &role, const QV4::CompiledData::Binding *b);
288
289 void setStringPropertyFast(const ListLayout::Role &role, const QString &s);
290 void setDoublePropertyFast(const ListLayout::Role &role, double n);
291 void setBoolPropertyFast(const ListLayout::Role &role, bool b);
292 void setQObjectPropertyFast(const ListLayout::Role &role, QV4::QObjectWrapper *o);
293 void setListPropertyFast(const ListLayout::Role &role, ListModel *m);
294 void setVariantMapFast(const ListLayout::Role &role, QV4::Object *o);
295 void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt);
296 void setUrlPropertyFast(const ListLayout::Role &role, const QUrl &url);
297 void setFunctionPropertyFast(const ListLayout::Role &role, const QJSValue &f);
298
299 void clearProperty(const ListLayout::Role &role);
300
301 QVariant getProperty(const ListLayout::Role &role, const QQmlListModel *owner, QV4::ExecutionEngine *eng);
302 ListModel *getListProperty(const ListLayout::Role &role);
303 StringOrTranslation *getStringProperty(const ListLayout::Role &role);
304 QV4::QObjectWrapper *getQObjectProperty(const ListLayout::Role &role);
305 QV4::PersistentValue *getGuardProperty(const ListLayout::Role &role);
306 QVariantMap *getVariantMapProperty(const ListLayout::Role &role);
307 QDateTime *getDateTimeProperty(const ListLayout::Role &role);
308 QUrl *getUrlProperty(const ListLayout::Role &role);
309 QJSValue *getFunctionProperty(const ListLayout::Role &role);
310
311 inline char *getPropertyMemory(const ListLayout::Role &role);
312
313 int getUid() const { return uid; }
314
315 ModelNodeMetaObject *objectCache();
316
317 char data[BLOCK_SIZE];
318 ListElement *next;
319
320 int uid;
321 QObject *m_objectCache;
322
323 friend class ListModel;
324};
325
326/*!
327\internal
328*/
330{
331public:
332
333 ListModel(ListLayout *layout, QQmlListModel *modelCache);
334
335 void destroy();
336
337 int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data);
338 int setExistingProperty(int uid, const QString &key, const QV4::Value &data, QV4::ExecutionEngine *eng);
339
340 QVariant getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng);
341 ListModel *getListProperty(int elementIndex, const ListLayout::Role &role);
342
343 void updateTranslations();
344
345 int roleCount() const
346 {
347 return m_layout->roleCount();
348 }
349
350 const ListLayout::Role &getExistingRole(int index) const
351 {
352 return m_layout->getExistingRole(index);
353 }
354
355 const ListLayout::Role *getExistingRole(QV4::String *key) const
356 {
357 return m_layout->getExistingRole(key);
358 }
359
360 const ListLayout::Role &getOrCreateListRole(const QString &name)
361 {
362 return m_layout->getRoleOrCreate(name, ListLayout::Role::List);
363 }
364
365 int elementCount() const
366 {
367 return int(elements.size());
368 }
369
371
372 void set(int elementIndex, QV4::Object *object, QList<int> *roles);
373 void set(int elementIndex, QV4::Object *object, SetElement reason = SetElement::IsCurrentlyUpdated);
374
375 int append(QV4::Object *object);
376 void insert(int elementIndex, QV4::Object *object);
377
379
380 int appendElement();
381 void insertElement(int index);
382
383 void move(int from, int to, int n);
384
385 static bool sync(ListModel *src, ListModel *target);
386
387 QObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
388
389private:
390 std::vector<ListElement *> elements;
391 ListLayout *m_layout;
392
393 QQmlListModel *m_modelCache;
394
395 struct ElementSync
396 {
397 ListElement *src = nullptr;
398 ListElement *target = nullptr;
399 int srcIndex = -1;
400 int targetIndex = -1;
401 QList<int> changedRoles;
402 };
403
404 void newElement(int index);
405
406 void updateCacheIndices(int start = 0, int end = -1);
407
408 template<typename ArrayLike>
409 ListModel *resolveSubModel(QV4::ScopedObject *o, const ListLayout::Role &r, ArrayLike *a)
410 {
411 ListModel *subModel = new ListModel(r.subLayout, nullptr);
412
413 for (qint64 j = 0, arrayLength = a->getLength(); j < arrayLength; ++j) {
414 *o = a->get(j);
415 subModel->append(*o);
416 }
417
418 return subModel;
419 }
420
421 template<typename ArrayLike>
422 void setArrayLikeFast(
423 QV4::ScopedObject *o, QV4::String *propertyName, ListElement *e, ArrayLike *a)
424 {
425 const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
427 e->setListPropertyFast(r, resolveSubModel(o, r, a));
428 }
429
430 template<typename ArrayLike>
431 int setArrayLike(
432 QV4::ScopedObject *o, QV4::String *propertyName, ListElement *e, ArrayLike *a)
433 {
434 const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
435 return e->setListProperty(r, resolveSubModel(o, r, a));
436 }
437
438 friend class ListElement;
441};
442
444
446
447#endif // QQUICKLISTMODEL_P_P_H
DynamicRoleModelNodeMetaObject(DynamicRoleModelNode *object)
void propertyWritten(int index) override
void propertyWrite(int index) override
void updateValues(const QVariantMap &object, QList< int > &roles)
static QList< int > sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target)
QVariant getValue(const QString &name) const
bool setValue(const QByteArray &name, const QVariant &val)
void setNodeUpdatesEnabled(bool enable)
static QList< 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)
ListModel * getListProperty(int elementIndex, const ListLayout::Role &role)
int roleCount() const
int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data)
void set(int elementIndex, QV4::Object *object, QList< int > *roles)
const ListLayout::Role & getOrCreateListRole(const QString &name)
const ListLayout::Role & getExistingRole(int index) const
QQmlListModel * m_model
void propertyWritten(int index) override
void updateValues(const QList< int > &roles)
static ModelNodeMetaObject * get(QObject *obj)
ModelNodeMetaObject(QObject *object, QQmlListModel *model, int elementIndex)
\inmodule QtCore
Definition qobject.h:106
void verifyBindings(const QQmlRefPointer< QV4::CompiledData::CompilationUnit > &compilationUnit, const QList< const QV4::CompiledData::Binding * > &bindings) override
Definition qjsvalue.h:24
DEFINE_OBJECT_VTABLE(ModelObject)
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)