diff options
56 files changed, 382 insertions, 176 deletions
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp index cadd2992b1..5e2133dfaf 100644 --- a/src/particles/qquickcustomaffector.cpp +++ b/src/particles/qquickcustomaffector.cpp @@ -233,7 +233,7 @@ bool QQuickCustomAffector::affectParticle(QQuickParticleData *d, qreal dt) return changed; } -void QQuickCustomAffector::affectProperties(const QList<QQuickParticleData*> particles, qreal dt) +void QQuickCustomAffector::affectProperties(const QList<QQuickParticleData*> &particles, qreal dt) { foreach (QQuickParticleData* d, particles) if ( affectParticle(d, dt) ) diff --git a/src/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h index 9fb7e67521..5e8671514d 100644 --- a/src/particles/qquickcustomaffector_p.h +++ b/src/particles/qquickcustomaffector_p.h @@ -158,7 +158,7 @@ protected: bool affectParticle(QQuickParticleData *d, qreal dt) override; private: - void affectProperties(const QList<QQuickParticleData*> particles, qreal dt); + void affectProperties(const QList<QQuickParticleData*> &particles, qreal dt); QQuickDirection * m_position; QQuickDirection * m_velocity; QQuickDirection * m_acceleration; diff --git a/src/particles/qquickmaskextruder.cpp b/src/particles/qquickmaskextruder.cpp index 4c5d9e9d88..2ce3650743 100644 --- a/src/particles/qquickmaskextruder.cpp +++ b/src/particles/qquickmaskextruder.cpp @@ -68,14 +68,14 @@ QQuickMaskExtruder::QQuickMaskExtruder(QObject *parent) : { } -void QQuickMaskExtruder::setSource(QUrl arg) +void QQuickMaskExtruder::setSource(const QUrl &arg) { if (m_source != arg) { m_source = arg; m_lastHeight = -1;//Trigger reset m_lastWidth = -1; - emit sourceChanged(arg); + emit sourceChanged(m_source); startMaskLoading(); } } diff --git a/src/particles/qquickmaskextruder_p.h b/src/particles/qquickmaskextruder_p.h index 62c8c3f04b..419d162811 100644 --- a/src/particles/qquickmaskextruder_p.h +++ b/src/particles/qquickmaskextruder_p.h @@ -74,10 +74,10 @@ public: Q_SIGNALS: - void sourceChanged(QUrl arg); + void sourceChanged(const QUrl &arg); public Q_SLOTS: - void setSource(QUrl arg); + void setSource(const QUrl &arg); private Q_SLOTS: void startMaskLoading(); diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp index 2d5282b48c..cc663cd6b3 100644 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp @@ -506,7 +506,7 @@ void QQmlDebugServerImpl::receiveMessage() in >> m_clientPlugins; for (DebugServiceConstIt iter = m_plugins.constBegin(), cend = m_plugins.constEnd(); iter != cend; ++iter) { - const QString pluginName = iter.key(); + const QString &pluginName = iter.key(); QQmlDebugService::State newState = QQmlDebugService::Unavailable; if (m_clientPlugins.contains(pluginName)) newState = QQmlDebugService::Enabled; diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index fbb6a07b1b..940d61ba97 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -971,7 +971,7 @@ QStringRef IRBuilder::asStringRef(QQmlJS::AST::Node *node) return textRefAt(node->firstSourceLocation(), node->lastSourceLocation()); } -void IRBuilder::extractVersion(QStringRef string, int *maj, int *min) +void IRBuilder::extractVersion(const QStringRef &string, int *maj, int *min) { *maj = -1; *min = -1; diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index c366c8e459..4279f5b768 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -453,7 +453,7 @@ public: static QString asString(QQmlJS::AST::UiQualifiedId *node); QStringRef asStringRef(QQmlJS::AST::Node *node); - static void extractVersion(QStringRef string, int *maj, int *min); + static void extractVersion(const QStringRef &string, int *maj, int *min); QStringRef textRefAt(const QQmlJS::AST::SourceLocation &loc) const { return QStringRef(&sourceCode, loc.offset, loc.length); } QStringRef textRefAt(const QQmlJS::AST::SourceLocation &first, diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index b083012eab..b2d322465d 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -628,8 +628,7 @@ */ /*! - \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int - versionMinor, const char *typeName, QObject* cppObject) + \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject* cppObject) \relates QQmlEngine \since 5.14 diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 5616b1450b..520b715189 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -601,8 +601,7 @@ static inline double ParseString(const QString &s, double localTZA) QStringLiteral("d MMMM, yyyy hh:mm:ss"), }; - for (uint i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) { - const QString &format(formats[i]); + for (const QString &format : formats) { dt = format.indexOf(QLatin1String("hh:mm")) < 0 ? QDateTime(QDate::fromString(s, format), QTime(0, 0, 0), Qt::UTC) diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index a3ca48d6d9..cfbe0c409e 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -79,6 +79,13 @@ int qmlTypeId(const char *uri, int versionMajor, int versionMinor, const char *q // From qqmlprivate.h QObject *QQmlPrivate::RegisterSingletonFunctor::operator()(QQmlEngine *qeng, QJSEngine *) { + if (!m_object) { + QQmlError error; + error.setDescription(QLatin1String("The registered singleton has already been deleted. Ensure that it outlives the engine.")); + QQmlEnginePrivate::get(qeng)->warning(qeng, error); + return nullptr; + } + if (qeng->thread() != m_object->thread()) { QQmlError error; error.setDescription(QLatin1String("Registered object must live in the same thread as the engine it was registered with")); diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 668f00b136..254b6cc3db 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -358,7 +358,7 @@ void QQmlContext::setContextProperties(const QVector<PropertyPair> &properties) data->expressions = nullptr; data->childContexts = nullptr; - for (auto property : properties) + for (const auto &property : properties) setContextProperty(property.name, property.value); data->expressions = expressions; diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp index 2183721d32..750fc6de50 100644 --- a/src/qml/qml/qqmldatablob.cpp +++ b/src/qml/qml/qqmldatablob.cpp @@ -351,7 +351,7 @@ void QQmlDataBlob::addDependency(QQmlDataBlob *blob) status() == Error || status() == Complete || m_isDone) return; - for (auto existingDep: qAsConst(m_waitingFor)) + for (const auto &existingDep: qAsConst(m_waitingFor)) if (existingDep.data() == blob) return; diff --git a/src/qml/qml/qqmldirdata.cpp b/src/qml/qml/qqmldirdata.cpp index 7652cec322..de74dfdf9b 100644 --- a/src/qml/qml/qqmldirdata.cpp +++ b/src/qml/qml/qqmldirdata.cpp @@ -61,7 +61,7 @@ QQmlTypeLoader::Blob::PendingImportPtr QQmlQmldirData::import(QQmlTypeLoader::Bl void QQmlQmldirData::setImport(QQmlTypeLoader::Blob *blob, QQmlTypeLoader::Blob::PendingImportPtr import) { - m_imports[blob] = import; + m_imports[blob] = std::move(import); } int QQmlQmldirData::priority(QQmlTypeLoader::Blob *blob) const diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 5feea9daa8..8b5e11c890 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -780,12 +780,12 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt typeStr + dotqml_string, // Type -> Type.qml typeStr + dotuidotqml_string // Type -> Type.ui.qml }; - for (uint i = 0; i < sizeof(urlsToTry) / sizeof(urlsToTry[0]); ++i) { - exists = typeLoader->fileExists(localDirectoryPath, urlsToTry[i]); + for (const QString &urlToTry : urlsToTry) { + exists = typeLoader->fileExists(localDirectoryPath, urlToTry); if (exists) { #if defined(Q_OS_MACOS) || defined(Q_OS_WIN) // don't let function.qml confuse the use of "new Function(...)" for example. - if (!QQml_isFileCaseCorrect(localDirectoryPath + urlsToTry[i])) { + if (!QQml_isFileCaseCorrect(localDirectoryPath + urlToTry)) { exists = false; if (errors) { QQmlError caseError; @@ -797,7 +797,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt #else Q_UNUSED(errors); #endif - qmlUrl = url + urlsToTry[i]; + qmlUrl = url + urlToTry; break; } } diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp index 41a7778da3..775bc8bdb4 100644 --- a/src/qml/qml/qqmlmetatypedata.cpp +++ b/src/qml/qml/qqmlmetatypedata.cpp @@ -150,7 +150,7 @@ QQmlPropertyCache *QQmlMetaTypeData::propertyCache(const QQmlType &type, int min bool hasCopied = false; for (int ii = 0; ii < types.count(); ++ii) { - QQmlType currentType = types.at(ii); + const QQmlType ¤tType = types.at(ii); if (!currentType.isValid()) continue; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index dfcab6181d..cf1795aafa 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -446,6 +446,8 @@ void QQmlObjectCreator::setPropertyValue(const QQmlPropertyData *property, const QV4::ScopedString s(scope, v4->newString(stringValue)); _vmeMetaObject->setVMEProperty(property->coreIndex(), s); } else { + // ### Qt 6: Doing the conversion here where we don't know the eventual target type is rather strange + // and caused for instance QTBUG-78943 QVariant value = QQmlStringConverters::variantFromString(stringValue); property->writeProperty(_qobject, &value, propertyWriteFlags); } diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index 8111178320..27dac71571 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -62,6 +62,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qvariant.h> #include <QtCore/qurl.h> +#include <QPointer> #include <QtCore/qmetaobject.h> #include <QtCore/qdebug.h> @@ -489,7 +490,7 @@ namespace QQmlPrivate { QObject *operator()(QQmlEngine *, QJSEngine *); - QObject *m_object; + QPointer<QObject> m_object; bool alreadyCalled = false; }; diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 94bf3cbdc3..39778aa328 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -585,13 +585,13 @@ public: QQmlPropertyCacheAliasCreator(QQmlPropertyCacheVector *propertyCaches, const ObjectContainer *objectContainer); - void appendAliasPropertiesToMetaObjects(); + void appendAliasPropertiesToMetaObjects(QQmlEnginePrivate *enginePriv); - QQmlJS::DiagnosticMessage appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex); + QQmlJS::DiagnosticMessage appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv); private: - void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex); - QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags); + void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv); + QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv); void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const; @@ -610,7 +610,7 @@ inline QQmlPropertyCacheAliasCreator<ObjectContainer>::QQmlPropertyCacheAliasCre } template <typename ObjectContainer> -inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertiesToMetaObjects() +inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertiesToMetaObjects(QQmlEnginePrivate *enginePriv) { // skip the root object (index 0) as that one does not have a first object index originating // from a binding. @@ -620,15 +620,15 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertie continue; const auto rootBinding = component.bindingsBegin(); - appendAliasPropertiesInMetaObjectsWithinComponent(component, rootBinding->value.objectIndex); + appendAliasPropertiesInMetaObjectsWithinComponent(component, rootBinding->value.objectIndex, enginePriv); } const int rootObjectIndex = 0; - appendAliasPropertiesInMetaObjectsWithinComponent(*objectContainer->objectAt(rootObjectIndex), rootObjectIndex); + appendAliasPropertiesInMetaObjectsWithinComponent(*objectContainer->objectAt(rootObjectIndex), rootObjectIndex, enginePriv); } template <typename ObjectContainer> -inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex) +inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex, QQmlEnginePrivate *enginePriv) { QVector<int> objectsWithAliases; collectObjectsWithAliasesRecursively(firstObjectIndex, &objectsWithAliases); @@ -668,7 +668,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasPropertie const CompiledObject &object = *objectContainer->objectAt(objectIndex); if (allAliasTargetsExist(object)) { - appendAliasesToPropertyCache(component, objectIndex); + appendAliasesToPropertyCache(component, objectIndex, enginePriv); } else { pendingObjects.append(objectIndex); } @@ -702,9 +702,8 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl } template <typename ObjectContainer> -inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias( - const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion, - QQmlPropertyData::Flags *propertyFlags) +inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion, + QQmlPropertyData::Flags *propertyFlags, QQmlEnginePrivate *enginePriv) { *type = 0; bool writable = false; @@ -736,7 +735,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: lastAlias = targetAlias; } while (lastAlias->aliasToLocalAlias); - return propertyDataForAlias(component, *lastAlias, type, minorVersion, propertyFlags); + return propertyDataForAlias(component, *lastAlias, type, minorVersion, propertyFlags, enginePriv); } const int targetObjectIndex = objectForId(component, alias.targetObjectId); @@ -768,29 +767,46 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: QQmlPropertyCache *targetCache = propertyCaches->at(targetObjectIndex); Q_ASSERT(targetCache); + QQmlPropertyData *targetProperty = targetCache->property(coreIndex); Q_ASSERT(targetProperty); - *type = targetProperty->propType(); + // for deep aliases, valueTypeIndex is always set + if (!QQmlValueTypeFactory::isValueType(targetProperty->propType()) && valueTypeIndex != -1) { + // deep alias property + *type = targetProperty->propType(); + targetCache = enginePriv->propertyCacheForType(*type); + Q_ASSERT(targetCache); + targetProperty = targetCache->property(valueTypeIndex); - writable = targetProperty->isWritable(); - resettable = targetProperty->isResettable(); - if (valueTypeIndex != -1) { - const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(*type); - if (valueTypeMetaObject->property(valueTypeIndex).isEnumType()) - *type = QVariant::Int; - else - *type = valueTypeMetaObject->property(valueTypeIndex).userType(); + *type = targetProperty->propType(); + writable = targetProperty->isWritable(); + resettable = targetProperty->isResettable(); + } else { - if (targetProperty->isEnum()) { - *type = QVariant::Int; + // value type or primitive type or enum + *type = targetProperty->propType(); + + writable = targetProperty->isWritable(); + resettable = targetProperty->isResettable(); + + if (valueTypeIndex != -1) { + const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(*type); + if (valueTypeMetaObject->property(valueTypeIndex).isEnumType()) + *type = QVariant::Int; + else + *type = valueTypeMetaObject->property(valueTypeIndex).userType(); } else { - // Copy type flags - propertyFlags->copyPropertyTypeFlags(targetProperty->flags()); + if (targetProperty->isEnum()) { + *type = QVariant::Int; + } else { + // Copy type flags + propertyFlags->copyPropertyTypeFlags(targetProperty->flags()); - if (targetProperty->isVarProperty()) - propertyFlags->type = QQmlPropertyData::Flags::QVariantType; + if (targetProperty->isVarProperty()) + propertyFlags->type = QQmlPropertyData::Flags::QVariantType; + } } } } @@ -802,7 +818,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: template <typename ObjectContainer> inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache( - const CompiledObject &component, int objectIndex) + const CompiledObject &component, int objectIndex, QQmlEnginePrivate *enginePriv) { const CompiledObject &object = *objectContainer->objectAt(objectIndex); if (!object.aliasCount()) @@ -823,7 +839,7 @@ inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>: int type = 0; int minorVersion = 0; QQmlPropertyData::Flags propertyFlags; - QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags); + QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags, enginePriv); if (error.isValid()) return error; diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 3615749da1..2db3ad6b2a 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -393,7 +393,7 @@ void QQmlTypePrivate::createEnumConflictReport(const QMetaObject *metaObject, co qWarning().noquote() << QLatin1String("Possible conflicting items:"); // find items with conflicting key - for (const auto i : enumInfoList) { + for (const auto &i : qAsConst(enumInfoList)) { if (i.enumKey == conflictingKey) qWarning().noquote().nospace() << " " << i.metaObjectName << "." << i.enumName << "." << i.enumKey << " from scope " << i.metaEnumScope << " injected by " << i.path.join(QLatin1String("->")); diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index bbeaf7be9a..9ff0e3fb9e 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -1016,7 +1016,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex) } if (result == AllAliasesResolved) { - QQmlJS::DiagnosticMessage error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex); + QQmlJS::DiagnosticMessage error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex, enginePrivate); if (error.isValid()) { recordError(error); return false; @@ -1143,23 +1143,42 @@ QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, if (!subProperty.isEmpty()) { const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(targetProperty->propType()); if (!valueTypeMetaObject) { - *error = qQmlCompileError( - alias->referenceLocation, - tr("Invalid alias target location: %1").arg(subProperty.toString())); - break; - } + // could be a deep alias + bool isDeepAlias = subProperty.at(0).isLower(); + if (isDeepAlias) { + isDeepAlias = false; + for (auto it = targetObject->bindingsBegin(); it != targetObject->bindingsEnd(); ++it) { + auto binding = *it; + if (compiler->stringAt(binding.propertyNameIndex) == property) { + resolver = QQmlPropertyResolver(propertyCaches.at(binding.value.objectIndex)); + QQmlPropertyData *actualProperty = resolver.property(subProperty.toString()); + if (actualProperty) { + propIdx = QQmlPropertyIndex(propIdx.coreIndex(), actualProperty->coreIndex()); + isDeepAlias = true; + } + } + } + } + if (!isDeepAlias) { + *error = qQmlCompileError( + alias->referenceLocation, + tr("Invalid alias target location: %1").arg(subProperty.toString())); + break; + } + } else { - int valueTypeIndex = - valueTypeMetaObject->indexOfProperty(subProperty.toString().toUtf8().constData()); - if (valueTypeIndex == -1) { - *error = qQmlCompileError( - alias->referenceLocation, - tr("Invalid alias target location: %1").arg(subProperty.toString())); - break; - } - Q_ASSERT(valueTypeIndex <= 0x0000FFFF); + int valueTypeIndex = + valueTypeMetaObject->indexOfProperty(subProperty.toString().toUtf8().constData()); + if (valueTypeIndex == -1) { + *error = qQmlCompileError( + alias->referenceLocation, + tr("Invalid alias target location: %1").arg(subProperty.toString())); + break; + } + Q_ASSERT(valueTypeIndex <= 0x0000FFFF); - propIdx = QQmlPropertyIndex(propIdx.coreIndex(), valueTypeIndex); + propIdx = QQmlPropertyIndex(propIdx.coreIndex(), valueTypeIndex); + } } else { if (targetProperty->isQObject()) alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index 99fe069685..cfdcf6aad5 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -209,7 +209,7 @@ void QQmlTypeData::createTypeAndPropertyCaches( QQmlPropertyCacheAliasCreator<QV4::ExecutableCompilationUnit> aliasCreator( &m_compiledData->propertyCaches, m_compiledData.data()); - aliasCreator.appendAliasPropertiesToMetaObjects(); + aliasCreator.appendAliasPropertiesToMetaObjects(engine); pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_compiledData->propertyCaches); } diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 42e7d2c4b4..62007effdd 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -491,7 +491,7 @@ bool QQmlTypeLoader::Blob::fetchQmldir(const QUrl &url, PendingImportPtr import, { QQmlRefPointer<QQmlQmldirData> data = typeLoader()->getQmldir(url); - data->setImport(this, import); + data->setImport(this, std::move(import)); data->setPriority(this, priority); if (data->status() == Error) { diff --git a/src/qml/qml/qqmltypeloaderqmldircontent.cpp b/src/qml/qml/qqmltypeloaderqmldircontent.cpp index 238af9b710..8e983db756 100644 --- a/src/qml/qml/qqmltypeloaderqmldircontent.cpp +++ b/src/qml/qml/qqmltypeloaderqmldircontent.cpp @@ -55,7 +55,8 @@ QList<QQmlError> QQmlTypeLoaderQmldirContent::errors(const QString &uri) const { QList<QQmlError> errors; const QUrl url(uri); - for (const auto parseError : m_parser.errors(uri)) { + const auto parseErrors = m_parser.errors(uri); + for (const auto &parseError : parseErrors) { QQmlError error; error.setUrl(url); error.setLine(parseError.line); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index a67ac7384d..9b5490b6e5 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -164,8 +164,19 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() QQmlData *targetDData = QQmlData::get(target, /*create*/false); if (!targetDData) return; - int coreIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex).coreIndex(); + QQmlPropertyIndex encodedIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex); + int coreIndex = encodedIndex.coreIndex(); + int valueTypeIndex = encodedIndex.valueTypeIndex(); const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex); + if (pd && valueTypeIndex != -1 && !QQmlValueTypeFactory::valueType(pd->propType())) { + // deep alias + QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(metaObject->compilationUnit->engine->qmlEngine()); + auto const *newPropertyCache = enginePriv->propertyCacheForType(pd->propType()); + void *argv[1] = { &target }; + QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv); + Q_ASSERT(newPropertyCache); + pd = newPropertyCache->property(valueTypeIndex); + } if (!pd) return; @@ -858,17 +869,23 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * if (!targetDData->propertyCache) return -1; const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex); - // Value type property + // Value type property or deep alias QQmlValueType *valueType = QQmlValueTypeFactory::valueType(pd->propType()); - Q_ASSERT(valueType); + if (valueType) { - valueType->read(target, coreIndex); - int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a); + valueType->read(target, coreIndex); + int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a); - if (c == QMetaObject::WriteProperty) - valueType->write(target, coreIndex, nullptr); + if (c == QMetaObject::WriteProperty) + valueType->write(target, coreIndex, nullptr); - return rv; + return rv; + } else { + // deep alias + void *argv[1] = { &target }; + QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv); + return QMetaObject::metacall(target, c, valueTypePropertyIndex, a); + } } else { return QMetaObject::metacall(target, c, coreIndex, a); diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 9d305cd24c..36de16a818 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -78,7 +78,7 @@ public: QQmlNullableValue<bool> when; QPointer<QObject> obj; QString propName; - QQmlNullableValue<QVariant> value; + QQmlNullableValue<QJSValue> value; QQmlProperty prop; QQmlAbstractBinding::Ptr prevBind; QV4::PersistentValue v4Value; @@ -293,13 +293,13 @@ void QQmlBind::setProperty(const QString &p) The value to be set on the target object and property. This can be a constant (which isn't very useful), or a bound expression. */ -QVariant QQmlBind::value() const +QJSValue QQmlBind::value() const { Q_D(const QQmlBind); return d->value.value; } -void QQmlBind::setValue(const QVariant &v) +void QQmlBind::setValue(const QJSValue &v) { Q_D(QQmlBind); d->value = v; @@ -359,7 +359,8 @@ void QQmlBind::setDelayed(bool delayed) \li Binding.RestoreBindingOrValue The original value is always restored. \endlist - The default value is Binding.RestoreBinding. + \warning The default value is Binding.RestoreBinding. This will change in + Qt 5.15 to Binding.RestoreBindingOrValue. If you rely on any specific behavior regarding the restoration of plain values when bindings get disabled you should migrate to explicitly set the @@ -456,11 +457,23 @@ void QQmlBind::eval() Q_ASSERT(vmemo); vmemo->setVMEProperty(propPriv->core.coreIndex(), *d->v4Value.valueRef()); d->clearPrev(); + } else if (!d->restoreModeExplicit) { + qmlWarning(this) + << "Not restoring previous value because restoreMode has not been set." + << "This behavior is deprecated." + << "In Qt < 5.15 the default is Binding.RestoreBinding." + << "In Qt >= 5.15 the default is Binding.RestoreBindingOrValue."; } } else if (d->prevIsVariant) { if (d->restoreValue) { d->prop.write(d->prevValue); d->clearPrev(); + } else if (!d->restoreModeExplicit) { + qmlWarning(this) + << "Not restoring previous value because restoreMode has not been set." + << "This behavior is deprecated." + << "In Qt < 5.15 the default is Binding.RestoreBinding." + << "In Qt >= 5.15 the default is Binding.RestoreBindingOrValue."; } } return; @@ -489,7 +502,7 @@ void QQmlBind::eval() QQmlPropertyPrivate::removeBinding(d->prop); } - d->prop.write(d->value.value); + d->prop.write(d->value.value.toVariant()); } QT_END_NAMESPACE diff --git a/src/qml/types/qqmlbind_p.h b/src/qml/types/qqmlbind_p.h index e7c7e01a0d..a100b1552c 100644 --- a/src/qml/types/qqmlbind_p.h +++ b/src/qml/types/qqmlbind_p.h @@ -75,7 +75,7 @@ private: Q_INTERFACES(QQmlPropertyValueSource) Q_PROPERTY(QObject *target READ object WRITE setObject) Q_PROPERTY(QString property READ property WRITE setProperty) - Q_PROPERTY(QVariant value READ value WRITE setValue) + Q_PROPERTY(QJSValue value READ value WRITE setValue) Q_PROPERTY(bool when READ when WRITE setWhen) Q_PROPERTY(bool delayed READ delayed WRITE setDelayed REVISION 8) Q_PROPERTY(RestorationMode restoreMode READ restoreMode WRITE setRestoreMode @@ -96,8 +96,8 @@ public: QString property() const; void setProperty(const QString &); - QVariant value() const; - void setValue(const QVariant &); + QJSValue value() const; + void setValue(const QJSValue &); bool delayed() const; void setDelayed(bool); diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp index 0afc9997aa..f404788de4 100644 --- a/src/quick/handlers/qquickmultipointhandler.cpp +++ b/src/quick/handlers/qquickmultipointhandler.cpp @@ -364,7 +364,7 @@ void QQuickMultiPointHandler::acceptPoints(const QVector<QQuickEventPoint *> &po point->setAccepted(); } -bool QQuickMultiPointHandler::grabPoints(QVector<QQuickEventPoint *> points) +bool QQuickMultiPointHandler::grabPoints(const QVector<QQuickEventPoint *> &points) { if (points.isEmpty()) return false; diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h index eeb4b13b83..480f69035b 100644 --- a/src/quick/handlers/qquickmultipointhandler_p.h +++ b/src/quick/handlers/qquickmultipointhandler_p.h @@ -107,7 +107,7 @@ protected: QVector<PointData> angles(const QPointF &ref) const; static qreal averageAngleDelta(const QVector<PointData> &old, const QVector<PointData> &newAngles); void acceptPoints(const QVector<QQuickEventPoint *> &points); - bool grabPoints(QVector<QQuickEventPoint *> points); + bool grabPoints(const QVector<QQuickEventPoint *> &points); void moveTarget(QPointF pos); Q_DECLARE_PRIVATE(QQuickMultiPointHandler) diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index 18adb4e992..d22e77c8ad 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -532,7 +532,7 @@ void QQuickAnimatedSprite::setInterpolate(bool arg) } } -void QQuickAnimatedSprite::setSource(QUrl arg) +void QQuickAnimatedSprite::setSource(const QUrl &arg) { Q_D(QQuickAnimatedSprite); diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index ff5002334e..30f64e9def 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -123,7 +123,7 @@ Q_SIGNALS: void runningChanged(bool arg); void interpolateChanged(bool arg); - void sourceChanged(QUrl arg); + void sourceChanged(const QUrl &arg); void reverseChanged(bool arg); void frameSyncChanged(bool arg); void frameCountChanged(int arg); @@ -149,7 +149,7 @@ public Q_SLOTS: void setRunning(bool arg); void setPaused(bool arg); void setInterpolate(bool arg); - void setSource(QUrl arg); + void setSource(const QUrl &arg); void setReverse(bool arg); void setFrameSync(bool arg); void setFrameCount(int arg); diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index 0fd7df8938..e217fdb5d0 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -189,8 +189,8 @@ class MappedSlotObject: public QtPrivate::QSlotObjectBase public: typedef std::function<void()> PropChangedFunc; - explicit MappedSlotObject(PropChangedFunc func) - : QSlotObjectBase(&impl), _signalIndex(-1), func(func) + explicit MappedSlotObject(PropChangedFunc f) + : QSlotObjectBase(&impl), _signalIndex(-1), func(std::move(f)) { ref(); } void setSignalIndex(int idx) { _signalIndex = idx; } diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp index fe1dfd349e..31d1c91649 100644 --- a/src/quick/items/qquickstateoperations.cpp +++ b/src/quick/items/qquickstateoperations.cpp @@ -200,7 +200,7 @@ QQmlScriptString QQuickParentChange::x() const return d->xString.value; } -void QQuickParentChange::setX(QQmlScriptString x) +void QQuickParentChange::setX(const QQmlScriptString &x) { Q_D(QQuickParentChange); d->xString = x; @@ -218,7 +218,7 @@ QQmlScriptString QQuickParentChange::y() const return d->yString.value; } -void QQuickParentChange::setY(QQmlScriptString y) +void QQuickParentChange::setY(const QQmlScriptString &y) { Q_D(QQuickParentChange); d->yString = y; @@ -236,7 +236,7 @@ QQmlScriptString QQuickParentChange::width() const return d->widthString.value; } -void QQuickParentChange::setWidth(QQmlScriptString width) +void QQuickParentChange::setWidth(const QQmlScriptString &width) { Q_D(QQuickParentChange); d->widthString = width; @@ -254,7 +254,7 @@ QQmlScriptString QQuickParentChange::height() const return d->heightString.value; } -void QQuickParentChange::setHeight(QQmlScriptString height) +void QQuickParentChange::setHeight(const QQmlScriptString &height) { Q_D(QQuickParentChange); d->heightString = height; @@ -272,7 +272,7 @@ QQmlScriptString QQuickParentChange::scale() const return d->scaleString.value; } -void QQuickParentChange::setScale(QQmlScriptString scale) +void QQuickParentChange::setScale(const QQmlScriptString &scale) { Q_D(QQuickParentChange); d->scaleString = scale; @@ -290,7 +290,7 @@ QQmlScriptString QQuickParentChange::rotation() const return d->rotationString.value; } -void QQuickParentChange::setRotation(QQmlScriptString rotation) +void QQuickParentChange::setRotation(const QQmlScriptString &rotation) { Q_D(QQuickParentChange); d->rotationString = rotation; diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h index c207a055cd..d451dc6f77 100644 --- a/src/quick/items/qquickstateoperations_p.h +++ b/src/quick/items/qquickstateoperations_p.h @@ -88,27 +88,27 @@ public: QQuickItem *originalParent() const; QQmlScriptString x() const; - void setX(QQmlScriptString x); + void setX(const QQmlScriptString &x); bool xIsSet() const; QQmlScriptString y() const; - void setY(QQmlScriptString y); + void setY(const QQmlScriptString &y); bool yIsSet() const; QQmlScriptString width() const; - void setWidth(QQmlScriptString width); + void setWidth(const QQmlScriptString &width); bool widthIsSet() const; QQmlScriptString height() const; - void setHeight(QQmlScriptString height); + void setHeight(const QQmlScriptString &height); bool heightIsSet() const; QQmlScriptString scale() const; - void setScale(QQmlScriptString scale); + void setScale(const QQmlScriptString &scale); bool scaleIsSet() const; QQmlScriptString rotation() const; - void setRotation(QQmlScriptString rotation); + void setRotation(const QQmlScriptString &rotation); bool rotationIsSet() const; ActionList actions() override; diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 95fac30808..295c6898bc 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -2582,7 +2582,7 @@ QJSValue QQuickTableView::rowHeightProvider() const return d_func()->rowHeightProvider; } -void QQuickTableView::setRowHeightProvider(QJSValue provider) +void QQuickTableView::setRowHeightProvider(const QJSValue &provider) { Q_D(QQuickTableView); if (provider.strictlyEquals(d->rowHeightProvider)) @@ -2598,7 +2598,7 @@ QJSValue QQuickTableView::columnWidthProvider() const return d_func()->columnWidthProvider; } -void QQuickTableView::setColumnWidthProvider(QJSValue provider) +void QQuickTableView::setColumnWidthProvider(const QJSValue &provider) { Q_D(QQuickTableView); if (provider.strictlyEquals(d->columnWidthProvider)) diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h index 2208891f50..5ef73a816f 100644 --- a/src/quick/items/qquicktableview_p.h +++ b/src/quick/items/qquicktableview_p.h @@ -99,10 +99,10 @@ public: void setColumnSpacing(qreal spacing); QJSValue rowHeightProvider() const; - void setRowHeightProvider(QJSValue provider); + void setRowHeightProvider(const QJSValue &provider); QJSValue columnWidthProvider() const; - void setColumnWidthProvider(QJSValue provider); + void setColumnWidthProvider(const QJSValue &provider); virtual QVariant model() const; virtual void setModel(const QVariant &newModel); diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index ab3b0c4605..127b3c3516 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -1397,7 +1397,7 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property) cons return inputMethodQuery(property, QVariant()); } -QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const +QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, const QVariant &argument) const { Q_D(const QQuickTextControl); QTextBlock block = d->cursor.block(); diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h index 3c7d48f918..41b8ed7821 100644 --- a/src/quick/items/qquicktextcontrol_p.h +++ b/src/quick/items/qquicktextcontrol_p.h @@ -174,7 +174,7 @@ public: #if QT_CONFIG(im) virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const; - Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const; + Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const; #endif virtual QMimeData *createMimeDataFromSelection() const; diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index b1ad6a1c15..34105d8c81 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1958,7 +1958,7 @@ QVariant QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery property) const return inputMethodQuery(property, QVariant()); } -QVariant QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const +QVariant QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery property, const QVariant &argument) const { Q_D(const QQuickTextInput); switch (property) { diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index e95717cf8c..9f7b82b168 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -269,7 +269,7 @@ public: #if QT_CONFIG(im) QVariant inputMethodQuery(Qt::InputMethodQuery property) const override; - Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const; + Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const; #endif QRectF boundingRect() const override; diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp index 7af90f0f8e..f8ebf13a1d 100644 --- a/src/quick/items/qquicktextnodeengine.cpp +++ b/src/quick/items/qquicktextnodeengine.cpp @@ -638,7 +638,7 @@ void QQuickTextNodeEngine::addBorder(const QRectF &rect, qreal border, QTextFrameFormat::BorderStyle borderStyle, const QBrush &borderBrush) { - QColor color = borderBrush.color(); + const QColor &color = borderBrush.color(); // Currently we don't support other styles than solid Q_UNUSED(borderStyle); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index d85188dbd6..3885700af8 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2768,7 +2768,7 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo // If the touch was accepted (regardless by whom or in what form), // update accepted new points. bool isPressOrRelease = pointerEvent->isPressEvent() || pointerEvent->isReleaseEvent(); - for (auto point: qAsConst(touchEvent->touchPoints())) { + for (const auto &point: qAsConst(touchEvent->touchPoints())) { if (auto pointerEventPoint = ptEvent->pointById(point.id())) { pointerEventPoint->setAccepted(); if (isPressOrRelease) @@ -2778,7 +2778,7 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo } else { // But if the event was not accepted then we know this item // will not be interested in further updates for those touchpoint IDs either. - for (auto point: qAsConst(touchEvent->touchPoints())) { + for (const auto &point: qAsConst(touchEvent->touchPoints())) { if (point.state() == Qt::TouchPointPressed) { if (auto *tp = ptEvent->pointById(point.id())) { if (tp->exclusiveGrabber() == item) { @@ -3019,7 +3019,7 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event if (filteringParent->childMouseEventFilter(receiver, filteringParentTouchEvent.data())) { qCDebug(DBG_TOUCH) << "touch event intercepted by childMouseEventFilter of " << filteringParent; skipDelivery.append(filteringParent); - for (auto point: qAsConst(filteringParentTouchEvent->touchPoints())) { + for (const auto &point: qAsConst(filteringParentTouchEvent->touchPoints())) { QQuickEventPoint *pt = event->pointById(point.id()); pt->setAccepted(); pt->setGrabberItem(filteringParent); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 29923b5d20..34027cbac7 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -187,7 +187,7 @@ static QRhiVertexInputLayout calculateVertexInputLayout(const QSGMaterialRhiShad } const int attrCount = geometry->attributeCount(); - QVector<QRhiVertexInputAttribute> inputAttributes; + QVarLengthArray<QRhiVertexInputAttribute, 8> inputAttributes; inputAttributes.reserve(attrCount + 1); int offset = 0; for (int i = 0; i < attrCount; ++i) { @@ -205,15 +205,14 @@ static QRhiVertexInputLayout calculateVertexInputLayout(const QSGMaterialRhiShad } Q_ASSERT(VERTEX_BUFFER_BINDING == 0 && ZORDER_BUFFER_BINDING == 1); // not very flexible - QVector<QRhiVertexInputBinding> inputBindings; - inputBindings.reserve(2); + QVarLengthArray<QRhiVertexInputBinding, 2> inputBindings; inputBindings.append(QRhiVertexInputBinding(geometry->sizeOfVertex())); if (batchable) inputBindings.append(QRhiVertexInputBinding(sizeof(float))); QRhiVertexInputLayout inputLayout; - inputLayout.setBindings(inputBindings); - inputLayout.setAttributes(inputAttributes); + inputLayout.setBindings(inputBindings.cbegin(), inputBindings.cend()); + inputLayout.setAttributes(inputAttributes.cbegin(), inputAttributes.cend()); return inputLayout; } @@ -2849,10 +2848,8 @@ void Renderer::updateClipState(const QSGClipNode *clipList, Batch *batch) // RHI else { if (qsg_topology(g->drawingMode()) != m_stencilClipCommon.topology) qWarning("updateClipState: Clip list entries have different primitive topologies, this is not currently supported."); -#if 0 // ### restore once the 5.14 submodule update is done - if (qsg_vertexInputFormat(*a) != m_stencilClipCommon.inputLayout.attributes().first().format()) + if (qsg_vertexInputFormat(*a) != m_stencilClipCommon.inputLayout.cbeginAttributes()->format()) qWarning("updateClipState: Clip list entries have different vertex input layouts, this is must not happen."); -#endif } #endif diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp index 28fc10e413..53b6fe117f 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp @@ -182,7 +182,9 @@ void QSGRhiDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &gly for (int i = 0; i < glyphs.size(); ++i) { TextureInfo *texInfo = m_glyphsTexture.value(glyphs.at(i).glyph()); if (!texInfo->uploads.isEmpty()) { - m_resourceUpdates->uploadTexture(texInfo->texture, texInfo->uploads); + QRhiTextureUploadDescription desc; + desc.setEntries(texInfo->uploads.cbegin(), texInfo->uploads.cend()); + m_resourceUpdates->uploadTexture(texInfo->texture, desc); texInfo->uploads.clear(); } } diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h index ddd3d92ba7..d43b0aa5d4 100644 --- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache_p.h @@ -88,7 +88,7 @@ private: QRect allocatedArea; QDistanceField image; int padding = -1; - QVector<QRhiTextureUploadEntry> uploads; + QVarLengthArray<QRhiTextureUploadEntry, 16> uploads; TextureInfo(const QRect &preallocRect = QRect()) : texture(nullptr), allocatedArea(preallocRect) { } }; diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp index 99761302e2..d0108bc56e 100644 --- a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp +++ b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp @@ -223,7 +223,9 @@ void QSGRhiTextureGlyphCache::endFillTexture() if (!m_resourceUpdates) m_resourceUpdates = m_rhi->nextResourceUpdateBatch(); - m_resourceUpdates->uploadTexture(m_texture, m_uploads); + QRhiTextureUploadDescription desc; + desc.setEntries(m_uploads.cbegin(), m_uploads.cend()); + m_resourceUpdates->uploadTexture(m_texture, desc); m_uploads.clear(); } diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h index 75d82de90d..a7374d91a4 100644 --- a/src/quick/scenegraph/qsgrhitextureglyphcache_p.h +++ b/src/quick/scenegraph/qsgrhitextureglyphcache_p.h @@ -90,7 +90,7 @@ private: QRhiTexture *m_texture = nullptr; QSize m_size; bool m_bgra = false; - QVector<QRhiTextureUploadEntry> m_uploads; + QVarLengthArray<QRhiTextureUploadEntry, 16> m_uploads; QSet<QRhiTexture *> m_pendingDispose; }; diff --git a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp index 665e9bb412..3dc1f5f526 100644 --- a/src/quick/scenegraph/util/qsgrhiatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgrhiatlastexture.cpp @@ -295,8 +295,7 @@ void Atlas::enqueueTextureUpload(TextureBase *t, QRhiResourceUpdateBatch *resour const int tmpBitsSize = tmpBits.size() * 4; const quint32 *src = reinterpret_cast<const quint32 *>(image.constBits()); quint32 *dst = tmpBits.data(); - QVector<QRhiTextureUploadEntry> entries; - entries.reserve(5); + QVarLengthArray<QRhiTextureUploadEntry, 5> entries; // top row, padding corners dst[0] = src[0]; @@ -361,7 +360,9 @@ void Atlas::enqueueTextureUpload(TextureBase *t, QRhiResourceUpdateBatch *resour entries.append(QRhiTextureUploadEntry(0, 0, subresDesc)); } - resourceUpdates->uploadTexture(m_texture, QRhiTextureUploadDescription(entries)); + QRhiTextureUploadDescription desc; + desc.setEntries(entries.cbegin(), entries.cend()); + resourceUpdates->uploadTexture(m_texture, desc); const QSize textureSize = t->textureSize(); if (textureSize.width() > m_atlas_transient_image_threshold || textureSize.height() > m_atlas_transient_image_threshold) diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 2043b50545..fe5b372da8 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -2636,7 +2636,7 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA for (int j = 0; j < targets.count(); ++j) { QQuickStateAction myAction; QString errorMessage; - const QString propertyName = props.at(i); + const QString &propertyName = props.at(i); myAction.property = d->createProperty(targets.at(j), propertyName, this, &errorMessage); if (myAction.property.isValid()) { if (usingDefaultProperties) diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index 730a14369e..5d227b4613 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -216,7 +216,7 @@ void QQuickShortcut::setSequences(const QVariantList &values) bool changed = !remainder.isEmpty(); for (int i = 0; i < values.count(); ++i) { - QVariant value = values.at(i); + const QVariant &value = values.at(i); Shortcut& shortcut = m_shortcuts[i]; if (value == shortcut.userValue) continue; diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp index 0adae82dcc..46e7d62fc1 100644 --- a/src/quick/util/qquickstategroup.cpp +++ b/src/quick/util/qquickstategroup.cpp @@ -311,7 +311,7 @@ void QQuickStateGroup::componentComplete() if (!state->isNamed()) state->setName(QLatin1String("anonymousState") + QString::number(++d->unnamedCount)); - const QString stateName = state->name(); + QString stateName = state->name(); if (names.contains(stateName)) { qmlWarning(state->parent()) << "Found duplicate state name: " << stateName; } else { diff --git a/src/quickshapes/qquickshapenvprrenderer.cpp b/src/quickshapes/qquickshapenvprrenderer.cpp index a5b2a3467c..721091b669 100644 --- a/src/quickshapes/qquickshapenvprrenderer.cpp +++ b/src/quickshapes/qquickshapenvprrenderer.cpp @@ -177,7 +177,7 @@ QDebug operator<<(QDebug debug, const QQuickShapeNvprRenderer::NvprPath &path) debug << "Path with" << path.cmd.count() << "commands"; int ci = 0; for (GLubyte cmd : path.cmd) { - static struct { GLubyte cmd; const char *s; int coordCount; } nameTab[] = { + static struct { GLubyte cmd; const char *s; int coordCount; } nameTabs[] = { { GL_MOVE_TO_NV, "moveTo", 2 }, { GL_LINE_TO_NV, "lineTo", 2 }, { GL_QUADRATIC_CURVE_TO_NV, "quadTo", 4 }, @@ -187,14 +187,14 @@ QDebug operator<<(QDebug debug, const QQuickShapeNvprRenderer::NvprPath &path) { GL_SMALL_CW_ARC_TO_NV, "arcTo-small-CW", 5 }, { GL_SMALL_CCW_ARC_TO_NV, "arcTo-small-CCW", 5 }, { GL_CLOSE_PATH_NV, "closePath", 0 } }; - for (size_t i = 0; i < sizeof(nameTab) / sizeof(nameTab[0]); ++i) { - if (nameTab[i].cmd == cmd) { + for (const auto &nameTab : nameTabs) { + if (nameTab.cmd == cmd) { QByteArray cs; - for (int j = 0; j < nameTab[i].coordCount; ++j) { + for (int j = 0; j < nameTab.coordCount; ++j) { cs.append(QByteArray::number(path.coord[ci++])); cs.append(' '); } - debug << "\n " << nameTab[i].s << " " << cs; + debug << "\n " << nameTab.s << " " << cs; break; } } diff --git a/tests/auto/qml/qqmlbinding/data/noUnexpectedStringConversion.qml b/tests/auto/qml/qqmlbinding/data/noUnexpectedStringConversion.qml new file mode 100644 index 0000000000..d0f30c5da5 --- /dev/null +++ b/tests/auto/qml/qqmlbinding/data/noUnexpectedStringConversion.qml @@ -0,0 +1,30 @@ +import QtQuick 2.12 +import QtQuick.Window 2.12 + +Window { +visible: true +width: 640 +height: 480 +title: qsTr("Hello World") + + Rectangle { + id: colorRect + objectName: "colorRect" + anchors.fill: parent + Text { + objectName: "colorLabel" + id: colorLabel + } + } + + Binding { + target: colorLabel + property: "text" + value: "red" + } + Binding { + target: colorRect + property: "color" + value: "red" + } +} diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp index 9b66cd828a..2c2d311ff7 100644 --- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp +++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp @@ -55,6 +55,7 @@ private slots: void delayed(); void bindingOverwriting(); void bindToQmlComponent(); + void bindingDoesNoWeirdConversion(); private: QQmlEngine engine; @@ -68,7 +69,7 @@ void tst_qqmlbinding::binding() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("test-binding.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QScopedPointer<QQuickRectangle> rect { qobject_cast<QQuickRectangle*>(c.create()) }; QVERIFY(rect != nullptr); QQmlBind *binding3 = qobject_cast<QQmlBind*>(rect->findChild<QQmlBind*>("binding3")); @@ -85,18 +86,16 @@ void tst_qqmlbinding::binding() QQmlBind *binding = qobject_cast<QQmlBind*>(rect->findChild<QQmlBind*>("binding1")); QVERIFY(binding != nullptr); - QCOMPARE(binding->object(), qobject_cast<QObject*>(rect)); + QCOMPARE(binding->object(), qobject_cast<QObject*>(rect.get())); QCOMPARE(binding->property(), QLatin1String("text")); QCOMPARE(binding->value().toString(), QLatin1String("Hello")); - - delete rect; } void tst_qqmlbinding::whenAfterValue() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("test-binding2.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())}; QVERIFY(rect != nullptr); QCOMPARE(rect->color(), QColor("yellow")); @@ -104,15 +103,13 @@ void tst_qqmlbinding::whenAfterValue() rect->setProperty("changeColor", true); QCOMPARE(rect->color(), QColor("red")); - - delete rect; } void tst_qqmlbinding::restoreBinding() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("restoreBinding.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QScopedPointer<QQuickRectangle> rect { qobject_cast<QQuickRectangle*>(c.create()) }; QVERIFY(rect != nullptr); QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem")); @@ -134,8 +131,6 @@ void tst_qqmlbinding::restoreBinding() //original binding restored myItem->setY(49); QCOMPARE(myItem->x(), qreal(100-49)); - - delete rect; } void tst_qqmlbinding::restoreBindingValue() @@ -214,7 +209,7 @@ void tst_qqmlbinding::restoreBindingWithLoop() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("restoreBindingWithLoop.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())}; QVERIFY(rect != nullptr); QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem")); @@ -242,15 +237,13 @@ void tst_qqmlbinding::restoreBindingWithLoop() myItem->setY(49); QCOMPARE(myItem->x(), qreal(49 + 100)); - - delete rect; } void tst_qqmlbinding::restoreBindingWithoutCrash() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("restoreBindingWithoutCrash.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())}; QVERIFY(rect != nullptr); QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem")); @@ -281,8 +274,6 @@ void tst_qqmlbinding::restoreBindingWithoutCrash() //original binding restored myItem->setY(49); QCOMPARE(myItem->x(), qreal(100-49)); - - delete rect; } //QTBUG-20692 @@ -290,15 +281,13 @@ void tst_qqmlbinding::deletedObject() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("deletedObject.qml")); - QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create()); + QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())}; QVERIFY(rect != nullptr); QGuiApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); //don't crash rect->setProperty("activateBinding", true); - - delete rect; } void tst_qqmlbinding::warningOnUnknownProperty() @@ -307,9 +296,8 @@ void tst_qqmlbinding::warningOnUnknownProperty() QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("unknownProperty.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) }; QVERIFY(item); - delete item; QCOMPARE(messageHandler.messages().count(), 1); @@ -323,9 +311,8 @@ void tst_qqmlbinding::warningOnReadOnlyProperty() QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("readonlyProperty.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) }; QVERIFY(item); - delete item; QCOMPARE(messageHandler.messages().count(), 1); @@ -339,9 +326,8 @@ void tst_qqmlbinding::disabledOnUnknownProperty() QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("disabledUnknown.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) }; QVERIFY(item); - delete item; QCOMPARE(messageHandler.messages().count(), 0); } @@ -352,10 +338,8 @@ void tst_qqmlbinding::disabledOnReadonlyProperty() QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("disabledReadonly.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) }; QVERIFY(item); - delete item; - QCOMPARE(messageHandler.messages().count(), 0); } @@ -363,21 +347,19 @@ void tst_qqmlbinding::delayed() { QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("delayed.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QScopedPointer<QQuickItem> item {qobject_cast<QQuickItem*>(c.create())}; QVERIFY(item != nullptr); // update on creation QCOMPARE(item->property("changeCount").toInt(), 1); - QMetaObject::invokeMethod(item, "updateText"); + QMetaObject::invokeMethod(item.get(), "updateText"); // doesn't update immediately QCOMPARE(item->property("changeCount").toInt(), 1); QCoreApplication::processEvents(); // only updates once (non-delayed would update twice) QCOMPARE(item->property("changeCount").toInt(), 2); - - delete item; } void tst_qqmlbinding::bindingOverwriting() @@ -387,9 +369,8 @@ void tst_qqmlbinding::bindingOverwriting() QQmlEngine engine; QQmlComponent c(&engine, testFileUrl("bindingOverwriting.qml")); - QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QScopedPointer<QQuickItem> item {qobject_cast<QQuickItem*>(c.create())}; QVERIFY(item); - delete item; QLoggingCategory::setFilterRules(QString()); QCOMPARE(messageHandler.messages().count(), 2); @@ -402,6 +383,21 @@ void tst_qqmlbinding::bindToQmlComponent() QVERIFY(c.create()); } +// QTBUG-78943 +void tst_qqmlbinding::bindingDoesNoWeirdConversion() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("noUnexpectedStringConversion.qml")); + QScopedPointer<QObject> o {c.create()}; + QVERIFY(o); + QObject *colorRect = o->findChild<QObject*>("colorRect"); + QVERIFY(colorRect); + QCOMPARE(qvariant_cast<QColor>(colorRect->property("color")), QColorConstants::Red); + QObject *colorLabel = o->findChild<QObject*>("colorLabel"); + QCOMPARE(colorLabel->property("text").toString(), QLatin1String("red")); + QVERIFY(colorLabel); +} + QTEST_MAIN(tst_qqmlbinding) #include "tst_qqmlbinding.moc" diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index de99e8c37d..2a3b945509 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -1110,6 +1110,16 @@ void tst_qqmlengine::singletonInstance() SomeQObjectClass * instance = engine.singletonInstance<SomeQObjectClass*>(cppSingletonTypeId); QVERIFY(!instance); } + + { + // deleted object + auto dayfly = new QObject{}; + auto id = qmlRegisterSingletonInstance("Vanity", 1, 0, "Dayfly", dayfly); + delete dayfly; + QTest::ignoreMessage(QtMsgType::QtWarningMsg, "<Unknown File>: The registered singleton has already been deleted. Ensure that it outlives the engine."); + QObject *instance = engine.singletonInstance<QObject*>(id); + QVERIFY(!instance); + } } void tst_qqmlengine::aggressiveGc() diff --git a/tests/auto/qml/qqmllanguage/data/alias.17.qml b/tests/auto/qml/qqmllanguage/data/alias.17.qml new file mode 100644 index 0000000000..a76dd120b6 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/alias.17.qml @@ -0,0 +1,31 @@ +import QtQuick 2.12 + +Item { + id: root + anchors.fill: parent + width: 100 + height: 100 + property bool success: checkValue === aliasUser.topMargin + property int checkValue: 42 + Rectangle { + id: myItem + objectName: "myItem" + color: "blue" + anchors.topMargin: root.checkValue + width: 50 + height: 50 + Text {text: "source:\n" + myItem.anchors.topMargin} + } + + Rectangle { + property alias topMargin: myItem.anchors.topMargin + id: aliasUser + objectName: "aliasUser" + color: "red" + anchors.left: myItem.right + width: 50 + height: 50 + Text {objectName: "myText"; text: "alias:\n" + aliasUser.topMargin} + } +} + diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index ed3f7a5658..e2032c3b86 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -1991,6 +1991,69 @@ void tst_qqmllanguage::aliasProperties() QScopedPointer<QObject> object(component.create()); QVERIFY(!object.isNull()); } + + // Alias to grouped property + { + QQmlComponent component(&engine, testFileUrl("alias.17.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + QVERIFY(object->property("success").toBool()); + } + + // Alias to grouped property updates + { + QQmlComponent component(&engine, testFileUrl("alias.17.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + QObject *aliasUser = object->findChild<QObject*>(QLatin1String("aliasUser")); + QVERIFY(aliasUser); + QQmlProperty checkValueProp(object.get(), "checkValue"); + QVERIFY(checkValueProp.isValid()); + checkValueProp.write(777); + QCOMPARE(object->property("checkValue").toInt(), 777); + QCOMPARE(aliasUser->property("topMargin").toInt(), 777); + } + + // Write to alias to grouped property + { + QQmlComponent component(&engine, testFileUrl("alias.17.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + QObject *aliasUser = object->findChild<QObject*>(QLatin1String("aliasUser")); + QVERIFY(aliasUser); + QQmlProperty topMarginProp {aliasUser, "topMargin"}; + QVERIFY(topMarginProp.isValid()); + topMarginProp.write(777); + QObject *myItem = object->findChild<QObject*>(QLatin1String("myItem")); + QVERIFY(myItem); + auto anchors = myItem->property("anchors").value<QObject*>(); + QVERIFY(anchors); + QCOMPARE(anchors->property("topMargin").toInt(), 777); + } + + // Binding to alias to grouped property gets updated + { + QQmlComponent component(&engine, testFileUrl("alias.17.qml")); + VERIFY_ERRORS(0); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + QObject *aliasUser = object->findChild<QObject*>(QLatin1String("aliasUser")); + QVERIFY(aliasUser); + QQmlProperty topMarginProp {aliasUser, "topMargin"}; + QVERIFY(topMarginProp.isValid()); + topMarginProp.write(20); + QObject *myText = object->findChild<QObject*>(QLatin1String("myText")); + QVERIFY(myText); + auto text = myText->property("text").toString(); + QCOMPARE(text, "alias:\n20"); + } } // QTBUG-13374 Test that alias properties and signals can coexist |