diff options
author | Ionut Alexandrescu <ionut.alexandrescu@qt.io> | 2017-02-20 13:27:22 +0100 |
---|---|---|
committer | Ionut Alexandrescu <ionut.alexandrescu@qt.io> | 2017-02-21 12:30:30 +0000 |
commit | bf1bd3abc9a2d990014fa8be451e0239fe12e198 (patch) | |
tree | 2d635481c7f3d92a686282c55c0d916e19b99dad /src | |
parent | 3e537dd3dcf5608241282d8437fb1593d2e6fa17 (diff) |
Add a javascript push method binding to QQmlListProperty
Create a PropertyList prototype, and add the push method to
QQmlListProperty that call the append function if it has been defined.
Added a unit test and updated the documentation.
Change-Id: I2647766e98b60bf0546f6d6ed1422a616e0d3a07
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmllistwrapper.cpp | 25 | ||||
-rw-r--r-- | src/qml/qml/qqmllistwrapper_p.h | 8 |
5 files changed, 40 insertions, 0 deletions
diff --git a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc index ffbf2282a6..a486b47f03 100644 --- a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc +++ b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc @@ -324,6 +324,9 @@ property is only invoked when the property is reassigned to a different object v \li Values in the list are accessed using the \c [index] syntax \endlist + Values can be dynamically added to the list by using the \c push method, + as if it were a JavaScript Array + A \c list can only store QML objects, and cannot contain any \l {QML Basic Types}{basic type} values. (To store basic types within a list, use the \l var type instead.) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 084ddc9010..f925c9184c 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -258,6 +258,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) arrayClass = emptyClass->addMember(id_length(), Attr_NotConfigurable|Attr_NotEnumerable); jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(arrayClass, objectPrototype()); + jsObjects[PropertyListProto] = memoryManager->allocObject<PropertyListPrototype>(); InternalClass *argsClass = emptyClass->addMember(id_length(), Attr_NotEnumerable); argumentsObjectClass = argsClass->addMember(id_callee(), Attr_Data|Attr_NotEnumerable); @@ -360,6 +361,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) static_cast<NumberPrototype *>(numberPrototype())->init(this, numberCtor()); static_cast<BooleanPrototype *>(booleanPrototype())->init(this, booleanCtor()); static_cast<ArrayPrototype *>(arrayPrototype())->init(this, arrayCtor()); + static_cast<PropertyListPrototype *>(propertyListPrototype())->init(this); static_cast<DatePrototype *>(datePrototype())->init(this, dateCtor()); static_cast<FunctionPrototype *>(functionPrototype())->init(this, functionCtor()); static_cast<RegExpPrototype *>(regExpPrototype())->init(this, regExpCtor()); diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 1c20ad30aa..69aa389c44 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -157,6 +157,7 @@ public: IntegerNull, // Has to come after the RootContext to make the context stack safe ObjectProto, ArrayProto, + PropertyListProto, StringProto, NumberProto, BooleanProto, @@ -225,6 +226,7 @@ public: Object *objectPrototype() const { return reinterpret_cast<Object *>(jsObjects + ObjectProto); } Object *arrayPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayProto); } + Object *propertyListPrototype() const { return reinterpret_cast<Object *>(jsObjects + PropertyListProto); } Object *stringPrototype() const { return reinterpret_cast<Object *>(jsObjects + StringProto); } Object *numberPrototype() const { return reinterpret_cast<Object *>(jsObjects + NumberProto); } Object *booleanPrototype() const { return reinterpret_cast<Object *>(jsObjects + BooleanProto); } diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 8aa107dc17..d94f7c56e4 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -165,4 +165,29 @@ void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name return QV4::Object::advanceIterator(m, it, name, index, p, attrs); } +void PropertyListPrototype::init(ExecutionEngine *) +{ + defineDefaultProperty(QStringLiteral("push"), method_push, 1); +} + +void PropertyListPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData *callData) +{ + ScopedObject instance(scope, callData->thisObject.toObject(scope.engine)); + if (!instance) + RETURN_UNDEFINED(); + QmlListWrapper *w = instance->as<QmlListWrapper>(); + if (!w) + RETURN_UNDEFINED(); + if (!w->d()->property().append) + THROW_GENERIC_ERROR("List doesn't define an Append function"); + + QV4::ScopedObject so(scope); + for (int i = 0; i < callData->argc; ++i) + { + so = callData->args[i].toObject(scope.engine); + if (QV4::QObjectWrapper *wrapper = so->as<QV4::QObjectWrapper>()) + w->d()->property().append(&w->d()->property(), wrapper->object() ); + } +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h index d01b332159..b914c681f2 100644 --- a/src/qml/qml/qqmllistwrapper_p.h +++ b/src/qml/qml/qqmllistwrapper_p.h @@ -86,6 +86,7 @@ struct Q_QML_EXPORT QmlListWrapper : Object { V4_OBJECT2(QmlListWrapper, Object) V4_NEEDS_DESTROY + V4_PROTOTYPE(propertyListPrototype) static ReturnedValue create(ExecutionEngine *engine, QObject *object, int propId, int propType); static ReturnedValue create(ExecutionEngine *engine, const QQmlListProperty<QObject> &prop, int propType); @@ -98,6 +99,13 @@ struct Q_QML_EXPORT QmlListWrapper : Object static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); }; +struct PropertyListPrototype : Object +{ + void init(ExecutionEngine *engine); + + static void method_push(const BuiltinFunction *, Scope &, CallData *callData); +}; + } QT_END_NAMESPACE |