aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4qobjectwrapper.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-01-07 11:01:56 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-01-28 15:03:00 +0100
commitb0fc028cb5a5dfa9e95640a32e9b38ca6df0734d (patch)
tree7a446acca0f5bcbe4e62a1ac22bdb0185913bc5a /src/qml/jsruntime/qv4qobjectwrapper.cpp
parent8c4c0605b077d63e3d73d34ad6dcc4a2cf607b4c (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.cpp33
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;
}