aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-12 21:02:14 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-12 21:02:14 +0100
commit3f4496ecea2cb1cb773c899675a6ecd0ef6183d5 (patch)
treea55813fb4fbe24fe0b1e1446abe29fd0818df576
parent31e64606f253663f8ee2032b94521afd1804ab11 (diff)
parent4c689ad93d06bcfff5dfc4fdc41c69767aa04bee (diff)
Merge remote-tracking branch 'origin/5.11' into dev
-rw-r--r--.gitmodules1
-rw-r--r--src/3rdparty/masm/wtf/Compiler.h6
-rw-r--r--src/3rdparty/masm/wtf/Platform.h12
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h11
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator.cpp56
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator_p.h51
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp9
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h12
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h19
-rw-r--r--src/qml/doc/src/javascript/dynamicobjectcreation.qdoc2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp5
-rw-r--r--src/qml/memory/qv4mm.cpp25
-rw-r--r--src/qml/memory/qv4mm_p.h2
-rw-r--r--src/qml/qml/qqmlbinding.cpp14
-rw-r--r--src/qml/qml/qqmlbinding_p.h4
-rw-r--r--src/qml/qml/qqmlcomponent.cpp3
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp135
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h3
-rw-r--r--src/qml/qml/qqmlproperty.cpp5
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h19
-rw-r--r--src/qml/qml/qqmltypeloader.cpp8
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp10
-rw-r--r--src/quick/items/qquickevents.cpp3
-rw-r--r--src/quick/items/qquickitem.cpp7
m---------tests/auto/qml/ecmascripttests/test2620
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp12
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.15.qml12
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.16.qml15
-rw-r--r--tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.2.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp525
-rw-r--r--tests/auto/qml/qqmlproperty/data/aliasToIdWithMatchingQmlFileName.qml9
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp12
-rw-r--r--tests/auto/quick/qquickmousearea/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp154
35 files changed, 697 insertions, 485 deletions
diff --git a/.gitmodules b/.gitmodules
index c9561f396d..e6e5650150 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,4 @@
[submodule "tests/auto/qml/ecmascripttests/test262"]
path = tests/auto/qml/ecmascripttests/test262
url = ../qtdeclarative-testsuites.git
+ branch = snapshot-20150317-8f6a508-based
diff --git a/src/3rdparty/masm/wtf/Compiler.h b/src/3rdparty/masm/wtf/Compiler.h
index da10196cc1..598d7f2c1c 100644
--- a/src/3rdparty/masm/wtf/Compiler.h
+++ b/src/3rdparty/masm/wtf/Compiler.h
@@ -27,13 +27,13 @@
#define WTF_Compiler_h
/* COMPILER() - the compiler being used to build the project */
-#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE && WTF_COMPILER_##WTF_FEATURE)
+#define COMPILER(WTF_FEATURE) WTF_COMPILER_##WTF_FEATURE
/* COMPILER_SUPPORTS() - whether the compiler being used to build the project supports the given feature. */
-#define COMPILER_SUPPORTS(WTF_COMPILER_FEATURE) (defined WTF_COMPILER_SUPPORTS_##WTF_COMPILER_FEATURE && WTF_COMPILER_SUPPORTS_##WTF_COMPILER_FEATURE)
+#define COMPILER_SUPPORTS(WTF_COMPILER_FEATURE) WTF_COMPILER_SUPPORTS_##WTF_COMPILER_FEATURE
/* COMPILER_QUIRK() - whether the compiler being used to build the project requires a given quirk. */
-#define COMPILER_QUIRK(WTF_COMPILER_QUIRK) (defined WTF_COMPILER_QUIRK_##WTF_COMPILER_QUIRK && WTF_COMPILER_QUIRK_##WTF_COMPILER_QUIRK)
+#define COMPILER_QUIRK(WTF_COMPILER_QUIRK) WTF_COMPILER_QUIRK_##WTF_COMPILER_QUIRK
/* ==== COMPILER() - the compiler being used to build the project ==== */
diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h
index 7f2023a68a..4f37245495 100644
--- a/src/3rdparty/masm/wtf/Platform.h
+++ b/src/3rdparty/masm/wtf/Platform.h
@@ -38,26 +38,26 @@
/* ==== PLATFORM handles OS, operating environment, graphics API, and
CPU. This macro will be phased out in favor of platform adaptation
macros, policy decision macros, and top-level port definitions. ==== */
-#define PLATFORM(WTF_FEATURE) (defined WTF_PLATFORM_##WTF_FEATURE && WTF_PLATFORM_##WTF_FEATURE)
+#define PLATFORM(WTF_FEATURE) WTF_PLATFORM_##WTF_FEATURE
/* ==== Platform adaptation macros: these describe properties of the target environment. ==== */
/* CPU() - the target CPU architecture */
-#define CPU(WTF_FEATURE) (defined WTF_CPU_##WTF_FEATURE && WTF_CPU_##WTF_FEATURE)
+#define CPU(WTF_FEATURE) WTF_CPU_##WTF_FEATURE
/* HAVE() - specific system features (headers, functions or similar) that are present or not */
-#define HAVE(WTF_FEATURE) (defined HAVE_##WTF_FEATURE && HAVE_##WTF_FEATURE)
+#define HAVE(WTF_FEATURE) HAVE_##WTF_FEATURE
/* OS() - underlying operating system; only to be used for mandated low-level services like
virtual memory, not to choose a GUI toolkit */
-#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE && WTF_OS_##WTF_FEATURE)
+#define OS(WTF_FEATURE) WTF_OS_##WTF_FEATURE
/* ==== Policy decision macros: these define policy choices for a particular port. ==== */
/* USE() - use a particular third-party library or optional OS service */
-#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE)
+#define USE(WTF_FEATURE) WTF_USE_##WTF_FEATURE
/* ENABLE() - turn on a specific feature of WebKit */
-#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE)
+#define ENABLE(WTF_FEATURE) ENABLE_##WTF_FEATURE
/* ==== CPU() - the target CPU architecture ==== */
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 7f2cf40611..c2cf18e3c4 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -665,6 +665,17 @@ private:
} // namespace QmlIR
+struct QQmlCompileError
+{
+ QQmlCompileError() {}
+ QQmlCompileError(const QV4::CompiledData::Location &location, const QString &description)
+ : location(location), description(description) {}
+ QV4::CompiledData::Location location;
+ QString description;
+
+ bool isSet() const { return !description.isEmpty(); }
+};
+
QT_END_NAMESPACE
#endif // QQMLIRBUILDER_P_H
diff --git a/src/qml/compiler/qqmlpropertycachecreator.cpp b/src/qml/compiler/qqmlpropertycachecreator.cpp
index 4f8b48f52e..fd22cd58f1 100644
--- a/src/qml/compiler/qqmlpropertycachecreator.cpp
+++ b/src/qml/compiler/qqmlpropertycachecreator.cpp
@@ -45,26 +45,54 @@ QT_BEGIN_NAMESPACE
QAtomicInt QQmlPropertyCacheCreatorBase::classIndexCounter(0);
-QQmlBindingInstantiationContext::QQmlBindingInstantiationContext()
- : referencingObjectIndex(-1)
- , instantiatingBinding(nullptr)
- , instantiatingProperty(nullptr)
+QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
+ const QString &instantiatingPropertyName, QQmlPropertyCache *referencingObjectPropertyCache)
+ : referencingObjectIndex(referencingObjectIndex)
+ , instantiatingBinding(instantiatingBinding)
+ , instantiatingPropertyName(instantiatingPropertyName)
+ , referencingObjectPropertyCache(referencingObjectPropertyCache)
{
+}
+bool QQmlBindingInstantiationContext::resolveInstantiatingProperty()
+{
+ if (!instantiatingBinding || instantiatingBinding->type != QV4::CompiledData::Binding::Type_GroupProperty)
+ return true;
+
+ Q_ASSERT(referencingObjectIndex >= 0);
+ Q_ASSERT(referencingObjectPropertyCache);
+ Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
+
+ bool notInRevision = false;
+ instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision, QmlIR::PropertyResolver::IgnoreRevision);
+ return instantiatingProperty != nullptr;
}
-QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding, const QString &instantiatingPropertyName, const QQmlPropertyCache *referencingObjectPropertyCache)
- : referencingObjectIndex(referencingObjectIndex)
- , instantiatingBinding(instantiatingBinding)
- , instantiatingProperty(nullptr)
+QQmlRefPointer<QQmlPropertyCache> QQmlBindingInstantiationContext::instantiatingPropertyCache(QQmlEnginePrivate *enginePrivate) const
{
- if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty) {
- Q_ASSERT(referencingObjectIndex >= 0);
- Q_ASSERT(referencingObjectPropertyCache);
- Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
+ if (instantiatingProperty) {
+ if (instantiatingProperty->isQObject()) {
+ return enginePrivate->rawPropertyCacheForType(instantiatingProperty->propType(), instantiatingProperty->typeMinorVersion());
+ } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(instantiatingProperty->propType())) {
+ return enginePrivate->cache(vtmo);
+ }
+ }
+ return QQmlRefPointer<QQmlPropertyCache>();
+}
+
+void QQmlPendingGroupPropertyBindings::resolveMissingPropertyCaches(QQmlEnginePrivate *enginePrivate, QQmlPropertyCacheVector *propertyCaches) const
+{
+ for (QQmlBindingInstantiationContext pendingBinding: *this) {
+ const int groupPropertyObjectIndex = pendingBinding.instantiatingBinding->value.objectIndex;
+
+ if (propertyCaches->at(groupPropertyObjectIndex))
+ continue;
+
+ if (!pendingBinding.resolveInstantiatingProperty())
+ continue;
- bool notInRevision = false;
- instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision, QmlIR::PropertyResolver::IgnoreRevision);
+ auto cache = pendingBinding.instantiatingPropertyCache(enginePrivate);
+ propertyCaches->set(groupPropertyObjectIndex, cache);
}
}
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h
index 2af0fe0036..8bbc8291b4 100644
--- a/src/qml/compiler/qqmlpropertycachecreator_p.h
+++ b/src/qml/compiler/qqmlpropertycachecreator_p.h
@@ -50,18 +50,31 @@
// We mean it.
//
-#include "qqmltypecompiler_p.h"
#include <private/qqmlvaluetype_p.h>
#include <private/qqmlengine_p.h>
QT_BEGIN_NAMESPACE
struct QQmlBindingInstantiationContext {
- QQmlBindingInstantiationContext();
- QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding, const QString &instantiatingPropertyName, const QQmlPropertyCache *referencingObjectPropertyCache);
- int referencingObjectIndex;
- const QV4::CompiledData::Binding *instantiatingBinding;
- QQmlPropertyData *instantiatingProperty;
+ QQmlBindingInstantiationContext() {}
+ QQmlBindingInstantiationContext(int referencingObjectIndex,
+ const QV4::CompiledData::Binding *instantiatingBinding,
+ const QString &instantiatingPropertyName,
+ QQmlPropertyCache *referencingObjectPropertyCache);
+
+ bool resolveInstantiatingProperty();
+ QQmlRefPointer<QQmlPropertyCache> instantiatingPropertyCache(QQmlEnginePrivate *enginePrivate) const;
+
+ int referencingObjectIndex = -1;
+ const QV4::CompiledData::Binding *instantiatingBinding = nullptr;
+ QString instantiatingPropertyName;
+ QQmlRefPointer<QQmlPropertyCache> referencingObjectPropertyCache;
+ QQmlPropertyData *instantiatingProperty = nullptr;
+};
+
+struct QQmlPendingGroupPropertyBindings : public QVector<QQmlBindingInstantiationContext>
+{
+ void resolveMissingPropertyCaches(QQmlEnginePrivate *enginePrivate, QQmlPropertyCacheVector *propertyCaches) const;
};
struct QQmlPropertyCacheCreatorBase
@@ -77,7 +90,10 @@ class QQmlPropertyCacheCreator : public QQmlPropertyCacheCreatorBase
public:
typedef typename ObjectContainer::CompiledObject CompiledObject;
- QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches, QQmlEnginePrivate *enginePrivate, const ObjectContainer *objectContainer, const QQmlImports *imports);
+ QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches,
+ QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings,
+ QQmlEnginePrivate *enginePrivate,
+ const ObjectContainer *objectContainer, const QQmlImports *imports);
QQmlCompileError buildMetaObjects();
@@ -92,14 +108,19 @@ protected:
const ObjectContainer * const objectContainer;
const QQmlImports * const imports;
QQmlPropertyCacheVector *propertyCaches;
+ QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings;
};
template <typename ObjectContainer>
-inline QQmlPropertyCacheCreator<ObjectContainer>::QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches, QQmlEnginePrivate *enginePrivate, const ObjectContainer *objectContainer, const QQmlImports *imports)
+inline QQmlPropertyCacheCreator<ObjectContainer>::QQmlPropertyCacheCreator(QQmlPropertyCacheVector *propertyCaches,
+ QQmlPendingGroupPropertyBindings *pendingGroupPropertyBindings,
+ QQmlEnginePrivate *enginePrivate,
+ const ObjectContainer *objectContainer, const QQmlImports *imports)
: enginePrivate(enginePrivate)
, objectContainer(objectContainer)
, imports(imports)
, propertyCaches(propertyCaches)
+ , pendingGroupPropertyBindings(pendingGroupPropertyBindings)
{
propertyCaches->resize(objectContainer->objectCount());
}
@@ -169,6 +190,14 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObje
for ( ; binding != end; ++binding)
if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
QQmlBindingInstantiationContext context(objectIndex, &(*binding), stringAt(binding->propertyNameIndex), thisCache);
+
+ // Binding to group property where we failed to look up the type of the
+ // property? Possibly a group property that is an alias that's not resolved yet.
+ // Let's attempt to resolve it after we're done with the aliases and fill in the
+ // propertyCaches entry then.
+ if (!context.resolveInstantiatingProperty())
+ pendingGroupPropertyBindings->append(context);
+
QQmlCompileError error = buildMetaObjectRecursively(binding->value.objectIndex, context);
if (error.isSet())
return error;
@@ -183,11 +212,7 @@ template <typename ObjectContainer>
inline QQmlPropertyCache *QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlCompileError *error) const
{
if (context.instantiatingProperty) {
- if (context.instantiatingProperty->isQObject()) {
- return enginePrivate->rawPropertyCacheForType(context.instantiatingProperty->propType(), context.instantiatingProperty->typeMinorVersion());
- } else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(context.instantiatingProperty->propType())) {
- return enginePrivate->cache(vtmo);
- }
+ return context.instantiatingPropertyCache(enginePrivate);
} else if (obj->inheritedTypeNameIndex != 0) {
auto *typeRef = objectContainer->resolvedTypes.value(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 3415e1c073..a896745b3f 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -45,7 +45,6 @@
#include <private/qqmlvmemetaobject_p.h>
#include <private/qqmlcomponent_p.h>
-#include "qqmlpropertycachecreator_p.h"
//#include "qv4jssimplifier_p.h"
#define COMPILE_EXCEPTION(token, desc) \
@@ -79,8 +78,12 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
customParsers.insert(it.key(), customParser);
}
+ QQmlPendingGroupPropertyBindings pendingGroupPropertyBindings;
+
+
{
- QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, engine, this, imports());
+ QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, &pendingGroupPropertyBindings,
+ engine, this, imports());
QQmlCompileError error = propertyCacheBuilder.buildMetaObjects();
if (error.isSet()) {
recordError(error);
@@ -122,6 +125,8 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
QQmlComponentAndAliasResolver resolver(this);
if (!resolver.resolve())
return nullptr;
+
+ pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_propertyCaches);
}
{
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index d905b956c7..b8eddcb9b2 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -55,6 +55,7 @@
#include <qhash.h>
#include <private/qqmltypeloader_p.h>
#include <private/qqmlirbuilder_p.h>
+#include <private/qqmlpropertycachecreator_p.h>
QT_BEGIN_NAMESPACE
@@ -74,17 +75,6 @@ struct Location;
}
}
-struct QQmlCompileError
-{
- QQmlCompileError() {}
- QQmlCompileError(const QV4::CompiledData::Location &location, const QString &description)
- : location(location), description(description) {}
- QV4::CompiledData::Location location;
- QString description;
-
- bool isSet() const { return !description.isEmpty(); }
-};
-
struct QQmlTypeCompiler
{
Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index 3b3c766bfe..e69f2cd310 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -102,14 +102,19 @@ public:
Jump(BytecodeGenerator *generator, int instruction)
: generator(generator),
index(instruction)
- {}
+ { Q_ASSERT(generator && index != -1); }
+
~Jump() {
- Q_ASSERT(generator->instructions[index].linkedLabel != -1);
+ Q_ASSERT(index == -1 || generator->instructions[index].linkedLabel != -1); // make sure link() got called
}
+ Jump(Jump &&j) {
+ std::swap(generator, j.generator);
+ std::swap(index, j.index);
+ }
- BytecodeGenerator *generator;
- int index;
+ BytecodeGenerator *generator = nullptr;
+ int index = -1;
void link() {
link(generator->label());
@@ -119,6 +124,12 @@ public:
Q_ASSERT(generator->instructions[index].linkedLabel == -1);
generator->instructions[index].linkedLabel = l.index;
}
+
+ private:
+ // make this type move-only:
+ Q_DISABLE_COPY(Jump)
+ // we never move-assign this type anywhere, so disable it:
+ Jump &operator=(Jump &&) = delete;
};
struct ExceptionHandler : public Label {
diff --git a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
index 0471d7db9b..be4db4c917 100644
--- a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
+++ b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
@@ -157,7 +157,7 @@ to inside the string literals.
When managing dynamically created objects, you must ensure the creation context
outlives the created object. Otherwise, if the creation context is destroyed
-first, the bindings in the dynamic object will no longer work.
+first, the bindings and signal handlers in the dynamic object will no longer work.
The actual creation context depends on how an object is created:
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index f555740455..36448638f3 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -341,6 +341,11 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
if (!ddata)
return QV4::Encode::undefined();
+ if (Q_UNLIKELY(!ddata->propertyCache)) {
+ ddata->propertyCache = QQmlEnginePrivate::get(engine)->cache(object->metaObject());
+ ddata->propertyCache->addref();
+ }
+
QQmlPropertyCache *cache = ddata->propertyCache;
Q_ASSERT(cache);
QQmlPropertyData *property = cache->property(propertyIndex);
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index cdda0bf7ef..4e83abebdf 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -664,8 +664,21 @@ void BlockAllocator::collectGrayItems(MarkStack *markStack)
}
HeapItem *HugeItemAllocator::allocate(size_t size) {
- Chunk *c = chunkAllocator->allocate(size);
- chunks.push_back(HugeChunk{c, size});
+ MemorySegment *m = nullptr;
+ Chunk *c = nullptr;
+ if (size >= MemorySegment::SegmentSize/2) {
+ // too large to handle through the ChunkAllocator, let's get our own memory segement
+ size_t segmentSize = size + Chunk::HeaderSize; // space required for the Chunk header
+ size_t pageSize = WTF::pageSize();
+ segmentSize = (segmentSize + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ m = new MemorySegment(segmentSize);
+ size = (size + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ c = m->allocate(size);
+ } else {
+ c = chunkAllocator->allocate(size);
+ }
+ Q_ASSERT(c);
+ chunks.push_back(HugeChunk{m, c, size});
Chunk::setBit(c->objectBitmap, c->first() - c->realBase());
Q_V4_PROFILE_ALLOC(engine, size, Profiling::LargeItem);
#ifdef V4_USE_HEAPTRACK
@@ -686,7 +699,13 @@ static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocato
v->destroy(b);
b->_checkIsDestroyed();
}
- chunkAllocator->free(c.chunk, c.size);
+ if (c.segment) {
+ // own memory segment
+ c.segment->free(c.chunk, c.size);
+ delete c.segment;
+ } else {
+ chunkAllocator->free(c.chunk, c.size);
+ }
#ifdef V4_USE_HEAPTRACK
heaptrack_report_free(c.chunk);
#endif
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 1ef54ffcc6..40670bcdc7 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -69,6 +69,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct ChunkAllocator;
+struct MemorySegment;
struct BlockAllocator {
BlockAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
@@ -136,6 +137,7 @@ struct HugeItemAllocator {
ChunkAllocator *chunkAllocator;
ExecutionEngine *engine;
struct HugeChunk {
+ MemorySegment *segment;
Chunk *chunk;
size_t size;
};
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index ca3bff43a4..c314833304 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -490,6 +490,7 @@ void QQmlBinding::refresh()
void QQmlBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags)
{
+ const bool wasEnabled = enabledFlag();
setEnabledFlag(e);
setNotifyOnValueChanged(e);
@@ -499,7 +500,7 @@ void QQmlBinding::setEnabled(bool e, QQmlPropertyData::WriteFlags flags)
m_nextBinding.clearFlag2();
}
- if (e)
+ if (e && !wasEnabled)
update(flags);
}
@@ -514,13 +515,13 @@ void QQmlBinding::setTarget(const QQmlProperty &prop)
setTarget(prop.object(), pd->core, &pd->valueTypeData);
}
-void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const QQmlPropertyData *valueType)
+bool QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const QQmlPropertyData *valueType)
{
m_target = object;
if (!object) {
m_targetIndex = QQmlPropertyIndex();
- return;
+ return false;
}
int coreIndex = core.coreIndex();
@@ -530,9 +531,10 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const
int aValueTypeIndex;
if (!vme->aliasTarget(coreIndex, &object, &coreIndex, &aValueTypeIndex)) {
+ // can't resolve id (yet)
m_target = nullptr;
m_targetIndex = QQmlPropertyIndex();
- return;
+ return false;
}
if (valueTypeIndex == -1)
valueTypeIndex = aValueTypeIndex;
@@ -541,7 +543,7 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const
if (!data || !data->propertyCache) {
m_target = nullptr;
m_targetIndex = QQmlPropertyIndex();
- return;
+ return false;
}
QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex);
Q_ASSERT(propertyData);
@@ -557,6 +559,8 @@ void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core, const
data->propertyCache = QQmlEnginePrivate::get(context()->engine)->cache(m_target->metaObject());
data->propertyCache->addref();
}
+
+ return true;
}
void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyData *valueTypeData) const
diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h
index 19ec3f5d4f..b67b02975f 100644
--- a/src/qml/qml/qqmlbinding_p.h
+++ b/src/qml/qml/qqmlbinding_p.h
@@ -72,6 +72,8 @@ class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression,
{
friend class QQmlAbstractBinding;
public:
+ typedef QExplicitlySharedDataPointer<QQmlBinding> Ptr;
+
static QQmlBinding *create(const QQmlPropertyData *, const QQmlScriptString &, QObject *, QQmlContext *);
static QQmlBinding *create(const QQmlPropertyData *, const QString &, QObject *, QQmlContextData *,
const QString &url = QString(), quint16 lineNumber = 0);
@@ -82,7 +84,7 @@ public:
~QQmlBinding() override;
void setTarget(const QQmlProperty &);
- void setTarget(QObject *, const QQmlPropertyData &, const QQmlPropertyData *valueType);
+ bool setTarget(QObject *, const QQmlPropertyData &, const QQmlPropertyData *valueType);
void setNotifyOnValueChanged(bool);
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 061f3b54a5..3174bbecd3 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -241,6 +241,9 @@ V4_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
\li main.qml
\li \snippet qml/component/main.qml 0
\endtable
+
+ It is important that the lifetime of the creation context outlive any created objects. See
+ \l{Maintaining Dynamically Created Objects} for more details.
*/
/*!
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 36e56a01f8..90f3beb40b 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -780,7 +780,7 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings)
qSwap(_currentList, savedList);
}
-bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, const QV4::CompiledData::Binding *binding)
+bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProperty, const QV4::CompiledData::Binding *binding)
{
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
Q_ASSERT(stringAt(qmlUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty());
@@ -802,7 +802,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
}
// ### resolve this at compile time
- if (property && property->propType() == qMetaTypeId<QQmlScriptString>()) {
+ if (bindingProperty && bindingProperty->propType() == qMetaTypeId<QQmlScriptString>()) {
QQmlScriptString ss(binding->valueAsScriptString(qmlUnit), context->asQQmlContext(), _scopeObject);
ss.d.data()->bindingId = binding->type == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid;
ss.d.data()->lineNumber = binding->location.line;
@@ -815,7 +815,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QQmlPropertyData::RemoveBindingOnAliasWrite;
int propertyWriteStatus = -1;
void *argv[] = { &ss, nullptr, &propertyWriteStatus, &propertyWriteFlags };
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex(), argv);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
return true;
}
@@ -826,7 +826,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
return false;
}
- if (!property) // ### error
+ if (!bindingProperty) // ### error
return true;
if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty) {
@@ -838,20 +838,20 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
const QQmlPropertyData *valueTypeProperty = nullptr;
QObject *bindingTarget = _bindingTarget;
- if (QQmlValueTypeFactory::isValueType(property->propType())) {
- valueType = QQmlValueTypeFactory::valueType(property->propType());
+ if (QQmlValueTypeFactory::isValueType(bindingProperty->propType())) {
+ valueType = QQmlValueTypeFactory::valueType(bindingProperty->propType());
if (!valueType) {
recordError(binding->location, tr("Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
return false;
}
- valueType->read(_qobject, property->coreIndex());
+ valueType->read(_qobject, bindingProperty->coreIndex());
groupObject = valueType;
- valueTypeProperty = property;
+ valueTypeProperty = bindingProperty;
} else {
void *argv[1] = { &groupObject };
- QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property->coreIndex(), argv);
+ QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, bindingProperty->coreIndex(), argv);
if (!groupObject) {
recordError(binding->location, tr("Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
return false;
@@ -864,21 +864,21 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
return false;
if (valueType)
- valueType->write(_qobject, property->coreIndex(), QQmlPropertyData::BypassInterceptor);
+ valueType->write(_qobject, bindingProperty->coreIndex(), QQmlPropertyData::BypassInterceptor);
return true;
}
}
- if (_ddata->hasBindingBit(property->coreIndex()) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
+ if (_ddata->hasBindingBit(bindingProperty->coreIndex()) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
&& !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment)
&& !_valueTypeProperty)
- QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(property->coreIndex()));
+ QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex()));
if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->containsTranslations()) {
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) {
QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
- int signalIndex = _propertyCache->methodIndexToSignalIndex(property->coreIndex());
+ int signalIndex = _propertyCache->methodIndexToSignalIndex(bindingProperty->coreIndex());
QQmlBoundSignal *bs = new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(_bindingTarget, signalIndex,
context, _scopeObject, runtimeFunction, currentQmlContext());
@@ -890,34 +890,44 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
// the point property (_qobjectForBindings) and after evaluating the expression,
// the result is written to a value type virtual property, that contains the sub-index
// of the "x" property.
- QQmlBinding *qmlBinding;
- const QQmlPropertyData *prop = property;
+ QQmlBinding::Ptr qmlBinding;
+ const QQmlPropertyData *targetProperty = bindingProperty;
const QQmlPropertyData *subprop = nullptr;
if (_valueTypeProperty) {
- prop = _valueTypeProperty;
- subprop = property;
+ targetProperty = _valueTypeProperty;
+ subprop = bindingProperty;
}
if (binding->containsTranslations()) {
qmlBinding = QQmlBinding::createTranslationBinding(compilationUnit, binding, _scopeObject, context);
} else {
QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
- qmlBinding = QQmlBinding::create(prop, runtimeFunction, _scopeObject, context, currentQmlContext());
+ qmlBinding = QQmlBinding::create(targetProperty, runtimeFunction, _scopeObject, context, currentQmlContext());
}
- qmlBinding->setTarget(_bindingTarget, *prop, subprop);
- sharedState->allCreatedBindings.push(QQmlAbstractBinding::Ptr(qmlBinding));
+ auto bindingTarget = _bindingTarget;
+ auto valueTypeProperty = _valueTypeProperty;
+ auto assignBinding = [qmlBinding, bindingTarget, targetProperty, subprop, bindingProperty, valueTypeProperty](QQmlObjectCreatorSharedState *sharedState) -> bool {
+ if (!qmlBinding->setTarget(bindingTarget, *targetProperty, subprop) && targetProperty->isAlias())
+ return false;
+
+ sharedState->allCreatedBindings.push(qmlBinding);
- if (property->isAlias()) {
- QQmlPropertyPrivate::setBinding(qmlBinding, QQmlPropertyPrivate::DontEnable);
- } else {
- qmlBinding->addToObject();
+ if (bindingProperty->isAlias()) {
+ QQmlPropertyPrivate::setBinding(qmlBinding.data(), QQmlPropertyPrivate::DontEnable);
+ } else {
+ qmlBinding->addToObject();
- if (!_valueTypeProperty) {
- QQmlData *targetDeclarativeData = QQmlData::get(_bindingTarget);
- Q_ASSERT(targetDeclarativeData);
- targetDeclarativeData->setPendingBindingBit(_bindingTarget, property->coreIndex());
+ if (!valueTypeProperty) {
+ QQmlData *targetDeclarativeData = QQmlData::get(bindingTarget);
+ Q_ASSERT(targetDeclarativeData);
+ targetDeclarativeData->setPendingBindingBit(bindingTarget, bindingProperty->coreIndex());
+ }
}
- }
+
+ return true;
+ };
+ if (!assignBinding(sharedState.data()))
+ pendingAliasBindings.push_back(assignBinding);
}
return true;
}
@@ -934,9 +944,9 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QObject *target = createdSubObject->parent();
QQmlProperty prop;
if (_valueTypeProperty)
- prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty, property, context);
+ prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty, bindingProperty, context);
else
- prop = QQmlPropertyPrivate::restore(target, *property, nullptr, context);
+ prop = QQmlPropertyPrivate::restore(target, *bindingProperty, nullptr, context);
vs->setTarget(prop);
return true;
}
@@ -946,8 +956,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
QObject *target = createdSubObject->parent();
QQmlPropertyIndex propertyIndex;
- if (property->isAlias()) {
- QQmlPropertyIndex originalIndex(property->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
+ if (bindingProperty->isAlias()) {
+ QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
QQmlPropertyIndex propIndex;
QQmlPropertyPrivate::findAliasTarget(target, originalIndex, &target, &propIndex);
QQmlData *data = QQmlData::get(target);
@@ -964,9 +974,9 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
} else {
QQmlProperty prop;
if (_valueTypeProperty)
- prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty, property, context);
+ prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty, bindingProperty, context);
else
- prop = QQmlPropertyPrivate::restore(target, *property, nullptr, context);
+ prop = QQmlPropertyPrivate::restore(target, *bindingProperty, nullptr, context);
vi->setTarget(prop);
propertyIndex = QQmlPropertyPrivate::propertyIndex(prop);
}
@@ -982,8 +992,8 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
// Assigning object to signal property?
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) {
- if (!property->isFunction()) {
- recordError(binding->valueLocation, tr("Cannot assign an object to signal property %1").arg(property->name(_qobject)));
+ if (!bindingProperty->isFunction()) {
+ recordError(binding->valueLocation, tr("Cannot assign an object to signal property %1").arg(bindingProperty->name(_qobject)));
return false;
}
QMetaMethod method = QQmlMetaType::defaultMethod(createdSubObject);
@@ -992,7 +1002,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
return false;
}
- QMetaMethod signalMethod = _qobject->metaObject()->method(property->coreIndex());
+ QMetaMethod signalMethod = _qobject->metaObject()->method(bindingProperty->coreIndex());
if (!QMetaObject::checkConnectArgs(signalMethod, method)) {
recordError(binding->valueLocation,
tr("Cannot connect mismatched signal/slot %1 %vs. %2")
@@ -1001,7 +1011,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
return false;
}
- QQmlPropertyPrivate::connect(_qobject, property->coreIndex(), createdSubObject, method.methodIndex());
+ QQmlPropertyPrivate::connect(_qobject, bindingProperty->coreIndex(), createdSubObject, method.methodIndex());
return true;
}
@@ -1010,32 +1020,32 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
int propertyWriteStatus = -1;
void *argv[] = { nullptr, nullptr, &propertyWriteStatus, &propertyWriteFlags };
- if (const char *iid = QQmlMetaType::interfaceIId(property->propType())) {
+ if (const char *iid = QQmlMetaType::interfaceIId(bindingProperty->propType())) {
void *ptr = createdSubObject->qt_metacast(iid);
if (ptr) {
argv[0] = &ptr;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex(), argv);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
} else {
recordError(binding->location, tr("Cannot assign object to interface property"));
return false;
}
- } else if (property->propType() == QMetaType::QVariant) {
- if (property->isVarProperty()) {
+ } else if (bindingProperty->propType() == QMetaType::QVariant) {
+ if (bindingProperty->isVarProperty()) {
QV4::Scope scope(v4);
QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject));
- _vmeMetaObject->setVMEProperty(property->coreIndex(), wrappedObject);
+ _vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
} else {
QVariant value = QVariant::fromValue(createdSubObject);
argv[0] = &value;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex(), argv);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
}
- } else if (property->isQList()) {
+ } else if (bindingProperty->isQList()) {
Q_ASSERT(_currentList.object);
void *itemToAdd = createdSubObject;
const char *iid = nullptr;
- int listItemType = QQmlEnginePrivate::get(engine)->listType(property->propType());
+ int listItemType = QQmlEnginePrivate::get(engine)->listType(bindingProperty->propType());
if (listItemType != -1)
iid = QQmlMetaType::interfaceIId(listItemType);
if (iid)
@@ -1051,17 +1061,17 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
} else {
// pointer compatibility was tested in QQmlPropertyValidator at type compile time
argv[0] = &createdSubObject;
- QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, property->coreIndex(), argv);
+ QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
}
return true;
}
- if (property->isQList()) {
+ if (bindingProperty->isQList()) {
recordError(binding->location, tr("Cannot assign primitives to lists"));
return false;
}
- setPropertyValue(property, binding);
+ setPropertyValue(bindingProperty, binding);
return true;
}
@@ -1274,12 +1284,33 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
qSwap(_qmlContext, qmlContext);
- bool result = populateInstance(index, instance, /*binding target*/instance, /*value type property*/nullptr);
+ bool ok = populateInstance(index, instance, /*binding target*/instance, /*value type property*/nullptr);
+ if (ok) {
+ if (isContextObject && !pendingAliasBindings.empty()) {
+ bool processedAtLeastOneBinding = false;
+ do {
+ processedAtLeastOneBinding = false;
+ for (std::vector<PendingAliasBinding>::iterator it = pendingAliasBindings.begin();
+ it != pendingAliasBindings.end(); ) {
+ if ((*it)(sharedState.data())) {
+ it = pendingAliasBindings.erase(it);
+ processedAtLeastOneBinding = true;
+ } else {
+ ++it;
+ }
+ }
+ } while (processedAtLeastOneBinding && pendingAliasBindings.empty());
+ Q_ASSERT(pendingAliasBindings.empty());
+ }
+ } else {
+ // an error occurred, so we can't setup the pending alias bindings
+ pendingAliasBindings.clear();
+ }
qSwap(_qmlContext, qmlContext);
qSwap(_scopeObject, scopeObject);
- return result ? instance : nullptr;
+ return ok ? instance : nullptr;
}
QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 399a5f6d4a..67a5bdd827 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -161,6 +161,9 @@ private:
QV4::QmlContext *_qmlContext;
friend struct QQmlObjectCreatorRecursionWatcher;
+
+ typedef std::function<bool(QQmlObjectCreatorSharedState *sharedState)> PendingAliasBinding;
+ std::vector<PendingAliasBinding> pendingAliasBindings;
};
struct QQmlObjectCreatorRecursionWatcher
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 8ecd597a39..c4487f91a3 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -269,7 +269,9 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
for (int ii = 0; ii < path.count() - 1; ++ii) {
const QStringRef &pathName = path.at(ii);
- if (typeNameCache) {
+ // Types must begin with an uppercase letter (see checkRegistration()
+ // in qqmlmetatype.cpp for the enforcement of this).
+ if (typeNameCache && !pathName.isEmpty() && pathName.at(0).isUpper()) {
QQmlTypeNameCache::Result r = typeNameCache->query(pathName);
if (r.isValid()) {
if (r.type.isValid()) {
@@ -875,6 +877,7 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, QQmlPropertyIndex bin
void QQmlPropertyPrivate::setBinding(QQmlAbstractBinding *binding, BindingFlags flags, QQmlPropertyData::WriteFlags writeFlags)
{
Q_ASSERT(binding);
+ Q_ASSERT(binding->targetObject());
QObject *object = binding->targetObject();
const QQmlPropertyIndex index = binding->targetPropertyIndex();
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 51a191a41f..b78a2ddd20 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -81,6 +81,7 @@ template <typename T> class QQmlPropertyCacheAliasCreator;
// We have this somewhat awful split between RawData and Data so that RawData can be
// used in unions. In normal code, you should always use Data which initializes RawData
// to an invalid state on construction.
+// ### We should be able to remove this split nowadays
class QQmlPropertyRawData
{
public:
@@ -273,20 +274,20 @@ public:
private:
Flags _flags;
- qint16 _coreIndex;
- quint16 _propType;
+ qint16 _coreIndex = 0;
+ quint16 _propType = 0;
// The notify index is in the range returned by QObjectPrivate::signalIndex().
// This is different from QMetaMethod::methodIndex().
- qint16 _notifyIndex;
- qint16 _overrideIndex;
+ qint16 _notifyIndex = 0;
+ qint16 _overrideIndex = 0;
- quint8 _revision;
- quint8 _typeMinorVersion;
- qint16 _metaObjectOffset;
+ quint8 _revision = 0;
+ quint8 _typeMinorVersion = 0;
+ qint16 _metaObjectOffset = 0;
- QQmlPropertyCacheMethodArguments *_arguments;
- StaticMetaCallFunction _staticMetaCallFunction;
+ QQmlPropertyCacheMethodArguments *_arguments = nullptr;
+ StaticMetaCallFunction _staticMetaCallFunction = nullptr;
friend class QQmlPropertyData;
friend class QQmlPropertyCache;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index a107bb42ce..61208d1c4a 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2187,8 +2187,12 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName
QQmlEnginePrivate * const engine = QQmlEnginePrivate::get(typeLoader()->engine());
+ QQmlPendingGroupPropertyBindings pendingGroupPropertyBindings;
+
{
- QQmlPropertyCacheCreator<QV4::CompiledData::CompilationUnit> propertyCacheCreator(&m_compiledData->propertyCaches, engine, m_compiledData, &m_importCache);
+ QQmlPropertyCacheCreator<QV4::CompiledData::CompilationUnit> propertyCacheCreator(&m_compiledData->propertyCaches,
+ &pendingGroupPropertyBindings,
+ engine, m_compiledData, &m_importCache);
QQmlCompileError error = propertyCacheCreator.buildMetaObjects();
if (error.isSet()) {
setError(error);
@@ -2198,6 +2202,8 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName
QQmlPropertyCacheAliasCreator<QV4::CompiledData::CompilationUnit> aliasCreator(&m_compiledData->propertyCaches, m_compiledData);
aliasCreator.appendAliasPropertiesToMetaObjects();
+
+ pendingGroupPropertyBindings.resolveMissingPropertyCaches(engine, &m_compiledData->propertyCaches);
}
static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeReference> &typeRefs, QCryptographicHash *hash, QQmlEngine *engine)
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 0e1d9e6fad..14ba6561d4 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1123,6 +1123,11 @@ ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Va
QQmlEngine *engine = scope.engine->qmlEngine();
QQmlContextData *context = scope.engine->callingQmlContext();
+ if (!context) {
+ QQmlEngine *qmlEngine = scope.engine->qmlEngine();
+ if (qmlEngine)
+ context = QQmlContextData::get(QQmlEnginePrivate::get(qmlEngine)->rootContext);
+ }
Q_ASSERT(context);
QQmlContext *effectiveContext = nullptr;
if (context->isPragmaLibraryContext)
@@ -1250,6 +1255,11 @@ ReturnedValue QtObject::method_createComponent(const FunctionObject *b, const Va
QQmlEngine *engine = scope.engine->qmlEngine();
QQmlContextData *context = scope.engine->callingQmlContext();
+ if (!context) {
+ QQmlEngine *qmlEngine = scope.engine->qmlEngine();
+ if (qmlEngine)
+ context = QQmlContextData::get(QQmlEnginePrivate::get(qmlEngine)->rootContext);
+ }
Q_ASSERT(context);
QQmlContextData *effectiveContext = context;
if (context->isPragmaLibraryContext)
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 40d1fab3dc..1be4bafe28 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -625,8 +625,7 @@ QQuickPointerDevice *QQuickPointerDevice::touchDevice(const QTouchDevice *d)
int maximumTouchPoints = 10;
QQuickPointerDevice::Capabilities caps = QQuickPointerDevice::Capabilities(QTouchDevice::Position);
if (d) {
- QQuickPointerDevice::Capabilities caps =
- static_cast<QQuickPointerDevice::Capabilities>(static_cast<int>(d->capabilities()) & 0x0F);
+ caps = static_cast<QQuickPointerDevice::Capabilities>(static_cast<int>(d->capabilities()) & 0xFF);
if (d->type() == QTouchDevice::TouchPad) {
type = QQuickPointerDevice::TouchPad;
caps |= QQuickPointerDevice::Scroll;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index ea24bfcad5..3a0aea517c 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1544,6 +1544,13 @@ QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
mirroring is not the desired behavior, or if the child item already implements mirroring in
some custom way.
+ To set the layout direction based on the \l {Default Layout Direction}{default layout direction}
+ of the application, use the following code:
+
+ \code
+ LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
+ \endcode
+
See \l {Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
other related features to implement right-to-left support for an application.
*/
diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262
-Subproject d60c4ed97e69639bc5bc1db43a98828debf80c8
+Subproject 40b4f28e98c416a092e26aa17489bf94ccb8bf4
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index bf964a5744..52e18011cb 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -76,6 +76,7 @@ private slots:
void qmlContextProperties();
void testGCCorruption();
void testGroupedPropertyRevisions();
+ void componentFromEval();
public slots:
QObject *createAQObjectForOwnershipTest ()
@@ -885,6 +886,17 @@ void tst_qqmlengine::testGroupedPropertyRevisions()
QVERIFY(!c2.errorString().isEmpty());
}
+void tst_qqmlengine::componentFromEval()
+{
+ QQmlEngine engine;
+ const QUrl testUrl = testFileUrl("EmptyComponent.qml");
+ QJSValue result = engine.evaluate("Qt.createComponent(\"" + testUrl.toString() + "\");");
+ QPointer<QQmlComponent> component(qobject_cast<QQmlComponent*>(result.toQObject()));
+ QVERIFY(!component.isNull());
+ QScopedPointer<QObject> item(component->create());
+ QVERIFY(!item.isNull());
+}
+
QTEST_MAIN(tst_qqmlengine)
#include "tst_qqmlengine.moc"
diff --git a/tests/auto/qml/qqmllanguage/data/alias.15.qml b/tests/auto/qml/qqmllanguage/data/alias.15.qml
new file mode 100644
index 0000000000..5f3de9c83e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.15.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.6
+
+Item {
+ id: root
+
+ property alias symbol: symbol
+ symbol.y: 1
+
+ Item {
+ id: symbol
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/alias.16.qml b/tests/auto/qml/qqmllanguage/data/alias.16.qml
new file mode 100644
index 0000000000..4637aec58f
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.16.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+import QtQuick.Window 2.0
+
+Window {
+ visible: true
+
+ property alias list: repeater.model
+
+ list: ["A", "B", "C"]
+
+ Repeater {
+ id: repeater
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.2.qml b/tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.2.qml
new file mode 100644
index 0000000000..ff2f0f5a2c
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.2.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+QtObject {
+ property int secondVar: {
+ stats.increaseEvaluationCounter()
+ return 1
+ }
+ property int firstVar: secondVar + 1
+}
diff --git a/tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.qml b/tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.qml
new file mode 100644
index 0000000000..0eb5e03642
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/noDoubleEvaluationForFlushedBindings.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+QtObject {
+ property int firstVar: secondVar + 1
+ property int secondVar: {
+ stats.increaseEvaluationCounter()
+ return 1
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 952e4a22a1..8bc631fbdd 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -125,6 +125,8 @@ private slots:
void dynamicObjectProperties();
void dynamicSignalsAndSlots();
void simpleBindings();
+ void noDoubleEvaluationForFlushedBindings_data();
+ void noDoubleEvaluationForFlushedBindings();
void autoComponentCreation();
void autoComponentCreationInGroupProperty();
void propertyValueSource();
@@ -372,9 +374,11 @@ void tst_qqmllanguage::insertedSemicolon()
QQmlComponent component(&engine, testFileUrl(file));
+ QScopedPointer<QObject> object;
+
if(create) {
- QObject *object = component.create();
- QVERIFY(!object);
+ object.reset(component.create());
+ QVERIFY(object.isNull());
}
VERIFY_ERRORS(errorFile.toLatin1().constData());
@@ -606,9 +610,11 @@ void tst_qqmllanguage::errors()
QQmlComponent component(&engine, testFileUrl(file));
+ QScopedPointer<QObject> object;
+
if (create) {
- QObject *object = component.create();
- QVERIFY(!object);
+ object.reset(component.create());
+ QVERIFY(object.isNull());
}
VERIFY_ERRORS(errorFile.toLatin1().constData());
@@ -618,7 +624,7 @@ void tst_qqmllanguage::simpleObject()
{
QQmlComponent component(&engine, testFileUrl("simpleObject.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -626,7 +632,7 @@ void tst_qqmllanguage::simpleContainer()
{
QQmlComponent component(&engine, testFileUrl("simpleContainer.qml"));
VERIFY_ERRORS(0);
- MyContainer *container= qobject_cast<MyContainer*>(component.create());
+ QScopedPointer<MyContainer> container(qobject_cast<MyContainer*>(component.create()));
QVERIFY(container != nullptr);
QCOMPARE(container->getChildren()->count(),2);
}
@@ -635,7 +641,7 @@ void tst_qqmllanguage::interfaceProperty()
{
QQmlComponent component(&engine, testFileUrl("interfaceProperty.qml"));
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(object->interface());
QCOMPARE(object->interface()->id, 913);
@@ -645,7 +651,7 @@ void tst_qqmllanguage::interfaceQList()
{
QQmlComponent component(&engine, testFileUrl("interfaceQList.qml"));
VERIFY_ERRORS(0);
- MyContainer *container= qobject_cast<MyContainer*>(component.create());
+ QScopedPointer<MyContainer> container(qobject_cast<MyContainer*>(component.create()));
QVERIFY(container != nullptr);
QCOMPARE(container->getQListInterfaces()->count(), 2);
for(int ii = 0; ii < 2; ++ii)
@@ -656,7 +662,7 @@ void tst_qqmllanguage::assignObjectToSignal()
{
QQmlComponent component(&engine, testFileUrl("assignObjectToSignal.qml"));
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
QVERIFY(object != nullptr);
QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
emit object->basicSignal();
@@ -666,7 +672,7 @@ void tst_qqmllanguage::assignObjectToVariant()
{
QQmlComponent component(&engine, testFileUrl("assignObjectToVariant.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVariant v = object->property("a");
QVERIFY(v.userType() == qMetaTypeId<QObject *>());
@@ -676,7 +682,7 @@ void tst_qqmllanguage::assignLiteralSignalProperty()
{
QQmlComponent component(&engine, testFileUrl("assignLiteralSignalProperty.qml"));
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->onLiteralSignal(), 10);
}
@@ -686,7 +692,7 @@ void tst_qqmllanguage::assignQmlComponent()
{
QQmlComponent component(&engine, testFileUrl("assignQmlComponent.qml"));
VERIFY_ERRORS(0);
- MyContainer *object = qobject_cast<MyContainer *>(component.create());
+ QScopedPointer<MyContainer> object(qobject_cast<MyContainer *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->getChildren()->count(), 1);
QObject *child = object->getChildren()->at(0);
@@ -699,7 +705,7 @@ void tst_qqmllanguage::assignBasicTypes()
{
QQmlComponent component(&engine, testFileUrl("assignBasicTypes.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3);
QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2);
@@ -744,7 +750,7 @@ void tst_qqmllanguage::assignTypeExtremes()
{
QQmlComponent component(&engine, testFileUrl("assignTypeExtremes.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->uintProperty(), 0xEE6B2800);
QCOMPARE(object->intProperty(), -0x77359400);
@@ -755,7 +761,7 @@ void tst_qqmllanguage::assignCompositeToType()
{
QQmlComponent component(&engine, testFileUrl("assignCompositeToType.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -764,7 +770,7 @@ void tst_qqmllanguage::assignLiteralToVariant()
{
QQmlComponent component(&engine, testFileUrl("assignLiteralToVariant.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVERIFY(isJSNumberType(object->property("test1").userType()));
@@ -792,8 +798,6 @@ void tst_qqmllanguage::assignLiteralToVariant()
QCOMPARE(object->property("test10"), QVariant(bool(true)));
QCOMPARE(object->property("test11"), QVariant(bool(false)));
QVERIFY(object->property("test12") == QVariant(QVector4D(100, 100, 100, 100)));
-
- delete object;
}
// Test that literals are stored correctly in "var" properties
@@ -803,7 +807,7 @@ void tst_qqmllanguage::assignLiteralToVar()
{
QQmlComponent component(&engine, testFileUrl("assignLiteralToVar.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVERIFY(isJSNumberType(object->property("test1").userType()));
@@ -843,15 +847,13 @@ void tst_qqmllanguage::assignLiteralToVar()
QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
QCOMPARE(object->property("test1Bound"), QVariant(11));
-
- delete object;
}
void tst_qqmllanguage::assignLiteralToJSValue()
{
QQmlComponent component(&engine, testFileUrl("assignLiteralToJSValue.qml"));
VERIFY_ERRORS(0);
- QObject *root = component.create();
+ QScopedPointer<QObject> root(component.create());
QVERIFY(root != nullptr);
{
@@ -939,11 +941,11 @@ void tst_qqmllanguage::assignNullStrings()
{
QQmlComponent component(&engine, testFileUrl("assignNullStrings.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(object->stringProperty().isNull());
QVERIFY(object->byteArrayProperty().isNull());
- QMetaObject::invokeMethod(object, "assignNullStringsFromJs", Qt::DirectConnection);
+ QMetaObject::invokeMethod(object.data(), "assignNullStringsFromJs", Qt::DirectConnection);
QVERIFY(object->stringProperty().isNull());
QVERIFY(object->byteArrayProperty().isNull());
}
@@ -953,7 +955,7 @@ void tst_qqmllanguage::bindJSValueToVar()
QQmlComponent component(&engine, testFileUrl("assignLiteralToJSValue.qml"));
VERIFY_ERRORS(0);
- QObject *root = component.create();
+ QScopedPointer<QObject> root(component.create());
QVERIFY(root != nullptr);
QObject *object = root->findChild<QObject *>("varProperties");
@@ -1002,7 +1004,7 @@ void tst_qqmllanguage::bindJSValueToVariant()
QQmlComponent component(&engine, testFileUrl("assignLiteralToJSValue.qml"));
VERIFY_ERRORS(0);
- QObject *root = component.create();
+ QScopedPointer<QObject> root(component.create());
QVERIFY(root != nullptr);
QObject *object = root->findChild<QObject *>("variantProperties");
@@ -1051,7 +1053,7 @@ void tst_qqmllanguage::bindJSValueToType()
QQmlComponent component(&engine, testFileUrl("assignLiteralToJSValue.qml"));
VERIFY_ERRORS(0);
- QObject *root = component.create();
+ QScopedPointer<QObject> root(component.create());
QVERIFY(root != nullptr);
{
@@ -1086,7 +1088,7 @@ void tst_qqmllanguage::bindTypeToJSValue()
QQmlComponent component(&engine, testFileUrl("bindTypeToJSValue.qml"));
VERIFY_ERRORS(0);
- QObject *root = component.create();
+ QScopedPointer<QObject> root(component.create());
QVERIFY(root != nullptr);
{
@@ -1225,7 +1227,7 @@ void tst_qqmllanguage::customParserTypes()
{
QQmlComponent component(&engine, testFileUrl("customParserTypes.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("count"), QVariant(2));
}
@@ -1235,7 +1237,7 @@ void tst_qqmllanguage::rootAsQmlComponent()
{
QQmlComponent component(&engine, testFileUrl("rootAsQmlComponent.qml"));
VERIFY_ERRORS(0);
- MyContainer *object = qobject_cast<MyContainer *>(component.create());
+ QScopedPointer<MyContainer> object(qobject_cast<MyContainer *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->property("x"), QVariant(11));
QCOMPARE(object->getChildren()->count(), 2);
@@ -1259,12 +1261,12 @@ void tst_qqmllanguage::inlineQmlComponents()
{
QQmlComponent component(&engine, testFileUrl("inlineQmlComponents.qml"));
VERIFY_ERRORS(0);
- MyContainer *object = qobject_cast<MyContainer *>(component.create());
+ QScopedPointer<MyContainer> object(qobject_cast<MyContainer *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->getChildren()->count(), 1);
QQmlComponent *comp = qobject_cast<QQmlComponent *>(object->getChildren()->at(0));
QVERIFY(comp != nullptr);
- MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create());
+ QScopedPointer<MyQmlObject> compObject(qobject_cast<MyQmlObject *>(comp->create()));
QVERIFY(compObject != nullptr);
QCOMPARE(compObject->value(), 11);
}
@@ -1275,7 +1277,7 @@ void tst_qqmllanguage::idProperty()
{
QQmlComponent component(&engine, testFileUrl("idProperty.qml"));
VERIFY_ERRORS(0);
- MyContainer *object = qobject_cast<MyContainer *>(component.create());
+ QScopedPointer<MyContainer> object(qobject_cast<MyContainer *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->getChildren()->count(), 2);
MyTypeObject *child =
@@ -1306,14 +1308,14 @@ void tst_qqmllanguage::autoNotifyConnection()
{
QQmlComponent component(&engine, testFileUrl("autoNotifyConnection.qml"));
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
QVERIFY(object != nullptr);
QMetaProperty prop = object->metaObject()->property(object->metaObject()->indexOfProperty("receivedNotify"));
QVERIFY(prop.isValid());
- QCOMPARE(prop.read(object), QVariant::fromValue(false));
+ QCOMPARE(prop.read(object.data()), QVariant::fromValue(false));
object->setPropertyWithNotify(1);
- QCOMPARE(prop.read(object), QVariant::fromValue(true));
+ QCOMPARE(prop.read(object.data()), QVariant::fromValue(true));
}
// Tests that signals can be assigned to
@@ -1321,7 +1323,7 @@ void tst_qqmllanguage::assignSignal()
{
QQmlComponent component(&engine, testFileUrl("assignSignal.qml"));
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
QVERIFY(object != nullptr);
QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
emit object->basicSignal();
@@ -1333,7 +1335,7 @@ void tst_qqmllanguage::assignSignalFunctionExpression()
{
QQmlComponent component(&engine, testFileUrl("assignSignalFunctionExpression.qml"));
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
QVERIFY(object != nullptr);
QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
emit object->basicSignal();
@@ -1362,10 +1364,9 @@ void tst_qqmllanguage::overrideSignal()
QQmlComponent component(&engine, testFileUrl(file));
if (errorFile.isEmpty()) {
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVERIFY(object->property("success").toBool());
- delete object;
} else {
VERIFY_ERRORS(errorFile.toLatin1().constData());
}
@@ -1376,8 +1377,7 @@ void tst_qqmllanguage::dynamicProperties()
{
QQmlComponent component(&engine, testFileUrl("dynamicProperties.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
- QVERIFY(object != nullptr);
+ QScopedPointer<QObject> object(component.create());
QCOMPARE(object->property("intProperty"), QVariant(10));
QCOMPARE(object->property("boolProperty"), QVariant(false));
QCOMPARE(object->property("doubleProperty"), QVariant(-10.1));
@@ -1394,15 +1394,13 @@ void tst_qqmllanguage::dynamicPropertiesNested()
{
QQmlComponent component(&engine, testFileUrl("dynamicPropertiesNested.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("super_a").toInt(), 11); // Overridden
QCOMPARE(object->property("super_c").toInt(), 14); // Inherited
QCOMPARE(object->property("a").toInt(), 13); // New
QCOMPARE(object->property("b").toInt(), 12); // New
-
- delete object;
}
// Tests the creation and assignment to dynamic list properties
@@ -1410,7 +1408,7 @@ void tst_qqmllanguage::listProperties()
{
QQmlComponent component(&engine, testFileUrl("listProperties.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("test").toInt(), 2);
@@ -1430,7 +1428,7 @@ void tst_qqmllanguage::dynamicObjectProperties()
{
QQmlComponent component(&engine, testFileUrl("dynamicObjectProperties.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("objectProperty"), qVariantFromValue((QObject*)nullptr));
@@ -1439,7 +1437,7 @@ void tst_qqmllanguage::dynamicObjectProperties()
{
QQmlComponent component(&engine, testFileUrl("dynamicObjectProperties.2.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVERIFY(object->property("objectProperty") != qVariantFromValue((QObject*)nullptr));
@@ -1453,7 +1451,7 @@ void tst_qqmllanguage::dynamicSignalsAndSlots()
QQmlComponent component(&engine, testFileUrl("dynamicSignalsAndSlots.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1);
QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1);
@@ -1461,7 +1459,7 @@ void tst_qqmllanguage::dynamicSignalsAndSlots()
QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1);
QCOMPARE(object->property("test").toInt(), 0);
- QMetaObject::invokeMethod(object, "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
+ QMetaObject::invokeMethod(object.data(), "slot3", Qt::DirectConnection, Q_ARG(QVariant, QVariant(10)));
QCOMPARE(object->property("test").toInt(), 10);
}
@@ -1469,13 +1467,44 @@ void tst_qqmllanguage::simpleBindings()
{
QQmlComponent component(&engine, testFileUrl("simpleBindings.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("value1"), QVariant(10));
QCOMPARE(object->property("value2"), QVariant(10));
QCOMPARE(object->property("value3"), QVariant(21));
QCOMPARE(object->property("value4"), QVariant(10));
- QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object));
+ QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object.data()));
+}
+
+class EvaluationCounter : public QObject
+{
+ Q_OBJECT
+public:
+ int counter = 0;
+ Q_INVOKABLE void increaseEvaluationCounter() { ++counter; }
+};
+
+void tst_qqmllanguage::noDoubleEvaluationForFlushedBindings_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::newRow("order1") << QString("noDoubleEvaluationForFlushedBindings.qml");
+ QTest::newRow("order2") << QString("noDoubleEvaluationForFlushedBindings.2.qml");
+}
+
+void tst_qqmllanguage::noDoubleEvaluationForFlushedBindings()
+{
+ QFETCH(QString, fileName);
+ QQmlEngine engine;
+
+ EvaluationCounter stats;
+ engine.rootContext()->setContextProperty("stats", &stats);
+
+ QQmlComponent component(&engine, testFileUrl(fileName));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ QCOMPARE(stats.counter, 1);
}
void tst_qqmllanguage::autoComponentCreation()
@@ -1483,20 +1512,20 @@ void tst_qqmllanguage::autoComponentCreation()
{
QQmlComponent component(&engine, testFileUrl("autoComponentCreation.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(object->componentProperty() != nullptr);
- MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
+ QScopedPointer<MyTypeObject> child(qobject_cast<MyTypeObject *>(object->componentProperty()->create()));
QVERIFY(child != nullptr);
QCOMPARE(child->realProperty(), qreal(9));
}
{
QQmlComponent component(&engine, testFileUrl("autoComponentCreation.2.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(object->componentProperty() != nullptr);
- MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
+ QScopedPointer<MyTypeObject> child(qobject_cast<MyTypeObject *>(object->componentProperty()->create()));
QVERIFY(child != nullptr);
QCOMPARE(child->realProperty(), qreal(9));
}
@@ -1506,10 +1535,10 @@ void tst_qqmllanguage::autoComponentCreationInGroupProperty()
{
QQmlComponent component(&engine, testFileUrl("autoComponentCreationInGroupProperties.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(object->componentProperty() != nullptr);
- MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create());
+ QScopedPointer<MyTypeObject> child(qobject_cast<MyTypeObject *>(object->componentProperty()->create()));
QVERIFY(child != nullptr);
QCOMPARE(child->realProperty(), qreal(9));
}
@@ -1519,7 +1548,7 @@ void tst_qqmllanguage::propertyValueSource()
{
QQmlComponent component(&engine, testFileUrl("propertyValueSource.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QList<QObject *> valueSources;
@@ -1533,14 +1562,14 @@ void tst_qqmllanguage::propertyValueSource()
MyPropertyValueSource *valueSource =
qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
QVERIFY(valueSource != nullptr);
- QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
+ QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object.data()));
QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
}
{
QQmlComponent component(&engine, testFileUrl("propertyValueSource.2.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QList<QObject *> valueSources;
@@ -1554,7 +1583,7 @@ void tst_qqmllanguage::propertyValueSource()
MyPropertyValueSource *valueSource =
qobject_cast<MyPropertyValueSource *>(valueSources.at(0));
QVERIFY(valueSource != nullptr);
- QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object));
+ QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object.data()));
QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty")));
}
}
@@ -1563,9 +1592,9 @@ void tst_qqmllanguage::attachedProperties()
{
QQmlComponent component(&engine, testFileUrl("attachedProperties.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object);
+ QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object.data());
QVERIFY(attached != nullptr);
QCOMPARE(attached->property("value"), QVariant(10));
QCOMPARE(attached->property("value2"), QVariant(13));
@@ -1576,7 +1605,7 @@ void tst_qqmllanguage::dynamicObjects()
{
QQmlComponent component(&engine, testFileUrl("dynamicObject.1.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -1585,7 +1614,7 @@ void tst_qqmllanguage::customVariantTypes()
{
QQmlComponent component(&engine, testFileUrl("customVariantTypes.qml"));
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->customType().a, 10);
}
@@ -1599,7 +1628,7 @@ void tst_qqmllanguage::valueTypes()
QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
@@ -1630,20 +1659,17 @@ void tst_qqmllanguage::cppnamespace()
{
QQmlComponent component(&engine, testFileUrl("cppnamespace.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("intProperty").toInt(), (int)MyNamespace::MyOtherNSEnum::OtherKey2);
-
- delete object;
}
{
QQmlComponent component(&engine, testFileUrl("cppnamespace.2.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- delete object;
}
}
@@ -1653,7 +1679,7 @@ void tst_qqmllanguage::aliasProperties()
{
QQmlComponent component(&engine, testFileUrl("alias.1.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
// Read through alias
@@ -1665,15 +1691,13 @@ void tst_qqmllanguage::aliasProperties()
object->setProperty("valueAlias", QVariant(19));
QCOMPARE(object->property("valueAlias").toInt(), 19);
QCOMPARE(object->property("value").toInt(), 19);
-
- delete object;
}
// Complex object alias
{
QQmlComponent component(&engine, testFileUrl("alias.2.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
// Read through alias
@@ -1684,21 +1708,19 @@ void tst_qqmllanguage::aliasProperties()
// Write through alias
MyQmlObject *v2 = new MyQmlObject();
- v2->setParent(object);
+ v2->setParent(object.data());
object->setProperty("aliasObject", qVariantFromValue(v2));
MyQmlObject *v3 =
qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
QVERIFY(v3 != nullptr);
QCOMPARE(v3, v2);
-
- delete object;
}
// Nested aliases
{
QQmlComponent component(&engine, testFileUrl("alias.3.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("value").toInt(), 1892);
@@ -1711,27 +1733,23 @@ void tst_qqmllanguage::aliasProperties()
object->setProperty("value2", QVariant(8080));
QCOMPARE(object->property("value").toInt(), 8080);
QCOMPARE(object->property("value2").toInt(), 8080);
-
- delete object;
}
// Enum aliases
{
QQmlComponent component(&engine, testFileUrl("alias.4.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("enumAlias").toInt(), 1);
-
- delete object;
}
// Id aliases
{
QQmlComponent component(&engine, testFileUrl("alias.5.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVariant v = object->property("otherAlias");
@@ -1745,15 +1763,13 @@ void tst_qqmllanguage::aliasProperties()
QCOMPARE(v.userType(), qMetaTypeId<MyQmlObject*>());
o = qvariant_cast<MyQmlObject*>(v);
QVERIFY(!o);
-
- delete object;
}
// Nested aliases - this used to cause a crash
{
QQmlComponent component(&engine, testFileUrl("alias.6.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("a").toInt(), 1923);
@@ -1765,7 +1781,7 @@ void tst_qqmllanguage::aliasProperties()
QQmlComponent component(&engine, testFileUrl("alias.7.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QObject *object1 = qvariant_cast<QObject *>(object->property("object"));
@@ -1778,10 +1794,10 @@ void tst_qqmllanguage::aliasProperties()
delete object1;
- QObject *alias2 = object; // "Random" start value
+ QObject *alias2 = object.data(); // "Random" start value
int status = -1;
void *a[] = { &alias2, nullptr, &status };
- QMetaObject::metacall(object, QMetaObject::ReadProperty,
+ QMetaObject::metacall(object.data(), QMetaObject::ReadProperty,
object->metaObject()->indexOfProperty("aliasedObject"), a);
QVERIFY(!alias2);
}
@@ -1790,24 +1806,20 @@ void tst_qqmllanguage::aliasProperties()
{
QQmlComponent component(&engine, testFileUrl("alias.8.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("value").toInt(), 10);
-
- delete object;
}
// Complex composite type
{
QQmlComponent component(&engine, testFileUrl("alias.9.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("value").toInt(), 10);
-
- delete object;
}
// Valuetype alias
@@ -1815,7 +1827,7 @@ void tst_qqmllanguage::aliasProperties()
{
QQmlComponent component(&engine, testFileUrl("alias.10.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
// Read through alias
@@ -1827,15 +1839,13 @@ void tst_qqmllanguage::aliasProperties()
object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
-
- delete object;
}
// Valuetype sub-alias
{
QQmlComponent component(&engine, testFileUrl("alias.11.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
// Read through alias
@@ -1847,8 +1857,6 @@ void tst_qqmllanguage::aliasProperties()
object->setProperty("aliasProperty", QVariant(4));
QCOMPARE(object->property("aliasProperty").toInt(), 4);
QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
-
- delete object;
}
// Nested aliases with a qml file
@@ -1892,6 +1900,30 @@ void tst_qqmllanguage::aliasProperties()
QVERIFY(subObject->property("success").toBool());
}
+
+ // Property bindings on group properties that are actually aliases (QTBUG-51043)
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.15.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QPointer<QObject> subItem = qvariant_cast<QObject*>(object->property("symbol"));
+ QVERIFY(!subItem.isNull());
+
+ QCOMPARE(subItem->property("y").toInt(), 1);
+ }
+
+ // Alias to sub-object with binding (QTBUG-57041)
+ {
+ // This is shold *not* crash.
+ QQmlComponent component(&engine, testFileUrl("alias.16.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ }
}
// QTBUG-13374 Test that alias properties and signals can coexist
@@ -1899,10 +1931,9 @@ void tst_qqmllanguage::aliasPropertiesAndSignals()
{
QQmlComponent component(&engine, testFileUrl("aliasPropertiesAndSignals.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o);
QCOMPARE(o->property("test").toBool(), true);
- delete o;
}
// Test that the root element in a composite type can be a Component
@@ -1910,7 +1941,7 @@ void tst_qqmllanguage::componentCompositeType()
{
QQmlComponent component(&engine, testFileUrl("componentCompositeType.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -1944,11 +1975,9 @@ void tst_qqmllanguage::i18n()
QFETCH(QString, stringProperty);
QQmlComponent component(&engine, testFileUrl(file));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->stringProperty(), stringProperty);
-
- delete object;
}
// Check that the Component::onCompleted attached property works
@@ -1959,7 +1988,7 @@ void tst_qqmllanguage::onCompleted()
QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -1968,12 +1997,11 @@ void tst_qqmllanguage::onDestruction()
{
QQmlComponent component(&engine, testFileUrl("onDestruction.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
- delete object;
}
// Check that assignments to QQmlScriptString properties work
@@ -1983,7 +2011,7 @@ void tst_qqmllanguage::scriptString()
QQmlComponent component(&engine, testFileUrl("scriptString.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(!object->scriptProperty().isEmpty());
QCOMPARE(object->scriptProperty().stringLiteral(), QString());
@@ -1994,21 +2022,21 @@ void tst_qqmllanguage::scriptString()
const QQmlScriptStringPrivate *scriptPrivate = QQmlScriptStringPrivate::get(object->scriptProperty());
QVERIFY(scriptPrivate != nullptr);
QCOMPARE(scriptPrivate->script, QString("foo + bar"));
- QCOMPARE(scriptPrivate->scope, qobject_cast<QObject*>(object));
- QCOMPARE(scriptPrivate->context, qmlContext(object));
+ QCOMPARE(scriptPrivate->scope, qobject_cast<QObject*>(object.data()));
+ QCOMPARE(scriptPrivate->context, qmlContext(object.data()));
QVERIFY(object->grouped() != nullptr);
const QQmlScriptStringPrivate *groupedPrivate = QQmlScriptStringPrivate::get(object->grouped()->script());
QCOMPARE(groupedPrivate->script, QString("console.log(1921)"));
- QCOMPARE(groupedPrivate->scope, qobject_cast<QObject*>(object));
- QCOMPARE(groupedPrivate->context, qmlContext(object));
+ QCOMPARE(groupedPrivate->scope, qobject_cast<QObject*>(object.data()));
+ QCOMPARE(groupedPrivate->context, qmlContext(object.data()));
}
{
QQmlComponent component(&engine, testFileUrl("scriptString2.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->scriptProperty().stringLiteral(), QString("hello\\n\\\"world\\\""));
}
@@ -2017,7 +2045,7 @@ void tst_qqmllanguage::scriptString()
QQmlComponent component(&engine, testFileUrl("scriptString3.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
bool ok;
QCOMPARE(object->scriptProperty().numberLiteral(&ok), qreal(12.345));
@@ -2029,7 +2057,7 @@ void tst_qqmllanguage::scriptString()
QQmlComponent component(&engine, testFileUrl("scriptString4.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
bool ok;
QCOMPARE(object->scriptProperty().booleanLiteral(&ok), true);
@@ -2040,7 +2068,7 @@ void tst_qqmllanguage::scriptString()
QQmlComponent component(&engine, testFileUrl("scriptString5.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->scriptProperty().isNullLiteral(), true);
}
@@ -2049,7 +2077,7 @@ void tst_qqmllanguage::scriptString()
QQmlComponent component(&engine, testFileUrl("scriptString6.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->scriptProperty().isUndefinedLiteral(), true);
}
@@ -2057,12 +2085,12 @@ void tst_qqmllanguage::scriptString()
QQmlComponent component(&engine, testFileUrl("scriptString7.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
QQmlScriptString ss = object->scriptProperty();
{
- QQmlExpression expr(ss, /*context*/nullptr, object);
+ QQmlExpression expr(ss, /*context*/nullptr, object.data());
QCOMPARE(expr.evaluate().toInt(), int(100));
}
@@ -2083,9 +2111,9 @@ void tst_qqmllanguage::scriptStringJs()
QQmlComponent component(&engine, testFileUrl("scriptStringJs.qml"));
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
- QQmlContext *context = QQmlEngine::contextForObject(object);
+ QQmlContext *context = QQmlEngine::contextForObject(object.data());
QVERIFY(context != nullptr);
bool ok;
@@ -2097,7 +2125,7 @@ void tst_qqmllanguage::scriptStringJs()
QVERIFY(object->scriptProperty().numberLiteral(&ok) == 0.0 && !ok);
QVERIFY(!object->scriptProperty().booleanLiteral(&ok) && !ok);
- QJSValue inst = engine.newQObject(object);
+ QJSValue inst = engine.newQObject(object.data());
QJSValue func = engine.evaluate("function(value) { this.scriptProperty = value }");
func.callWithInstance(inst, QJSValueList() << "test a \"string ");
@@ -2187,7 +2215,7 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode()
QQmlComponent component(&engine, url);
VERIFY_ERRORS(0);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
QQmlScriptString ss = object->scriptProperty();
QVERIFY(!ss.isEmpty());
@@ -2199,11 +2227,11 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode()
const QQmlScriptStringPrivate *scriptPrivate = QQmlScriptStringPrivate::get(ss);
QVERIFY(scriptPrivate != nullptr);
QVERIFY(scriptPrivate->script.isEmpty());
- QCOMPARE(scriptPrivate->scope, qobject_cast<QObject*>(object));
- QCOMPARE(scriptPrivate->context, qmlContext(object));
+ QCOMPARE(scriptPrivate->scope, qobject_cast<QObject*>(object.data()));
+ QCOMPARE(scriptPrivate->context, qmlContext(object.data()));
{
- QQmlExpression expr(ss, /*context*/nullptr, object);
+ QQmlExpression expr(ss, /*context*/nullptr, object.data());
QCOMPARE(expr.evaluate().toInt(), int(100));
}
}
@@ -2214,22 +2242,22 @@ void tst_qqmllanguage::scriptStringComparison()
{
QQmlComponent component1(&engine, testFileUrl("scriptString.qml"));
QVERIFY(!component1.isError() && component1.errors().isEmpty());
- MyTypeObject *object1 = qobject_cast<MyTypeObject*>(component1.create());
+ QScopedPointer<MyTypeObject> object1(qobject_cast<MyTypeObject*>(component1.create()));
QVERIFY(object1 != nullptr);
QQmlComponent component2(&engine, testFileUrl("scriptString2.qml"));
QVERIFY(!component2.isError() && component2.errors().isEmpty());
- MyTypeObject *object2 = qobject_cast<MyTypeObject*>(component2.create());
+ QScopedPointer<MyTypeObject> object2(qobject_cast<MyTypeObject*>(component2.create()));
QVERIFY(object2 != nullptr);
QQmlComponent component3(&engine, testFileUrl("scriptString3.qml"));
QVERIFY(!component3.isError() && component3.errors().isEmpty());
- MyTypeObject *object3 = qobject_cast<MyTypeObject*>(component3.create());
+ QScopedPointer<MyTypeObject> object3(qobject_cast<MyTypeObject*>(component3.create()));
QVERIFY(object3 != nullptr);
//QJSValue inst1 = engine.newQObject(object1);
- QJSValue inst2 = engine.newQObject(object2);
- QJSValue inst3 = engine.newQObject(object3);
+ QJSValue inst2 = engine.newQObject(object2.data());
+ QJSValue inst3 = engine.newQObject(object3.data());
QJSValue func = engine.evaluate("function(value) { this.scriptProperty = value }");
const QString s = "hello\\n\\\"world\\\"";
@@ -2284,7 +2312,7 @@ void tst_qqmllanguage::scriptStringComparison()
// While this are two instances of the same object they are still considered different
// because the (none literal) script string may access variables which have different
// values in both instances and hence evaluated to different results.
- MyTypeObject *object1_2 = qobject_cast<MyTypeObject*>(component1.create());
+ QScopedPointer<MyTypeObject> object1_2(qobject_cast<MyTypeObject*>(component1.create()));
QVERIFY(object1_2 != nullptr);
QVERIFY(object1->scriptProperty() != object1_2->scriptProperty());
}
@@ -2296,7 +2324,7 @@ void tst_qqmllanguage::defaultPropertyListOrder()
QQmlComponent component(&engine, testFileUrl("defaultPropertyListOrder.qml"));
VERIFY_ERRORS(0);
- MyContainer *container = qobject_cast<MyContainer *>(component.create());
+ QScopedPointer<MyContainer> container(qobject_cast<MyContainer *>(component.create()));
QVERIFY(container != nullptr);
QCOMPARE(container->getChildren()->count(), 6);
@@ -2317,15 +2345,13 @@ void tst_qqmllanguage::declaredPropertyValues()
void tst_qqmllanguage::dontDoubleCallClassBegin()
{
QQmlComponent component(&engine, testFileUrl("dontDoubleCallClassBegin.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o);
MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object")));
QVERIFY(o2);
QCOMPARE(o2->classBeginCount(), 1);
QCOMPARE(o2->componentCompleteCount(), 1);
-
- delete o;
}
void tst_qqmllanguage::reservedWords_data()
@@ -2425,10 +2451,9 @@ void tst_qqmllanguage::testType(const QString& qml, const QString& type, const Q
QCOMPARE(actualerror.left(partialMatch ? expectederror.length(): -1),expectederror);
} else {
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(QString(object->metaObject()->className()), type);
- delete object;
}
engine.setImportPathList(defaultImportPathList);
@@ -2439,10 +2464,9 @@ void tst_qqmllanguage::inlineAssignmentsOverrideBindings()
{
QQmlComponent component(&engine, testFileUrl("inlineAssignmentsOverrideBindings.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test").toInt(), 11);
- delete o;
}
// QTBUG-19354
@@ -2873,10 +2897,9 @@ void tst_qqmllanguage::importsPath()
QTRY_VERIFY(component.isReady());
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("test").toString(), value);
- delete object;
engine.setImportPathList(defaultImportPathList);
}
@@ -3084,10 +3107,9 @@ void tst_qqmllanguage::importJs()
}
if (performTest) {
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("test").toBool(),true);
- delete object;
}
engine.setImportPathList(defaultImportPathList);
@@ -3136,21 +3158,21 @@ void tst_qqmllanguage::qmlAttachedPropertiesObjectMethod()
{
QQmlComponent component(&engine, testFileUrl("qmlAttachedPropertiesObjectMethod.1.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)nullptr);
- QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != nullptr);
+ QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object.data(), false), (QObject *)nullptr);
+ QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object.data(), true) != nullptr);
}
{
QQmlComponent component(&engine, testFileUrl("qmlAttachedPropertiesObjectMethod.2.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != nullptr);
- QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != nullptr);
+ QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object.data(), false) != nullptr);
+ QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object.data(), true) != nullptr);
}
}
@@ -3171,12 +3193,10 @@ void tst_qqmllanguage::customOnProperty()
QQmlComponent component(&engine, testFileUrl("customOnProperty.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("on").toInt(), 10);
-
- delete object;
}
// QTBUG-12601
@@ -3185,12 +3205,10 @@ void tst_qqmllanguage::variantNotify()
QQmlComponent component(&engine, testFileUrl("variantNotify.qml"));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("notifyCount").toInt(), 1);
-
- delete object;
}
void tst_qqmllanguage::revisions()
@@ -3199,38 +3217,32 @@ void tst_qqmllanguage::revisions()
QQmlComponent component(&engine, testFileUrl("revisions11.qml"));
VERIFY_ERRORS(0);
- MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create());
+ QScopedPointer<MyRevisionedClass> object(qobject_cast<MyRevisionedClass*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->prop2(), 10.0);
-
- delete object;
}
{
QQmlEngine myEngine;
QQmlComponent component(&myEngine, testFileUrl("revisionssub11.qml"));
VERIFY_ERRORS(0);
- MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create());
+ QScopedPointer<MyRevisionedSubclass> object(qobject_cast<MyRevisionedSubclass*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->prop1(), 10.0);
QCOMPARE(object->prop2(), 10.0);
QCOMPARE(object->prop3(), 10.0);
QCOMPARE(object->prop4(), 10.0);
-
- delete object;
}
{
QQmlComponent component(&engine, testFileUrl("versionedbase.qml"));
VERIFY_ERRORS(0);
- MySubclass *object = qobject_cast<MySubclass*>(component.create());
+ QScopedPointer<MySubclass> object(qobject_cast<MySubclass*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->prop1(), 10.0);
QCOMPARE(object->prop2(), 10.0);
-
- delete object;
}
}
@@ -3276,8 +3288,8 @@ void tst_qqmllanguage::subclassedUncreateableRevision()
QQmlComponent c(&engine);
QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
- QObject *obj = c.create();
- QCOMPARE(obj, static_cast<QObject*>(nullptr));
+ QScopedPointer<QObject> obj(c.create());
+ QCOMPARE(obj.data(), static_cast<QObject*>(nullptr));
QCOMPARE(c.errors().count(), 1);
QCOMPARE(c.errors().first().description(), QString("Cannot create MyUncreateableBaseClass"));
}
@@ -3288,17 +3300,16 @@ void tst_qqmllanguage::subclassedUncreateableRevision()
if (!shouldWork)
QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
if (!shouldWork) {
- QCOMPARE(obj, static_cast<QObject*>(nullptr));
+ QCOMPARE(obj.data(), static_cast<QObject*>(nullptr));
return;
}
QVERIFY(obj);
- MyUncreateableBaseClass *base = qobject_cast<MyUncreateableBaseClass*>(obj);
+ MyUncreateableBaseClass *base = qobject_cast<MyUncreateableBaseClass*>(obj.data());
QVERIFY(base);
QCOMPARE(base->property(prop.toLatin1()).toBool(), true);
- delete obj;
}
void tst_qqmllanguage::subclassedExtendedUncreateableRevision_data()
@@ -3332,8 +3343,8 @@ void tst_qqmllanguage::subclassedExtendedUncreateableRevision()
QQmlComponent c(&engine);
QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
- QObject *obj = c.create();
- QCOMPARE(obj, static_cast<QObject*>(nullptr));
+ QScopedPointer<QObject> obj(c.create());
+ QCOMPARE(obj.data(), static_cast<QObject*>(nullptr));
QCOMPARE(c.errors().count(), 1);
QCOMPARE(c.errors().first().description(), QString("Cannot create MyExtendedUncreateableBaseClass"));
}
@@ -3344,17 +3355,16 @@ void tst_qqmllanguage::subclassedExtendedUncreateableRevision()
if (!shouldWork)
QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
c.setData(qml.toUtf8(), QUrl::fromLocalFile(QDir::currentPath()));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
if (!shouldWork) {
- QCOMPARE(obj, static_cast<QObject*>(nullptr));
+ QCOMPARE(obj.data(), static_cast<QObject*>(nullptr));
return;
}
QVERIFY(obj);
- MyExtendedUncreateableBaseClass *base = qobject_cast<MyExtendedUncreateableBaseClass*>(obj);
+ MyExtendedUncreateableBaseClass *base = qobject_cast<MyExtendedUncreateableBaseClass*>(obj.data());
QVERIFY(base);
QCOMPARE(base->property(prop.toLatin1()).toBool(), true);
- delete obj;
}
void tst_qqmllanguage::uncreatableTypesAsProperties()
@@ -3415,12 +3425,10 @@ void tst_qqmllanguage::aliasPropertyChangeSignals()
QQmlComponent component(&engine, testFileUrl("aliasPropertyChangeSignals.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test").toBool(), true);
-
- delete o;
}
// QTCREATORBUG-2769
@@ -3428,12 +3436,10 @@ void tst_qqmllanguage::aliasPropertyChangeSignals()
QQmlComponent component(&engine, testFileUrl("aliasPropertyChangeSignals.2.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test").toBool(), true);
-
- delete o;
}
}
@@ -3444,24 +3450,20 @@ void tst_qqmllanguage::propertyInit()
QQmlComponent component(&engine, testFileUrl("propertyInit.1.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test").toInt(), 1);
-
- delete o;
}
{
QQmlComponent component(&engine, testFileUrl("propertyInit.2.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test").toInt(), 123);
-
- delete o;
}
}
@@ -3471,17 +3473,16 @@ void tst_qqmllanguage::registrationOrder()
{
QQmlComponent component(&engine, testFileUrl("registrationOrder.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->metaObject(), &MyVersion2Class::staticMetaObject);
- delete o;
}
void tst_qqmllanguage::readonly()
{
QQmlComponent component(&engine, testFileUrl("readonly.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test1").toInt(), 10);
@@ -3507,8 +3508,6 @@ void tst_qqmllanguage::readonly()
QCOMPARE(o->property("test1").toInt(), 10);
QCOMPARE(o->property("test2").toInt(), 22);
QCOMPARE(o->property("test3").toInt(), 2);
-
- delete o;
}
void tst_qqmllanguage::readonlyObjectProperties()
@@ -3533,7 +3532,7 @@ void tst_qqmllanguage::receivers()
{
QQmlComponent component(&engine, testFileUrl("receivers.qml"));
- MyReceiversTestObject *o = qobject_cast<MyReceiversTestObject*>(component.create());
+ QScopedPointer<MyReceiversTestObject> o(qobject_cast<MyReceiversTestObject*>(component.create()));
QVERIFY(o != nullptr);
QCOMPARE(o->mySignalCount(), 1);
QCOMPARE(o->propChangedCount(), 2);
@@ -3542,8 +3541,6 @@ void tst_qqmllanguage::receivers()
QVERIFY(o->isSignalConnected(QMetaMethod::fromSignal(&MyReceiversTestObject::mySignal)));
QVERIFY(o->isSignalConnected(QMetaMethod::fromSignal(&MyReceiversTestObject::propChanged)));
QVERIFY(!o->isSignalConnected(QMetaMethod::fromSignal(&MyReceiversTestObject::myUnconnectedSignal)));
-
- delete o;
}
void tst_qqmllanguage::registeredCompositeType()
@@ -3551,10 +3548,8 @@ void tst_qqmllanguage::registeredCompositeType()
QQmlComponent component(&engine, testFileUrl("registeredCompositeType.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
-
- delete o;
}
// QTBUG-43582
@@ -3563,14 +3558,12 @@ void tst_qqmllanguage::registeredCompositeTypeWithEnum()
QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeWithEnum.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("enumValue0").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue0));
QCOMPARE(o->property("enumValue42").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue42));
QCOMPARE(o->property("enumValue15").toInt(), static_cast<int>(MyCompositeBaseType::ScopedCompositeEnum::EnumValue15));
-
- delete o;
}
// QTBUG-43581
@@ -3579,12 +3572,10 @@ void tst_qqmllanguage::registeredCompositeTypeWithAttachedProperty()
QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeWithAttachedProperty.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("attachedProperty").toString(), QStringLiteral("test"));
-
- delete o;
}
// QTBUG-18268
@@ -3597,15 +3588,14 @@ void tst_qqmllanguage::remoteLoadCrash()
while (component.isLoading())
QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
- QObject *o = component.create();
- delete o;
+ QScopedPointer<QObject> o(component.create());
}
void tst_qqmllanguage::signalWithDefaultArg()
{
QQmlComponent component(&engine, testFileUrl("signalWithDefaultArg.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject *>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->property("signalCount").toInt(), 0);
@@ -3620,15 +3610,13 @@ void tst_qqmllanguage::signalWithDefaultArg()
QCOMPARE(object->property("signalArg").toInt(), 15);
- QMetaObject::invokeMethod(object, "emitNoArgSignal");
+ QMetaObject::invokeMethod(object.data(), "emitNoArgSignal");
QCOMPARE(object->property("signalCount").toInt(), 3);
QCOMPARE(object->property("signalArg").toInt(), 5);
- QMetaObject::invokeMethod(object, "emitArgSignal");
+ QMetaObject::invokeMethod(object.data(), "emitArgSignal");
QCOMPARE(object->property("signalCount").toInt(), 4);
QCOMPARE(object->property("signalArg").toInt(), 22);
-
- delete object;
}
void tst_qqmllanguage::signalParameterTypes()
@@ -3636,19 +3624,17 @@ void tst_qqmllanguage::signalParameterTypes()
// bound signal handlers
{
QQmlComponent component(&engine, testFileUrl("signalParameterTypes.1.qml"));
- QObject *obj = component.create();
+ QScopedPointer<QObject> obj(component.create());
QVERIFY(obj != nullptr);
QVERIFY(obj->property("success").toBool());
- delete obj;
}
// dynamic signal connections
{
QQmlComponent component(&engine, testFileUrl("signalParameterTypes.2.qml"));
- QObject *obj = component.create();
+ QScopedPointer<QObject> obj(component.create());
QVERIFY(obj != nullptr);
QVERIFY(obj->property("success").toBool());
- delete obj;
}
}
@@ -3661,7 +3647,7 @@ void tst_qqmllanguage::globalEnums()
QQmlComponent component(&engine, testFileUrl("globalEnums.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
MyEnum1Class *enum1Class = o->findChild<MyEnum1Class *>(QString::fromLatin1("enum1Class"));
@@ -3687,7 +3673,7 @@ void tst_qqmllanguage::globalEnums()
QSignalSpy signalA(enum2Class, SIGNAL(valueAChanged(MyEnum1Class::EnumA)));
QSignalSpy signalB(enum2Class, SIGNAL(valueBChanged(MyEnum2Class::EnumB)));
- QMetaObject::invokeMethod(o, "setEnumValues");
+ QMetaObject::invokeMethod(o.data(), "setEnumValues");
QVERIFY(enum1Class->getValue() == MyEnum1Class::A_13);
QVERIFY(enum2Class->getValueA() == MyEnum1Class::A_11);
@@ -3706,8 +3692,6 @@ void tst_qqmllanguage::globalEnums()
QVERIFY(enum2Class->property("dValue") == 2);
QVERIFY(enum2Class->property("eValue") == 14);
QVERIFY(enum2Class->property("e2Value") == 76);
-
- delete o;
}
void tst_qqmllanguage::lowercaseEnumRuntime_data()
@@ -3753,7 +3737,7 @@ void tst_qqmllanguage::scopedEnum()
{
QQmlComponent component(&engine, testFileUrl("scopedEnum.qml"));
- MyTypeObject *o = qobject_cast<MyTypeObject *>(component.create());
+ QScopedPointer<MyTypeObject> o(qobject_cast<MyTypeObject *>(component.create()));
QVERIFY(o != nullptr);
QCOMPARE(o->scopedEnum(), MyTypeObject::MyScopedEnum::ScopedVal1);
@@ -3761,7 +3745,7 @@ void tst_qqmllanguage::scopedEnum()
QCOMPARE(o->property("listValue").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal3);
QCOMPARE(o->property("noScope").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal1);
- QMetaObject::invokeMethod(o, "assignNewValue");
+ QMetaObject::invokeMethod(o.data(), "assignNewValue");
QCOMPARE(o->scopedEnum(), MyTypeObject::MyScopedEnum::ScopedVal2);
QCOMPARE(o->property("noScope").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal2);
}
@@ -3770,7 +3754,7 @@ void tst_qqmllanguage::qmlEnums()
{
{
QQmlComponent component(&engine, testFileUrl("TypeWithEnum.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o);
QCOMPARE(o->property("enumValue").toInt(), 1);
QCOMPARE(o->property("enumValue2").toInt(), 2);
@@ -3785,7 +3769,7 @@ void tst_qqmllanguage::qmlEnums()
{
QQmlComponent component(&engine, testFileUrl("usingTypeWithEnum.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o);
QCOMPARE(o->property("enumValue").toInt(), 1);
QCOMPARE(o->property("enumValue2").toInt(), 0);
@@ -3830,10 +3814,9 @@ void tst_qqmllanguage::literals()
QQmlComponent component(&engine, testFile("literals.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property(property.toLatin1()), value);
- delete object;
}
void tst_qqmllanguage::objectDeletionNotify_data()
@@ -3852,19 +3835,17 @@ void tst_qqmllanguage::objectDeletionNotify()
QQmlComponent component(&engine, testFile(file));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("success").toBool(), true);
- QMetaObject::invokeMethod(object, "destroyObject");
+ QMetaObject::invokeMethod(object.data(), "destroyObject");
// Process the deletion event
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
QCoreApplication::processEvents();
QCOMPARE(object->property("success").toBool(), true);
-
- delete object;
}
void tst_qqmllanguage::scopedProperties()
@@ -3898,7 +3879,7 @@ void tst_qqmllanguage::implicitImportsLast()
QQmlComponent component(&engine, testFile("localOrderTest.qml"));
VERIFY_ERRORS(0);
- QObject *object = qobject_cast<QObject *>(component.create());
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QVERIFY(QString(object->metaObject()->className()).startsWith(QLatin1String("QQuickMouseArea")));
QObject* object2 = object->property("item").value<QObject*>();
@@ -3918,10 +3899,10 @@ void tst_qqmllanguage::getSingletonInstance(QQmlEngine& engine, const char* file
QQmlComponent component(&engine, testFile(fileName));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- getSingletonInstance(object, propertyName, result);
+ getSingletonInstance(object.data(), propertyName, result);
}
void tst_qqmllanguage::getSingletonInstance(QObject* o, const char* propertyName, QObject** result /* out */)
@@ -3958,10 +3939,10 @@ void tst_qqmllanguage::compositeSingletonProperties()
{
QQmlComponent component(&engine, testFile("singletonTest1.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 125, "value2", -55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 125, "value2", -55);
}
// Checks that the addresses of the composite singletons used in the same
@@ -4012,15 +3993,15 @@ void tst_qqmllanguage::compositeSingletonQualifiedNamespace()
{
QQmlComponent component(&engine, testFile("singletonTest5.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 125, "value2", -55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 125, "value2", -55);
// lets verify that the singleton instance we are using is the same
// when loaded through another file (without namespace!)
QObject *s1 = nullptr;
- getSingletonInstance(o, "singletonInstance", &s1);
+ getSingletonInstance(o.data(), "singletonInstance", &s1);
QVERIFY(s1 != nullptr);
QObject* s2 = nullptr;
@@ -4037,16 +4018,16 @@ void tst_qqmllanguage::compositeSingletonModule()
QQmlComponent component(&engine, testFile("singletonTest6.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 125, "value2", -55);
- verifyCompositeSingletonPropertyValues(o, "value3", 125, "value4", -55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 125, "value2", -55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value3", 125, "value4", -55);
// lets verify that the singleton instance we are using is the same
// when loaded through another file
QObject *s1 = nullptr;
- getSingletonInstance(o, "singletonInstance", &s1);
+ getSingletonInstance(o.data(), "singletonInstance", &s1);
QVERIFY(s1 != nullptr);
QObject* s2 = nullptr;
@@ -4063,16 +4044,16 @@ void tst_qqmllanguage::compositeSingletonModuleVersioned()
QQmlComponent component(&engine, testFile("singletonTest7.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 225, "value2", 55);
- verifyCompositeSingletonPropertyValues(o, "value3", 225, "value4", 55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 225, "value2", 55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value3", 225, "value4", 55);
// lets verify that the singleton instance we are using is the same
// when loaded through another file
QObject *s1 = nullptr;
- getSingletonInstance(o, "singletonInstance", &s1);
+ getSingletonInstance(o.data(), "singletonInstance", &s1);
QVERIFY(s1 != nullptr);
QObject* s2 = nullptr;
@@ -4089,16 +4070,16 @@ void tst_qqmllanguage::compositeSingletonModuleQualified()
QQmlComponent component(&engine, testFile("singletonTest8.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 225, "value2", 55);
- verifyCompositeSingletonPropertyValues(o, "value3", 225, "value4", 55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 225, "value2", 55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value3", 225, "value4", 55);
// lets verify that the singleton instance we are using is the same
// when loaded through another file
QObject *s1 = nullptr;
- getSingletonInstance(o, "singletonInstance", &s1);
+ getSingletonInstance(o.data(), "singletonInstance", &s1);
QVERIFY(s1 != nullptr);
QObject* s2 = nullptr;
@@ -4128,10 +4109,10 @@ void tst_qqmllanguage::compositeSingletonDynamicSignal()
{
QQmlComponent component(&engine, testFile("singletonTest11.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 99, "value2", -55);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", -55);
}
// Use qmlRegisterType to register a qml composite type with pragma Singleton defined in it.
@@ -4177,10 +4158,10 @@ void tst_qqmllanguage::compositeSingletonRemote()
QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 525, "value2", 355);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 525, "value2", 355);
}
// Load a composite singleton type and a javascript file that has .pragma library
@@ -4190,14 +4171,14 @@ void tst_qqmllanguage::compositeSingletonJavaScriptPragma()
{
QQmlComponent component(&engine, testFile("singletonTest16.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
// The value1 that is read from the SingletonType was changed from 125 to 99
// in compositeSingletonDynamicSignal() above. As the type is a singleton and
// the engine has not been destroyed, we just retrieve the old instance and
// the value is still 99.
- verifyCompositeSingletonPropertyValues(o, "value1", 99, "value2", 333);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", 333);
}
// Reads values from a Singleton accessed through selectors.
@@ -4208,10 +4189,10 @@ void tst_qqmllanguage::compositeSingletonSelectors()
qmlSelector.setExtraSelectors(QStringList() << "basicSelector");
QQmlComponent component(&e2, testFile("singletonTest1.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 625, "value2", 455);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 625, "value2", 455);
}
// Reads values from a Singleton that was registered through the C++ API:
@@ -4220,10 +4201,10 @@ void tst_qqmllanguage::compositeSingletonRegistered()
{
QQmlComponent component(&engine, testFile("singletonTest17.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
- verifyCompositeSingletonPropertyValues(o, "value1", 925, "value2", 755);
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 925, "value2", 755);
}
void tst_qqmllanguage::compositeSingletonCircular()
@@ -4233,7 +4214,7 @@ void tst_qqmllanguage::compositeSingletonCircular()
QQmlTestMessageHandler messageHandler;
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
// ensure we aren't hitting the recursion warning
@@ -4588,7 +4569,7 @@ void tst_qqmllanguage::noChildEvents()
QQmlComponent component(&engine);
component.setData("import QtQml 2.0; import Test 1.0; MyQmlObject { property QtObject child: QtObject {} }", QUrl());
VERIFY_ERRORS(0);
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->childAddedEventCount(), 0);
}
@@ -4608,10 +4589,10 @@ void tst_qqmllanguage::deleteSingletons()
QQmlEngine tmpEngine;
QQmlComponent component(&tmpEngine, testFile("singletonTest5.qml"));
VERIFY_ERRORS(0);
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QObject *s1 = nullptr;
- getSingletonInstance(o, "singletonInstance", &s1);
+ getSingletonInstance(o.data(), "singletonInstance", &s1);
QVERIFY(s1 != nullptr);
singleton = s1;
QVERIFY(singleton.data() != nullptr);
@@ -4635,7 +4616,7 @@ void tst_qqmllanguage::arrayBuffer()
QFETCH(QString, file);
QQmlComponent component(&engine, testFile(file));
VERIFY_ERRORS(0);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("ok").toBool(), true);
}
diff --git a/tests/auto/qml/qqmlproperty/data/aliasToIdWithMatchingQmlFileName.qml b/tests/auto/qml/qqmlproperty/data/aliasToIdWithMatchingQmlFileName.qml
new file mode 100644
index 0000000000..8cbd928f36
--- /dev/null
+++ b/tests/auto/qml/qqmlproperty/data/aliasToIdWithMatchingQmlFileName.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+Item {
+ property alias testType: testType
+
+ Rectangle {
+ id: testType
+ }
+}
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 128dc21b9a..1e9ba80264 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -143,6 +143,7 @@ private slots:
void registeredCompositeTypeProperty();
void deeplyNestedObject();
void readOnlyDynamicProperties();
+ void aliasToIdWithMatchingQmlFileNameOnCaseInsensitiveFileSystem();
void floatToStringPrecision_data();
void floatToStringPrecision();
@@ -2047,6 +2048,17 @@ void tst_qqmlproperty::readOnlyDynamicProperties()
delete obj;
}
+void tst_qqmlproperty::aliasToIdWithMatchingQmlFileNameOnCaseInsensitiveFileSystem()
+{
+ const QUrl url = testFileUrl("aliasToIdWithMatchingQmlFileName.qml");
+ QQmlEngine engine;
+ QQmlComponent component(&engine, url);
+ QScopedPointer<QObject> root(component.create());
+
+ QQmlProperty property(root.data(), "testType.objectName", QQmlEngine::contextForObject(root.data()));
+ QVERIFY(property.isValid());
+}
+
void tst_qqmlproperty::floatToStringPrecision_data()
{
QTest::addColumn<QString>("propertyName");
diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST
deleted file mode 100644
index 817eb472a4..0000000000
--- a/tests/auto/quick/qquickmousearea/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-# QTBUG-63786
-[pressedMultipleButtons]
-*
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index ea55c25761..aa379e834e 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -1578,91 +1578,85 @@ void tst_QQuickMouseArea::transformedMouseArea()
}
}
+struct MouseEvent {
+ QEvent::Type type;
+ Qt::MouseButton button;
+};
+Q_DECLARE_METATYPE(MouseEvent)
+
void tst_QQuickMouseArea::pressedMultipleButtons_data()
{
QTest::addColumn<Qt::MouseButtons>("accepted");
- QTest::addColumn<QList<Qt::MouseButtons> >("buttons");
+ QTest::addColumn<QList<MouseEvent> >("mouseEvents");
QTest::addColumn<QList<bool> >("pressed");
QTest::addColumn<QList<Qt::MouseButtons> >("pressedButtons");
QTest::addColumn<int>("changeCount");
- QList<Qt::MouseButtons> buttons;
+ Qt::MouseButtons accepted;
+ QList<MouseEvent> mouseEvents;
QList<bool> pressed;
QList<Qt::MouseButtons> pressedButtons;
- buttons << Qt::LeftButton
- << (Qt::LeftButton | Qt::RightButton)
- << Qt::LeftButton
- << nullptr;
- pressed << true
- << true
- << true
- << false;
- pressedButtons << Qt::LeftButton
- << Qt::LeftButton
- << Qt::LeftButton
- << nullptr;
- QTest::newRow("Accept Left - Press left, Press Right, Release Right")
- << Qt::MouseButtons(Qt::LeftButton) << buttons << pressed << pressedButtons << 2;
-
- buttons.clear();
- pressed.clear();
- pressedButtons.clear();
- buttons << Qt::LeftButton
- << (Qt::LeftButton | Qt::RightButton)
- << Qt::RightButton
- << nullptr;
- pressed << true
- << true
- << false
- << false;
- pressedButtons << Qt::LeftButton
- << Qt::LeftButton
- << nullptr
- << nullptr;
- QTest::newRow("Accept Left - Press left, Press Right, Release Left")
- << Qt::MouseButtons(Qt::LeftButton) << buttons << pressed << pressedButtons << 2;
-
- buttons.clear();
- pressed.clear();
- pressedButtons.clear();
- buttons << Qt::LeftButton
- << (Qt::LeftButton | Qt::RightButton)
- << Qt::LeftButton
- << nullptr;
- pressed << true
- << true
- << true
- << false;
- pressedButtons << Qt::LeftButton
- << (Qt::LeftButton | Qt::RightButton)
- << Qt::LeftButton
- << nullptr;
- QTest::newRow("Accept Left|Right - Press left, Press Right, Release Right")
- << (Qt::LeftButton | Qt::RightButton) << buttons << pressed << pressedButtons << 4;
-
- buttons.clear();
- pressed.clear();
- pressedButtons.clear();
- buttons << Qt::RightButton
- << (Qt::LeftButton | Qt::RightButton)
- << Qt::LeftButton
- << nullptr;
- pressed << true
- << true
- << false
- << false;
- pressedButtons << Qt::RightButton
- << Qt::RightButton
- << nullptr
- << nullptr;
- QTest::newRow("Accept Right - Press Right, Press Left, Release Right")
- << Qt::MouseButtons(Qt::RightButton) << buttons << pressed << pressedButtons << 2;
+ int changeCount;
+
+ MouseEvent leftPress = { QEvent::MouseButtonPress, Qt::LeftButton };
+ MouseEvent leftRelease = { QEvent::MouseButtonRelease, Qt::LeftButton };
+ MouseEvent rightPress = { QEvent::MouseButtonPress, Qt::RightButton };
+ MouseEvent rightRelease = { QEvent::MouseButtonRelease, Qt::RightButton };
+
+ auto addRowWithFormattedTitleAndReset = [&]() {
+ QByteArray title;
+ title.append("Accept:");
+ if (accepted & Qt::LeftButton)
+ title.append(" LeftButton");
+ if (accepted & Qt::RightButton)
+ title.append(" RightButton");
+ title.append(" | Events:");
+ for (MouseEvent event : mouseEvents) {
+ title.append(event.type == QEvent::MouseButtonPress ? " Press" : " Release");
+ title.append(event.button == Qt::LeftButton ? " Left," : " Right,");
+ }
+ title.chop(1); // remove last comma
+ QTest::newRow(title) << accepted << mouseEvents << pressed << pressedButtons << changeCount;
+
+ mouseEvents.clear();
+ pressed.clear();
+ pressedButtons.clear();
+ };
+
+ accepted = Qt::LeftButton;
+ changeCount = 2;
+ mouseEvents << leftPress << rightPress << rightRelease << leftRelease;
+ pressed << true << true << true << false;
+ pressedButtons << Qt::LeftButton << Qt::LeftButton << Qt::LeftButton << Qt::NoButton;
+ addRowWithFormattedTitleAndReset();
+
+ accepted = Qt::LeftButton;
+ changeCount = 2;
+ mouseEvents << leftPress << rightPress << leftRelease << rightRelease;
+ pressed << true << true << false << false;
+ pressedButtons << Qt::LeftButton << Qt::LeftButton << Qt::NoButton << Qt::NoButton;
+ addRowWithFormattedTitleAndReset();
+
+ accepted = Qt::LeftButton | Qt::RightButton;
+ changeCount = 4;
+ mouseEvents << leftPress << rightPress << rightRelease << leftRelease;
+ pressed << true << true << true << false;
+ pressedButtons << Qt::LeftButton << (Qt::LeftButton | Qt::RightButton) << Qt::LeftButton
+ << Qt::NoButton;
+ addRowWithFormattedTitleAndReset();
+
+ accepted = Qt::RightButton;
+ changeCount = 2;
+ mouseEvents << rightPress << leftPress << rightRelease << leftRelease;
+ pressed << true << true << false << false;
+ pressedButtons << Qt::RightButton << Qt::RightButton << Qt::NoButton << Qt::NoButton;
+ addRowWithFormattedTitleAndReset();
}
void tst_QQuickMouseArea::pressedMultipleButtons()
{
QFETCH(Qt::MouseButtons, accepted);
- QFETCH(QList<Qt::MouseButtons>, buttons);
+ QFETCH(QList<MouseEvent>, mouseEvents);
QFETCH(QList<bool>, pressed);
QFETCH(QList<Qt::MouseButtons>, pressedButtons);
QFETCH(int, changeCount);
@@ -1681,21 +1675,17 @@ void tst_QQuickMouseArea::pressedMultipleButtons()
QSignalSpy pressedButtonsSpy(mouseArea, SIGNAL(pressedButtonsChanged()));
mouseArea->setAcceptedMouseButtons(accepted);
- QPoint point(10,10);
-
- for (int i = 0; i < buttons.count(); ++i) {
- int btns = buttons.at(i);
-
- // The windowsysteminterface takes care of sending releases
- QTest::mousePress(&view, (Qt::MouseButton)btns, Qt::NoModifier, point);
-
+ QPoint point(10, 10);
+ for (int i = 0; i < mouseEvents.count(); ++i) {
+ const MouseEvent mouseEvent = mouseEvents.at(i);
+ if (mouseEvent.type == QEvent::MouseButtonPress)
+ QTest::mousePress(&view, mouseEvent.button, Qt::NoModifier, point);
+ else
+ QTest::mouseRelease(&view, mouseEvent.button, Qt::NoModifier, point);
QCOMPARE(mouseArea->pressed(), pressed.at(i));
QCOMPARE(mouseArea->pressedButtons(), pressedButtons.at(i));
}
- QTest::mousePress(&view, Qt::NoButton, Qt::NoModifier, point);
- QCOMPARE(mouseArea->pressed(), false);
-
QCOMPARE(pressedSpy.count(), 2);
QCOMPARE(pressedButtonsSpy.count(), changeCount);
}