diff options
22 files changed, 122 insertions, 107 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp index 5dcfbf2e0f..971404c831 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp @@ -215,7 +215,8 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const // maps for serialization. if (value.userType() == qMetaTypeId<QJSValue>()) value = value.value<QJSValue>().toVariant(); - const int userType = value.userType(); + const QMetaType metaType = value.metaType(); + const int metaTypeId = metaType.id(); //QObject * is not streamable. //Convert all such instances to a String value @@ -238,7 +239,7 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const return contents; } - switch (userType) { + switch (metaTypeId) { case QMetaType::QRect: case QMetaType::QRectF: case QMetaType::QPoint: @@ -257,8 +258,8 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const case QMetaType::QJsonDocument: return value.toJsonDocument().toVariant(); default: - if (QQmlValueTypeFactory::isValueType(userType)) { - const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(userType); + if (QQmlValueTypeFactory::isValueType(metaType)) { + const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(metaType); if (mo) { int toStringIndex = mo->indexOfMethod("toString()"); if (toStringIndex != -1) { @@ -274,7 +275,7 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const return value; } - if (QQmlMetaType::isQObject(userType)) { + if (QQmlMetaType::isQObject(metaTypeId)) { QObject *o = QQmlMetaType::toQObject(value); if (o) { QString name = o->objectName(); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 2892b616b0..1085b81ab7 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1718,7 +1718,8 @@ static QVariant objectToVariant(QV4::ExecutionEngine *e, const QV4::Object *o, V QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) { - int type = variant.userType(); + const QMetaType metaType = variant.metaType(); + int type = metaType.id(); const void *ptr = variant.constData(); if (type < QMetaType::User) { @@ -1804,8 +1805,8 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) break; } - if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type)) - return QV4::QQmlValueTypeWrapper::create(this, variant, vtmo, type); + if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(metaType)) + return QV4::QQmlValueTypeWrapper::create(this, variant, vtmo, metaType); } else { QV4::Scope scope(this); if (type == qMetaTypeId<QQmlListReference>()) { @@ -1851,8 +1852,8 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant) return sequentialIterableToJS(this, lst); } - if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type)) - return QV4::QQmlValueTypeWrapper::create(this, variant, vtmo, type); + if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(metaType)) + return QV4::QQmlValueTypeWrapper::create(this, variant, vtmo, metaType); } // XXX TODO: To be compatible, we still need to handle: diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 2e6df06c36..200ebfaffd 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -132,7 +132,8 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object { Q_ASSERT(!property.isFunction()); QV4::Scope scope(v4); - const int propType = property.propType().id(); + const QMetaType propMetaType = property.propType(); + const int propType = propMetaType.id(); if (property.isQObject()) { QObject *rv = nullptr; @@ -176,15 +177,15 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object QVariant v; property.readProperty(object, &v); - if (QQmlValueTypeFactory::isValueType(v.userType())) { - if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(v.userType())) - return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, v.userType()); // VariantReference value-type. + if (QQmlValueTypeFactory::isValueType(v.metaType())) { + if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(v.metaType())) + return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, v.metaType()); // VariantReference value-type. } return scope.engine->fromVariant(v); - } else if (QQmlValueTypeFactory::isValueType(propType)) { - if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(propType)) - return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, propType); + } else if (QQmlValueTypeFactory::isValueType(propMetaType)) { + if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(propMetaType)) + return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, propMetaType); } else { #if QT_CONFIG(qml_sequence_object) // see if it's a sequence type diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 0101607b4f..68764f1052 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -630,7 +630,7 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD Q_ASSERT(*propertyData); if (Q_UNLIKELY(m_targetIndex.hasValueTypeIndex() && valueTypeData)) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType((*propertyData)->propType().id()); + const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType((*propertyData)->propType()); Q_ASSERT(valueTypeMetaObject); QMetaProperty vtProp = valueTypeMetaObject->property(m_targetIndex.valueTypeIndex()); valueTypeData->setFlags(QQmlPropertyData::flagsForProperty(vtProp)); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 7db03570e2..b217f09ca6 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -288,13 +288,14 @@ public: mutable QMutex networkAccessManagerMutex; - QQmlGadgetPtrWrapper *valueTypeInstance(int typeIndex) + QQmlGadgetPtrWrapper *valueTypeInstance(QMetaType type) { + int typeIndex = type.id(); auto it = cachedValueTypeInstances.find(typeIndex); if (it != cachedValueTypeInstances.end()) return *it; - if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(typeIndex)) { + if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type)) { QQmlGadgetPtrWrapper *instance = new QQmlGadgetPtrWrapper(valueType, q_func()); cachedValueTypeInstances.insert(typeIndex, instance); return instance; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 21e845ccdb..8bf16fec96 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -843,8 +843,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper const QQmlPropertyData *valueTypeProperty = nullptr; QObject *bindingTarget = _bindingTarget; - if (QQmlValueTypeFactory::isValueType(bindingProperty->propType().id())) { - valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType().id()); + if (QQmlValueTypeFactory::isValueType(bindingProperty->propType())) { + valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType()); if (!valueType) { recordError(binding->location, tr("Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex))); return false; diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index d05b9c52fe..8f6639adf5 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -316,9 +316,9 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name) if (property->isFunction()) return; // Not an object property - if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType().id())) { + if (ii == (path.count() - 2) && QQmlValueTypeFactory::isValueType(property->propType())) { // We're now at a value type property - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType().id()); + const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType()); if (!valueTypeMetaObject) return; // Not a value type int idx = valueTypeMetaObject->indexOfProperty(path.last().toUtf8().constData()); @@ -477,10 +477,10 @@ QQmlPropertyPrivate::propertyTypeCategory() const if (isValueType()) { return QQmlProperty::Normal; } else if (type & QQmlProperty::Property) { - int type = propertyType(); - if (type == QMetaType::UnknownType) + QMetaType type = propertyType(); + if (!type.isValid()) return QQmlProperty::InvalidCategory; - else if (QQmlValueTypeFactory::isValueType((uint)type)) + else if (QQmlValueTypeFactory::isValueType(type)) return QQmlProperty::Normal; else if (core.isQObject()) return QQmlProperty::Object; @@ -502,7 +502,7 @@ const char *QQmlProperty::propertyTypeName() const if (!d) return nullptr; if (d->isValueType()) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType().id()); + const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType()); Q_ASSERT(valueTypeMetaObject); return valueTypeMetaObject->property(d->valueTypeData.coreIndex()).typeName(); } else if (d->object && type() & Property && d->core.isValid()) { @@ -533,7 +533,12 @@ bool QQmlProperty::operator==(const QQmlProperty &other) const */ int QQmlProperty::propertyType() const { - return d ? d->propertyType() : int(QMetaType::UnknownType); + return d ? d->propertyType().id() : int(QMetaType::UnknownType); +} + +QMetaType QQmlProperty::propertyMetaType() const +{ + return d ? d->propertyType() : QMetaType {}; } bool QQmlPropertyPrivate::isValueType() const @@ -541,15 +546,15 @@ bool QQmlPropertyPrivate::isValueType() const return valueTypeData.isValid(); } -int QQmlPropertyPrivate::propertyType() const +QMetaType QQmlPropertyPrivate::propertyType() const { uint type = this->type(); if (isValueType()) { - return valueTypeData.propType().id(); + return valueTypeData.propType(); } else if (type & QQmlProperty::Property) { - return core.propType().id(); + return core.propType(); } else { - return QMetaType::UnknownType; + return QMetaType(); } } @@ -676,7 +681,7 @@ QString QQmlProperty::name() const // ### if (!d->object) { } else if (d->isValueType()) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType().id()); + const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(d->core.propType()); Q_ASSERT(valueTypeMetaObject); const char *vtName = valueTypeMetaObject->property(d->valueTypeData.coreIndex()).name(); @@ -1057,9 +1062,9 @@ QVariant QQmlPropertyPrivate::readValueProperty() }; if (isValueType()) { - if (QQmlGadgetPtrWrapper *wrapper = QQmlGadgetPtrWrapper::instance(engine, core.propType().id())) + if (QQmlGadgetPtrWrapper *wrapper = QQmlGadgetPtrWrapper::instance(engine, core.propType())) return doRead(wrapper); - if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType().id())) { + if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) { QQmlGadgetPtrWrapper wrapper(valueType, nullptr); return doRead(&wrapper); } @@ -1195,11 +1200,11 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object, }; QQmlGadgetPtrWrapper *wrapper = context - ? QQmlGadgetPtrWrapper::instance(context->engine(), core.propType().id()) + ? QQmlGadgetPtrWrapper::instance(context->engine(), core.propType()) : nullptr; if (wrapper) { doWrite(wrapper); - } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType().id())) { + } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) { QQmlGadgetPtrWrapper wrapper(valueType, nullptr); doWrite(&wrapper); } diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h index 99288ac831..53443bdee4 100644 --- a/src/qml/qml/qqmlproperty.h +++ b/src/qml/qml/qqmlproperty.h @@ -90,6 +90,7 @@ public: bool isSignalProperty() const; int propertyType() const; + QMetaType propertyMetaType() const; PropertyTypeCategory propertyTypeCategory() const; const char *propertyTypeName() const; diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h index 75b505ddc9..a0ef99124c 100644 --- a/src/qml/qml/qqmlproperty_p.h +++ b/src/qml/qml/qqmlproperty_p.h @@ -96,7 +96,7 @@ public: void initDefault(QObject *obj); bool isValueType() const; - int propertyType() const; + QMetaType propertyType() const; QQmlProperty::Type type() const; QQmlProperty::PropertyTypeCategory propertyTypeCategory() const; diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp index dcefa33166..b8d2eeccf8 100644 --- a/src/qml/qml/qqmlpropertycachecreator.cpp +++ b/src/qml/qml/qqmlpropertycachecreator.cpp @@ -123,7 +123,7 @@ QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiating // There is another overload that takes no version, which we shall not use here. return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType().id(), instantiatingProperty->typeVersion()); - } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType().id())) { + } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) { return enginePrivate->cache(vtmo, instantiatingProperty->typeVersion()); } } diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 9552cadccf..2377bd0c3b 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -237,7 +237,7 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecur // group properties and value type group properties. For the former the base type is derived from // the property that references us, for the latter we only need a meta-object on the referencing object // because interceptors can't go to the shared value type instances. - if (context.instantiatingProperty && QQmlValueTypeFactory::isValueType(context.instantiatingProperty->propType().id())) { + if (context.instantiatingProperty && QQmlValueTypeFactory::isValueType(context.instantiatingProperty->propType())) { if (!propertyCaches->needsVMEMetaObject(context.referencingObjectIndex)) { const CompiledObject *obj = objectContainer->objectAt(context.referencingObjectIndex); auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex); @@ -851,7 +851,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor Q_ASSERT(targetProperty); // for deep aliases, valueTypeIndex is always set - if (!QQmlValueTypeFactory::isValueType(targetProperty->propType().id()) && valueTypeIndex != -1) { + if (!QQmlValueTypeFactory::isValueType(targetProperty->propType()) && valueTypeIndex != -1) { // deep alias property *type = targetProperty->propType(); targetCache = enginePriv->propertyCacheForType(type->id()); diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp index c1d0977f31..d9e6537179 100644 --- a/src/qml/qml/qqmlpropertyvalidator.cpp +++ b/src/qml/qml/qqmlpropertyvalidator.cpp @@ -229,7 +229,7 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( if (binding->type >= QV4::CompiledData::Binding::Type_Object && (pd || binding->isAttachedProperty())) { const bool populatingValueTypeGroupProperty = pd - && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType().id()) + && QQmlValueTypeFactory::metaObjectForMetaType(pd->propType()) && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment); const QVector<QQmlError> subObjectValidatorErrors = validateObject(binding->value.objectIndex, binding, @@ -282,7 +282,7 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( if (loc < (*assignedGroupProperty)->valueLocation) loc = (*assignedGroupProperty)->valueLocation; - if (pd && QQmlValueTypeFactory::isValueType(pd->propType().id())) + if (pd && QQmlValueTypeFactory::isValueType(pd->propType())) return recordError(loc, tr("Property has already been assigned a value")); return recordError(loc, tr("Cannot assign a value directly to a grouped property")); } @@ -296,8 +296,8 @@ QVector<QQmlError> QQmlPropertyValidator::validateObject( if (bindingError.isValid()) return recordError(bindingError); } else if (binding->isGroupProperty()) { - if (QQmlValueTypeFactory::isValueType(pd->propType().id())) { - if (QQmlValueTypeFactory::metaObjectForMetaType(pd->propType().id())) { + if (QQmlValueTypeFactory::isValueType(pd->propType())) { + if (QQmlValueTypeFactory::metaObjectForMetaType(pd->propType())) { if (!pd->isWritable()) { return recordError(binding->location, tr("Invalid property assignment: \"%1\" is a read-only property").arg(name)); } @@ -737,7 +737,7 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert .arg(typeName)); } else if (propType == qMetaTypeId<QQmlScriptString>()) { return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected")); - } else if (QQmlValueTypeFactory::isValueType(propType)) { + } else if (QQmlValueTypeFactory::isValueType(property->propType())) { return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting an object") .arg(rhsType()).arg(propertyName)); } else { diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index b39aa174a3..cd89a908b3 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -1184,7 +1184,7 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, propIdx = QQmlPropertyIndex(targetProperty->coreIndex()); if (!subProperty.isEmpty()) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(targetProperty->propType().id()); + const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(targetProperty->propType()); if (!valueTypeMetaObject) { // could be a deep alias bool isDeepAlias = subProperty.at(0).isLower(); diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index 9f19f21664..b0e08d3c41 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -59,10 +59,10 @@ struct QQmlValueTypeFactoryImpl QQmlValueTypeFactoryImpl(); ~QQmlValueTypeFactoryImpl(); - bool isValueType(int idx); + bool isValueType(QMetaType type); - const QMetaObject *metaObjectForMetaType(int); - QQmlValueType *valueType(int); + const QMetaObject *metaObjectForMetaType(QMetaType metaType); + QQmlValueType *valueType(QMetaType type); QQmlValueType *valueTypes[QMetaType::User]; QHash<int, QQmlValueType *> userTypes; @@ -109,16 +109,17 @@ bool isInternalType(int idx) } } -bool QQmlValueTypeFactoryImpl::isValueType(int idx) +bool QQmlValueTypeFactoryImpl::isValueType(QMetaType type) { - if (idx < 0 || isInternalType(idx)) + if (!type.isValid() || isInternalType(type.id())) return false; - return valueType(idx) != nullptr; + return valueType(type) != nullptr; } -const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t) +const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(QMetaType metaType) { + const int t = metaType.id(); switch (t) { case QMetaType::QPoint: return &QQmlPointValueType::staticMetaObject; @@ -144,16 +145,14 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t) #endif default: #if QT_CONFIG(qml_itemmodel) - if (t == qMetaTypeId<QItemSelectionRange>()) + if (metaType == QMetaType::fromType<QItemSelectionRange>()) return &QQmlItemSelectionRangeValueType::staticMetaObject; #endif - if (t == qMetaTypeId<QQmlProperty>()) + if (metaType == QMetaType::fromType<QQmlProperty>()) return &QQmlPropertyValueType::staticMetaObject; break; } - const QMetaType metaType(t); - // It doesn't have to be a gadget for a QML type to exist, but we don't want to // call QObject pointers value types. Explicitly registered types also override // the implicit use of gadgets. @@ -176,8 +175,9 @@ const QMetaObject *QQmlValueTypeFactoryImpl::metaObjectForMetaType(int t) return nullptr; } -QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx) +QQmlValueType *QQmlValueTypeFactoryImpl::valueType(QMetaType type) { + int idx = type.id(); if (idx >= (int)QMetaType::User) { // Protect the hash with a mutex mutex.lock(); @@ -185,7 +185,7 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx) QHash<int, QQmlValueType *>::iterator it = userTypes.find(idx); if (it == userTypes.end()) { QQmlValueType *vt = nullptr; - if (const QMetaObject *mo = metaObjectForMetaType(idx)) + if (const QMetaObject *mo = metaObjectForMetaType(type)) vt = new QQmlValueType(idx, mo); it = userTypes.insert(idx, vt); } @@ -202,7 +202,7 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx) // removing the preallocated array if (isInternalType(idx)) rv = valueTypes[idx] = nullptr; - else if (const QMetaObject *mo = metaObjectForMetaType(idx)) + else if (const QMetaObject *mo = metaObjectForMetaType(type)) rv = valueTypes[idx] = new QQmlValueType(idx, mo); else rv = valueTypes[idx] = nullptr; @@ -215,17 +215,17 @@ QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx) Q_GLOBAL_STATIC(QQmlValueTypeFactoryImpl, factoryImpl); -bool QQmlValueTypeFactory::isValueType(int idx) +bool QQmlValueTypeFactory::isValueType(QMetaType type) { - return factoryImpl()->isValueType(idx); + return factoryImpl()->isValueType(type); } -QQmlValueType *QQmlValueTypeFactory::valueType(int idx) +QQmlValueType *QQmlValueTypeFactory::valueType(QMetaType type) { - return factoryImpl()->valueType(idx); + return factoryImpl()->valueType(type); } -const QMetaObject *QQmlValueTypeFactory::metaObjectForMetaType(int type) +const QMetaObject *QQmlValueTypeFactory::metaObjectForMetaType(QMetaType type) { return factoryImpl()->metaObjectForMetaType(type); } @@ -243,9 +243,9 @@ QQmlValueType::~QQmlValueType() ::free(dynamicMetaObject); } -QQmlGadgetPtrWrapper *QQmlGadgetPtrWrapper::instance(QQmlEngine *engine, int index) +QQmlGadgetPtrWrapper *QQmlGadgetPtrWrapper::instance(QQmlEngine *engine, QMetaType type) { - return engine ? QQmlEnginePrivate::get(engine)->valueTypeInstance(index) : nullptr; + return engine ? QQmlEnginePrivate::get(engine)->valueTypeInstance(type) : nullptr; } QQmlGadgetPtrWrapper::QQmlGadgetPtrWrapper(QQmlValueType *valueType, QObject *parent) diff --git a/src/qml/qml/qqmlvaluetype_p.h b/src/qml/qml/qqmlvaluetype_p.h index 4abf324121..d2c49c9387 100644 --- a/src/qml/qml/qqmlvaluetype_p.h +++ b/src/qml/qml/qqmlvaluetype_p.h @@ -97,7 +97,7 @@ class Q_QML_PRIVATE_EXPORT QQmlGadgetPtrWrapper : public QObject { Q_OBJECT public: - static QQmlGadgetPtrWrapper *instance(QQmlEngine *engine, int index); + static QQmlGadgetPtrWrapper *instance(QQmlEngine *engine, QMetaType type); QQmlGadgetPtrWrapper(QQmlValueType *valueType, QObject *parent); ~QQmlGadgetPtrWrapper(); @@ -120,11 +120,9 @@ private: class Q_QML_PRIVATE_EXPORT QQmlValueTypeFactory { public: - static bool isValueType(int idx); - static QQmlValueType *valueType(QMetaType metaType) {return valueType(metaType.id());}; - static QQmlValueType *valueType(int idx); - static const QMetaObject *metaObjectForMetaType(QMetaType type) {return metaObjectForMetaType(type.id());}; - static const QMetaObject *metaObjectForMetaType(int type); + static bool isValueType(QMetaType type); + static QQmlValueType *valueType(QMetaType metaType); + static const QMetaObject *metaObjectForMetaType(QMetaType type); }; struct QQmlPointFValueType diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index f8f10b3277..e1b76cdb6f 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -138,8 +138,8 @@ bool QQmlValueTypeReference::readReferenceValue() const void *a[] = { &variantReferenceValue, nullptr }; QMetaObject::metacall(d()->object, QMetaObject::ReadProperty, d()->property, a); - int variantReferenceType = variantReferenceValue.userType(); - if (variantReferenceType != typeId()) { + const QMetaType variantReferenceType = variantReferenceValue.metaType(); + if (variantReferenceType != type()) { // This is a stale VariantReference. That is, the variant has been // overwritten with a different type in the meantime. // We need to modify this reference to the updated value type, if @@ -183,7 +183,7 @@ void QQmlValueTypeWrapper::initProto(ExecutionEngine *v4) v4->jsObjects[QV4::ExecutionEngine::ValueTypeProto] = o->d(); } -ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *object, int property, const QMetaObject *metaObject, int typeId) +ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *object, int property, const QMetaObject *metaObject, QMetaType type) { Scope scope(engine); initProto(engine); @@ -192,27 +192,27 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj r->d()->object = object; r->d()->property = property; r->d()->setMetaObject(metaObject); - auto valueType = QQmlValueTypeFactory::valueType(typeId); + auto valueType = QQmlValueTypeFactory::valueType(type); if (!valueType) { return engine->throwTypeError(QLatin1String("Type %1 is not a value type") - .arg(QString::fromUtf8(QMetaType(typeId).name()))); + .arg(QString::fromUtf8(type.name()))); } r->d()->setValueType(valueType); r->d()->setGadgetPtr(nullptr); return r->asReturnedValue(); } -ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVariant &value, const QMetaObject *metaObject, int typeId) +ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVariant &value, const QMetaObject *metaObject, QMetaType type) { Scope scope(engine); initProto(engine); Scoped<QQmlValueTypeWrapper> r(scope, engine->memoryManager->allocate<QQmlValueTypeWrapper>()); r->d()->setMetaObject(metaObject); - auto valueType = QQmlValueTypeFactory::valueType(typeId); + auto valueType = QQmlValueTypeFactory::valueType(type); if (!valueType) { return engine->throwTypeError(QLatin1String("Type %1 is not a value type") - .arg(QString::fromUtf8(QMetaType(typeId).name()))); + .arg(QString::fromUtf8(type.name()))); } r->d()->setValueType(valueType); r->d()->setGadgetPtr(nullptr); @@ -405,6 +405,11 @@ int QQmlValueTypeWrapper::typeId() const return d()->valueType()->metaType.id(); } +QMetaType QQmlValueTypeWrapper::type() const +{ + return d()->valueType()->metaType; +} + bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const { bool destructGadgetOnExit = false; diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index 0a6d073478..ffce64d54e 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -121,13 +121,14 @@ struct Q_QML_EXPORT QQmlValueTypeWrapper : Object public: - static ReturnedValue create(ExecutionEngine *engine, QObject *, int, const QMetaObject *metaObject, int typeId); - static ReturnedValue create(ExecutionEngine *engine, const QVariant &, const QMetaObject *metaObject, int typeId); + static ReturnedValue create(ExecutionEngine *engine, QObject *, int, const QMetaObject *metaObject, QMetaType type); + static ReturnedValue create(ExecutionEngine *engine, const QVariant &, const QMetaObject *metaObject, QMetaType type); QVariant toVariant() const; bool toGadget(void *data) const; bool isEqual(const QVariant& value) const; int typeId() const; + QMetaType type() const; bool write(QObject *target, int propertyIndex) const; QQmlPropertyData dataForPropertyKey(PropertyKey id) const; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 2ae9707c22..bea8fc06f7 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -321,12 +321,13 @@ bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a) const int valueIndex = vi->m_propertyIndex.valueTypeIndex(); const QQmlData *data = QQmlData::get(object); - const int type = data->propertyCache->property(id)->propType().id(); + const QMetaType metaType = data->propertyCache->property(id)->propType(); + const int type = metaType.id(); if (type != QMetaType::UnknownType) { if (valueIndex != -1) { QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance( - data->context->engine(), type); + data->context->engine(), metaType); Q_ASSERT(valueType); // @@ -930,7 +931,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex); // Value type property or deep alias QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance( - ctxt->engine(), pd->propType().id()); + ctxt->engine(), pd->propType()); if (valueType) { valueType->read(target, coreIndex); int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a); diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp index a9e8251572..1115c60b02 100644 --- a/src/quick/designer/qquickdesignersupportproperties.cpp +++ b/src/quick/designer/qquickdesignersupportproperties.cpp @@ -154,7 +154,7 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propert + '.', inspectedObjects)); } } else if (QQmlGadgetPtrWrapper *valueType - = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) { + = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.metaType())) { valueType->setValue(metaProperty.read(object)); propertyNameList.append(propertyNameListForWritableProperties(valueType, baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()) @@ -222,7 +222,7 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp + '.', inspectedObjects)); } } else if (QQmlGadgetPtrWrapper *valueType - = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) { + = QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.metaType())) { valueType->setValue(metaProperty.read(object)); propertyNameList.append(baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())); propertyNameList.append(allPropertyNames(valueType, diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index cfa8d3a51a..bfdc863d10 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -1270,7 +1270,7 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti myAction.property = d->createProperty(targets.at(j), props.at(i), this); if (myAction.property.isValid()) { myAction.toValue = d->value; - QQuickPropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType()); + QQuickPropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyMetaType()); data->actions << myAction; hasExplicit = true; for (int ii = 0; ii < actions.count(); ++ii) { @@ -1303,7 +1303,7 @@ QAbstractAnimationJob* QQuickPropertyAction::transition(QQuickStateActions &acti if (d->value.isValid()) myAction.toValue = d->value; - QQuickPropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyType()); + QQuickPropertyAnimationPrivate::convertVariant(myAction.toValue, myAction.property.propertyMetaType()); modified << action.property; data->actions << myAction; @@ -1962,14 +1962,14 @@ QAbstractAnimationJob* QQuickParallelAnimation::transition(QQuickStateActions &a } //convert a variant from string type to another animatable type -void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type) +void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, QMetaType type) { if (variant.userType() != QMetaType::QString) { - variant.convert(QMetaType(type)); + variant.convert(type); return; } - switch (type) { + switch (type.id()) { case QMetaType::QRect: case QMetaType::QRectF: case QMetaType::QPoint: @@ -1980,14 +1980,14 @@ void QQuickPropertyAnimationPrivate::convertVariant(QVariant &variant, int type) case QMetaType::QVector3D: { bool ok = false; - variant = QQmlStringConverters::variantFromString(variant.toString(), type, &ok); + variant = QQmlStringConverters::variantFromString(variant.toString(), type.id(), &ok); } break; default: - if (QQmlValueTypeFactory::isValueType((uint)type)) { + if (QQmlValueTypeFactory::isValueType(type)) { variant.convert(QMetaType(type)); } else { - QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(type); + QQmlMetaType::StringConverter converter = QQmlMetaType::customStringConverter(type.id()); if (converter) variant = converter(variant.toString()); } @@ -2599,7 +2599,7 @@ void QQuickAnimationPropertyUpdater::setValue(qreal v) if (!fromSourced && !fromDefined) { action.fromValue = action.property.read(); if (interpolatorType) { - QQuickPropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType); + QQuickPropertyAnimationPrivate::convertVariant(action.fromValue, QMetaType(interpolatorType)); } } if (!interpolatorType) { @@ -2681,10 +2681,10 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA if (d->fromIsDefined) { myAction.fromValue = d->from; - d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); + d->convertVariant(myAction.fromValue, d->interpolatorType ? QMetaType(d->interpolatorType) : myAction.property.propertyMetaType()); } myAction.toValue = d->to; - d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); + d->convertVariant(myAction.toValue, d->interpolatorType ? QMetaType(d->interpolatorType) : myAction.property.propertyMetaType()); newActions << myAction; hasExplicit = true; for (int ii = 0; ii < actions.count(); ++ii) { @@ -2730,8 +2730,8 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA if (d->toIsDefined) myAction.toValue = d->to; - d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); - d->convertVariant(myAction.toValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); + d->convertVariant(myAction.fromValue, d->interpolatorType ? QMetaType(d->interpolatorType) : myAction.property.propertyMetaType()); + d->convertVariant(myAction.toValue, d->interpolatorType ? QMetaType(d->interpolatorType) : myAction.property.propertyMetaType()); modified << action.property; diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h index 98d4751d1f..1b62f97faf 100644 --- a/src/quick/util/qquickanimation_p_p.h +++ b/src/quick/util/qquickanimation_p_p.h @@ -296,7 +296,7 @@ public: QQuickStateActions *actions; static QVariant interpolateVariant(const QVariant &from, const QVariant &to, qreal progress); - static void convertVariant(QVariant &variant, int type); + static void convertVariant(QVariant &variant, QMetaType type); }; class QQuickRotationAnimationPrivate : public QQuickPropertyAnimationPrivate diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index cf6ed273af..f615060ce3 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -1823,8 +1823,8 @@ void tst_qqmlvaluetypes::scarceTypes() // These should not be treated as value types because we want the scarce resource // mechanism to clear them when going out of scope. The scarce resource mechanism // only works on QV4::VariantObject as that has an additional level of redirection. - QVERIFY(!QQmlValueTypeFactory::isValueType(qMetaTypeId<QImage>())); - QVERIFY(!QQmlValueTypeFactory::isValueType(qMetaTypeId<QPixmap>())); + QVERIFY(!QQmlValueTypeFactory::isValueType(QMetaType::fromType<QImage>())); + QVERIFY(!QQmlValueTypeFactory::isValueType(QMetaType::fromType<QPixmap>())); QV4::ExecutionEngine engine; QV4::Scope scope(&engine); @@ -1839,7 +1839,7 @@ void tst_qqmlvaluetypes::scarceTypes() } #define CHECK_TYPE_IS_NOT_VALUETYPE(Type, typeId, cppType) \ - QVERIFY(!QQmlValueTypeFactory::isValueType(QMetaType::Type)); + QVERIFY(!QQmlValueTypeFactory::isValueType(QMetaType(QMetaType::Type))); void tst_qqmlvaluetypes::nonValueTypes() { |