diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2022-01-07 11:01:56 +0100 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2022-01-28 15:03:00 +0100 |
| commit | b0fc028cb5a5dfa9e95640a32e9b38ca6df0734d (patch) | |
| tree | 7a446acca0f5bcbe4e62a1ac22bdb0185913bc5a /src/qml/jsruntime/qv4qobjectwrapper.cpp | |
| parent | 8c4c0605b077d63e3d73d34ad6dcc4a2cf607b4c (diff) | |
QML: Allow named lists of value types
We register QList<T> as sequential container type for any value type T
we get. This way we can always find a type to use for list<t> with t
being a value type. The metatypes are shuffled around so that we have an
easier time associating a type with its list and vice versa.
As QQmlPropertyData's isQList flag denotes both QQmlListProperty<T> and
QList<T> now, we need to use QMetaType::IsQmlList more often.
Conversely, any name given to extra sequential containers registered via
QML_SEQUENTIAL_CONTAINER is explicitly ignored now. As you can do
list<foo> for any type foo now, there is not much of a point in having
further named container registrations for the same type. It would just
make things more complicated. Mind that the name had already been
ignored before, just not explicitly.
[ChangeLog][QtQml] You can now use lists of value types in QML. For
example a property of type list<int> will hold a list of integers.
Task-number: QTBUG-82443
Change-Id: I7bee61cee3963dae5d231bf59f70b8012984371d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4qobjectwrapper.cpp')
| -rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index a63f1fc7f9..c775d66638 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -131,11 +131,12 @@ static ReturnedValue loadProperty(ExecutionEngine *v4, QObject *object, Q_ASSERT(!property.isFunction()); Scope scope(v4); + const QMetaType propMetaType = property.propType(); if (property.isQObject()) { QObject *rv = nullptr; property.readProperty(object, &rv); ReturnedValue ret = QObjectWrapper::wrap(v4, rv); - if (property.propType().flags().testFlag(QMetaType::IsConst)) { + if (propMetaType.flags().testFlag(QMetaType::IsConst)) { ScopedValue v(scope, ret); if (auto obj = v->as<Object>()) { obj->setInternalClass(obj->internalClass()->cryopreserved()); @@ -145,10 +146,9 @@ static ReturnedValue loadProperty(ExecutionEngine *v4, QObject *object, return ret; } - if (property.isQList()) - return QmlListWrapper::create(v4, object, property.coreIndex(), property.propType()); + if (property.isQList() && propMetaType.flags().testFlag(QMetaType::IsQmlList)) + return QmlListWrapper::create(v4, object, property.coreIndex(), propMetaType); - const QMetaType propMetaType = property.propType(); switch (property.isEnum() ? QMetaType::Int : propMetaType.id()) { case QMetaType::Int: { int v = 0; @@ -205,23 +205,23 @@ static ReturnedValue loadProperty(ExecutionEngine *v4, QObject *object, if (QQmlMetaType::isValueType(propMetaType)) { if (const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(propMetaType)) return QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, propMetaType); - } else { - // see if it's a sequence type - bool succeeded = false; - ScopedValue retn(scope, SequencePrototype::newSequence( - v4, propMetaType, object, property.coreIndex(), - !property.isWritable(), &succeeded)); - if (succeeded) - return retn->asReturnedValue(); } + // see if it's a sequence type + bool succeeded = false; + QV4::ScopedValue retn(scope, QV4::SequencePrototype::newSequence( + v4, propMetaType, object, property.coreIndex(), + !property.isWritable(), &succeeded)); + if (succeeded) + return retn->asReturnedValue(); + if (!propMetaType.isValid()) { QMetaProperty p = object->metaObject()->property(property.coreIndex()); qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property " "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name()); return Encode::undefined(); } else { - QVariant v(property.propType(), (void *)nullptr); + QVariant v(propMetaType); property.readProperty(object, v.data()); return scope.engine->fromVariant(v); } @@ -1541,8 +1541,8 @@ static int MatchScore(const Value &actual, QMetaType conversionMetaType) } } - if (auto sequenceMetaType = SequencePrototype::metaTypeForSequence(obj); sequenceMetaType != -1) { - if (sequenceMetaType == conversionType) + if (auto sequenceMetaType = SequencePrototype::metaTypeForSequence(obj); sequenceMetaType.isValid()) { + if (sequenceMetaType == conversionMetaType) return 1; else return 10; @@ -1888,7 +1888,8 @@ bool CallArgument::fromContainerValue(const Value &value, M CallArgument::*membe { const Object *object = value.as<Object>(); if (object && object->isListType()) { - if (T* ptr = static_cast<T *>(SequencePrototype::getRawContainerPtr(object, type))) { + if (T* ptr = static_cast<T *>(SequencePrototype::getRawContainerPtr( + object, QMetaType(type)))) { (this->*member) = ptr; return true; } |
