diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-12-07 13:20:36 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-12-07 13:20:36 +0100 |
commit | 4ab7deb923237b0186a211b0326217c480e33848 (patch) | |
tree | e277fb616e58e02bb49e0dc62d1ff9a039e8bcdb | |
parent | c3f03bbff1db14dc5b5436d8aef834512207d498 (diff) | |
parent | bb921064b966efdaabc2245cad21c3d852848a22 (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: Ica75a71062d0613e415f2433c5c22c2e251b37cd
38 files changed, 473 insertions, 226 deletions
diff --git a/examples/quick/mousearea/mousearea-wheel-example.qml b/examples/quick/mousearea/mousearea-wheel-example.qml index ca6518ec4b..861639811c 100644 --- a/examples/quick/mousearea/mousearea-wheel-example.qml +++ b/examples/quick/mousearea/mousearea-wheel-example.qml @@ -64,10 +64,9 @@ Rectangle { anchors.fill: parent onWheel: { if (wheel.modifiers & Qt.ControlModifier) { - if (wheel.angleDelta.y > 0) - parent.scaleFactor += 0.2; - else if (parent.scaleFactor - 0.2 >= 0.2) - parent.scaleFactor -= 0.2; + parent.scaleFactor += 0.2 * wheel.angleDelta.y / 120; + if (parent.scaleFactor < 0) + parent.scaleFactor = 0; } } } diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 6fef1ae372..16c4cb28ed 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1693,7 +1693,8 @@ static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4 } } - if (qmlEngine && !(resolver->flags & LookupsExcludeProperties)) { + if (member->kind != QV4::IR::Member::MemberOfIdObjectsArray && member->kind != QV4::IR::Member::MemberOfSingletonObject && + qmlEngine && !(resolver->flags & LookupsExcludeProperties)) { QQmlPropertyData *property = member->property; if (!property && metaObject) { if (QQmlPropertyData *candidate = metaObject->property(*member->name, /*object*/0, /*context*/0)) { diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 2944c7b421..be09a58fc9 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -729,7 +729,8 @@ ReturnedValue BoundFunction::construct(const Managed *that, CallData *dd) void BoundFunction::markObjects(Heap::Base *that, ExecutionEngine *e) { BoundFunction::Data *o = static_cast<BoundFunction::Data *>(that); - o->target->mark(e); + if (o->target) + o->target->mark(e); o->boundThis.mark(e); if (o->boundArgs) o->boundArgs->mark(e); diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 3d2a76693a..ef05dd1fd7 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -112,9 +112,10 @@ public: * v8 GC will check this flag, only deletes the objects when rootObjectInCreation is false. */ quint32 rootObjectInCreation:1; + quint32 hasInterceptorMetaObject:1; quint32 hasVMEMetaObject:1; quint32 parentFrozen:1; - quint32 dummy:22; + quint32 dummy:21; // When bindingBitsSize < 32, we store the binding bit flags inside // bindingBitsValue. When we need more than 32 bits, we allocated diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 4da19a5a5c..2d3d8aa03c 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -668,7 +668,7 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o) QQmlData::QQmlData() : ownedByQml1(false), ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), - hasVMEMetaObject(false), parentFrozen(false), bindingBitsSize(0), bindingBits(0), notifyList(0), context(0), outerContext(0), + hasInterceptorMetaObject(false), hasVMEMetaObject(false), parentFrozen(false), bindingBitsSize(0), bindingBits(0), notifyList(0), context(0), outerContext(0), bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), lineNumber(0), columnNumber(0), jsEngineId(0), compiledData(0), deferredData(0), propertyCache(0), guards(0), extendedData(0) diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index f096dfeea9..cb4bbbab77 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -859,11 +859,24 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con QQmlPropertyValueInterceptor *vi = reinterpret_cast<QQmlPropertyValueInterceptor *>(reinterpret_cast<char *>(createdSubObject) + valueInterceptorCast); QObject *target = createdSubObject->parent(); + if (targetCorePropertyData.isAlias()) { + int propIndex; + QQmlPropertyPrivate::findAliasTarget(target, targetCorePropertyData.coreIndex, &target, &propIndex); + QQmlData *data = QQmlData::get(target); + if (!data || !data->propertyCache) { + qWarning() << "can't resolve property alias for 'on' assignment"; + return false; + } + targetCorePropertyData = *data->propertyCache->property(propIndex); + } + QQmlProperty prop = QQmlPropertyPrivate::restore(target, targetCorePropertyData, context); + vi->setTarget(prop); - QQmlVMEMetaObject *mo = QQmlVMEMetaObject::get(target); - Q_ASSERT(mo); + QQmlInterceptorMetaObject *mo = QQmlInterceptorMetaObject::get(target); + if (!mo) + mo = new QQmlInterceptorMetaObject(target, QQmlData::get(target)->propertyCache); mo->registerInterceptor(prop.index(), QQmlPropertyPrivate::valueTypeCoreIndex(prop), vi); return true; } diff --git a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h index ea267f9c30..6403e85f2a 100644 --- a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h +++ b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h @@ -60,7 +60,7 @@ public: virtual void write(const QVariant &value) = 0; private: - friend class QQmlVMEMetaObject; + friend class QQmlInterceptorMetaObject; int m_coreIndex; int m_valueTypeCoreIndex; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index b1f2549035..00ecf813ce 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -130,7 +130,131 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() } } -QAbstractDynamicMetaObject *QQmlVMEMetaObject::toDynamicMetaObject(QObject *o) + +QQmlInterceptorMetaObject::QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache) + : object(obj), + cache(cache), + interceptors(0), + hasAssignedMetaObjectData(false) +{ + QObjectPrivate *op = QObjectPrivate::get(obj); + + if (op->metaObject) { + parent = op->metaObject; + // Use the extra flag in QBiPointer to know if we can safely cast parent.asT1() to QQmlVMEMetaObject* + parent.setFlagValue(QQmlData::get(obj)->hasVMEMetaObject); + } else { + parent = obj->metaObject(); + } + + op->metaObject = this; + QQmlData::get(obj)->hasInterceptorMetaObject = true; +} + +QQmlInterceptorMetaObject::~QQmlInterceptorMetaObject() +{ + +} + +void QQmlInterceptorMetaObject::registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor) +{ + interceptor->m_coreIndex = index; + interceptor->m_valueTypeCoreIndex = valueIndex; + interceptor->m_next = interceptors; + interceptors = interceptor; +} + +int QQmlInterceptorMetaObject::metaCall(QObject *o, QMetaObject::Call c, int id, void **a) +{ + Q_ASSERT(o == object); + Q_UNUSED(o); + + if (intercept(c, id, a)) + return -1; + return object->qt_metacall(c, id, a); +} + +bool QQmlInterceptorMetaObject::intercept(QMetaObject::Call c, int id, void **a) +{ + if (c == QMetaObject::WriteProperty && interceptors && + !(*reinterpret_cast<int*>(a[3]) & QQmlPropertyPrivate::BypassInterceptor)) { + + for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) { + if (vi->m_coreIndex != id) + continue; + + int valueIndex = vi->m_valueTypeCoreIndex; + int type = QQmlData::get(object)->propertyCache->property(id)->propType; + + if (type != QVariant::Invalid) { + if (valueIndex != -1) { + QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type); + Q_ASSERT(valueType); + + // + // Consider the following case: + // color c = { 0.1, 0.2, 0.3 } + // interceptor exists on c.r + // write { 0.2, 0.4, 0.6 } + // + // The interceptor may choose not to update the r component at this + // point (for example, a behavior that creates an animation). But we + // need to ensure that the g and b components are updated correctly. + // + // So we need to perform a full write where the value type is: + // r = old value, g = new value, b = new value + // + // And then call the interceptor which may or may not write the + // new value to the r component. + // + // This will ensure that the other components don't contain stale data + // and any relevant signals are emitted. + // + // To achieve this: + // (1) Store the new value type as a whole (needed due to + // aliasing between a[0] and static storage in value type). + // (2) Read the entire existing value type from object -> valueType temp. + // (3) Read the previous value of the component being changed + // from the valueType temp. + // (4) Write the entire new value type into the temp. + // (5) Overwrite the component being changed with the old value. + // (6) Perform a full write to the value type (which may emit signals etc). + // (7) Issue the interceptor call with the new component value. + // + + QMetaProperty valueProp = valueType->metaObject()->property(valueIndex); + QVariant newValue(type, a[0]); + + valueType->read(object, id); + QVariant prevComponentValue = valueProp.read(valueType); + + valueType->setValue(newValue); + QVariant newComponentValue = valueProp.read(valueType); + + // Don't apply the interceptor if the intercepted value has not changed + bool updated = false; + if (newComponentValue != prevComponentValue) { + valueProp.write(valueType, prevComponentValue); + valueType->write(object, id, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); + + vi->write(newComponentValue); + updated = true; + } + + if (updated) + return true; + } else { + vi->write(QVariant(type, a[0])); + return true; + } + } + } + } + return false; +} + + +QAbstractDynamicMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObject *o) { if (!hasAssignedMetaObjectData) { *static_cast<QMetaObject *>(this) = *cache->createMetaObject(); @@ -149,23 +273,13 @@ QAbstractDynamicMetaObject *QQmlVMEMetaObject::toDynamicMetaObject(QObject *o) QQmlVMEMetaObject::QQmlVMEMetaObject(QObject *obj, QQmlPropertyCache *cache, const QQmlVMEMetaData *meta) - : object(obj), - ctxt(QQmlData::get(obj, true)->outerContext), cache(cache), metaData(meta), - hasAssignedMetaObjectData(false), aliasEndpoints(0), - interceptors(0), methods(0) + : QQmlInterceptorMetaObject(obj, cache), + ctxt(QQmlData::get(obj, true)->outerContext), metaData(meta), + aliasEndpoints(0), + methods(0) { cache->addref(); - QObjectPrivate *op = QObjectPrivate::get(obj); - - if (op->metaObject) { - parent = op->metaObject; - // Use the extra flag in QBiPointer to know if we can safely cast parent.asT1() to QQmlVMEMetaObject* - parent.setFlagValue(QQmlData::get(obj)->hasVMEMetaObject); - } else - parent = obj->metaObject(); - - op->metaObject = this; QQmlData::get(obj)->hasVMEMetaObject = true; int qobject_type = qMetaTypeId<QObject*>(); @@ -471,80 +585,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * Q_UNUSED(o); int id = _id; - if (c == QMetaObject::WriteProperty && interceptors && - !(*reinterpret_cast<int*>(a[3]) & QQmlPropertyPrivate::BypassInterceptor)) { - - for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) { - if (vi->m_coreIndex != id) - continue; - - int valueIndex = vi->m_valueTypeCoreIndex; - int type = QQmlData::get(object)->propertyCache->property(id)->propType; - - if (type != QVariant::Invalid) { - if (valueIndex != -1) { - QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type); - Q_ASSERT(valueType); - - // - // Consider the following case: - // color c = { 0.1, 0.2, 0.3 } - // interceptor exists on c.r - // write { 0.2, 0.4, 0.6 } - // - // The interceptor may choose not to update the r component at this - // point (for example, a behavior that creates an animation). But we - // need to ensure that the g and b components are updated correctly. - // - // So we need to perform a full write where the value type is: - // r = old value, g = new value, b = new value - // - // And then call the interceptor which may or may not write the - // new value to the r component. - // - // This will ensure that the other components don't contain stale data - // and any relevant signals are emitted. - // - // To achieve this: - // (1) Store the new value type as a whole (needed due to - // aliasing between a[0] and static storage in value type). - // (2) Read the entire existing value type from object -> valueType temp. - // (3) Read the previous value of the component being changed - // from the valueType temp. - // (4) Write the entire new value type into the temp. - // (5) Overwrite the component being changed with the old value. - // (6) Perform a full write to the value type (which may emit signals etc). - // (7) Issue the interceptor call with the new component value. - // - - QMetaProperty valueProp = valueType->metaObject()->property(valueIndex); - QVariant newValue(type, a[0]); - valueType->read(object, id); - QVariant prevComponentValue = valueProp.read(valueType); - - valueType->setValue(newValue); - QVariant newComponentValue = valueProp.read(valueType); + if (intercept(c, _id, a)) + return -1; - // Don't apply the interceptor if the intercepted value has not changed - bool updated = false; - if (newComponentValue != prevComponentValue) { - valueProp.write(valueType, prevComponentValue); - valueType->write(object, id, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); - - vi->write(newComponentValue); - updated = true; - } - - if (updated) - return -1; - } else { - vi->write(QVariant(type, a[0])); - return -1; - } - } - } - } if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty) { if (id >= propOffset()) { id -= propOffset(); @@ -994,14 +1038,6 @@ void QQmlVMEMetaObject::list_clear(QQmlListProperty<QObject> *prop) static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), 0); } -void QQmlVMEMetaObject::registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor) -{ - interceptor->m_coreIndex = index; - interceptor->m_valueTypeCoreIndex = valueIndex; - interceptor->m_next = interceptors; - interceptors = interceptor; -} - quint16 QQmlVMEMetaObject::vmeMethodLineNumber(int index) { if (index < methodOffset()) { diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index af0742d2c6..7da44e3b82 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -148,17 +148,57 @@ public: int m_index; }; + +class Q_QML_PRIVATE_EXPORT QQmlInterceptorMetaObject : public QAbstractDynamicMetaObject +{ +public: + QQmlInterceptorMetaObject(QObject *obj, QQmlPropertyCache *cache); + ~QQmlInterceptorMetaObject(); + + void registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor); + + static QQmlInterceptorMetaObject *get(QObject *obj); + + virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *o); + + // Used by auto-tests for inspection + QQmlPropertyCache *propertyCache() const { return cache; } + +protected: + virtual int metaCall(QObject *o, QMetaObject::Call c, int id, void **a); + bool intercept(QMetaObject::Call c, int id, void **a); + +public: + QObject *object; + QQmlPropertyCache *cache; + QBiPointer<QDynamicMetaObjectData, const QMetaObject> parent; + + QQmlPropertyValueInterceptor *interceptors; + bool hasAssignedMetaObjectData; +}; + +inline QQmlInterceptorMetaObject *QQmlInterceptorMetaObject::get(QObject *obj) +{ + if (obj) { + if (QQmlData *data = QQmlData::get(obj)) { + if (data->hasInterceptorMetaObject) + return static_cast<QQmlInterceptorMetaObject *>(QObjectPrivate::get(obj)->metaObject); + } + } + + return 0; +} + class QQmlVMEVariant; class QQmlRefCount; class QQmlVMEMetaObjectEndpoint; -class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QAbstractDynamicMetaObject +class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject { public: QQmlVMEMetaObject(QObject *obj, QQmlPropertyCache *cache, const QQmlVMEMetaData *data); ~QQmlVMEMetaObject(); bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; - void registerInterceptor(int index, int valueIndex, QQmlPropertyValueInterceptor *interceptor); QV4::ReturnedValue vmeMethod(int index); quint16 vmeMethodLineNumber(int index); void setVmeMethod(int index, const QV4::Value &function); @@ -167,11 +207,6 @@ public: void connectAliasSignal(int index, bool indexInSignalRange); - virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *o); - - // Used by auto-tests for inspection - QQmlPropertyCache *propertyCache() const { return cache; } - static inline QQmlVMEMetaObject *get(QObject *o); static QQmlVMEMetaObject *getForProperty(QObject *o, int coreIndex); static QQmlVMEMetaObject *getForMethod(QObject *o, int coreIndex); @@ -185,9 +220,7 @@ public: friend class QQmlVMEVariantQObjectPtr; friend class QQmlPropertyCache; - QObject *object; QQmlGuardedContextData ctxt; - QQmlPropertyCache *cache; const QQmlVMEMetaData *metaData; inline int propOffset() const; @@ -195,7 +228,6 @@ public: inline int signalOffset() const; inline int signalCount() const; - bool hasAssignedMetaObjectData; QQmlVMEMetaObjectEndpoint *aliasEndpoints; QV4::WeakValue properties; @@ -233,8 +265,6 @@ public: void connectAlias(int aliasId); - QQmlPropertyValueInterceptor *interceptors; - QV4::PersistentValue *methods; QV4::ReturnedValue method(int); @@ -243,8 +273,6 @@ public: QVariant readPropertyAsVariant(int); void writeProperty(int, const QVariant &); - QBiPointer<QDynamicMetaObjectData, const QMetaObject> parent; - inline QQmlVMEMetaObject *parentVMEMetaObject() const; void listChanged(int); diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index bd893bd2f4..45b7edd316 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -50,29 +50,6 @@ QT_BEGIN_NAMESPACE -namespace { - -void validateProperty(QObject *target, const QString &propertyName, QObject *binding) -{ - if (!target) - return; - - const QMetaObject *mo = target->metaObject(); - const int index = mo->indexOfProperty(propertyName.toUtf8()); - if (index == -1) { - qmlInfo(binding) << "Property '" << propertyName << "' does not exist on " << QQmlMetaType::prettyTypeName(target) << "."; - return; - } - - const QMetaProperty mp = mo->property(index); - if (!mp.isWritable()) { - qmlInfo(binding) << "Property '" << propertyName << "' on " << QQmlMetaType::prettyTypeName(target) << " is read-only."; - return; - } -} - -} - class QQmlBindPrivate : public QObjectPrivate { public: @@ -86,8 +63,25 @@ public: QQmlNullableValue<QVariant> value; QQmlProperty prop; QQmlAbstractBinding::Ptr prevBind; + + void validate(QObject *binding) const; }; +void QQmlBindPrivate::validate(QObject *binding) const +{ + if (!obj) + return; + + if (!prop.isValid()) { + qmlInfo(binding) << "Property '" << propName << "' does not exist on " << QQmlMetaType::prettyTypeName(obj) << "."; + return; + } + + if (!prop.isWritable()) { + qmlInfo(binding) << "Property '" << propName << "' on " << QQmlMetaType::prettyTypeName(obj) << " is read-only."; + return; + } +} /*! \qmltype Binding @@ -211,8 +205,8 @@ void QQmlBind::setObject(QObject *obj) } d->obj = obj; if (d->componentComplete) { - validateProperty(d->obj, d->propName, this); d->prop = QQmlProperty(d->obj, d->propName); + d->validate(this); } eval(); } @@ -257,8 +251,8 @@ void QQmlBind::setProperty(const QString &p) } d->propName = p; if (d->componentComplete) { - validateProperty(d->obj, d->propName, this); d->prop = QQmlProperty(d->obj, d->propName); + d->validate(this); } eval(); } @@ -299,8 +293,8 @@ void QQmlBind::componentComplete() Q_D(QQmlBind); d->componentComplete = true; if (!d->prop.isValid()) { - validateProperty(d->obj, d->propName, this); d->prop = QQmlProperty(d->obj, d->propName); + d->validate(this); } eval(); } diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 520b9d46bb..88deefbd9a 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -352,10 +352,7 @@ Item { MouseArea { onWheel: { if (wheel.modifiers & Qt.ControlModifier) { - if (wheel.angleDelta.y > 0) - zoomIn(); - else - zoomOut(); + adjustZoom(wheel.angleDelta.y / 120); } } } diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 23d13c2fd4..b89482fb90 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4278,8 +4278,10 @@ void QQuickItem::polish() */ void QQuickItem::mapFromItem(QQmlV4Function *args) const { - if (args->length() == 0) + if (args->length() != 3 && args->length() != 5) { + args->v4engine()->throwTypeError(); return; + } QV4::ExecutionEngine *v4 = args->v4engine(); QV4::Scope scope(v4); @@ -4295,19 +4297,33 @@ void QQuickItem::mapFromItem(QQmlV4Function *args) const if (!itemObj && !item->isNull()) { qmlInfo(this) << "mapFromItem() given argument \"" << item->toQStringNoThrow() << "\" which is neither null nor an Item"; + args->v4engine()->throwTypeError(); return; } - QV4::ScopedValue v(scope); + QV4::ScopedValue vx(scope, (*args)[1]); + QV4::ScopedValue vy(scope, (*args)[2]); + + if (!vx->isNumber() || !vy->isNumber()) { + args->v4engine()->throwTypeError(); + return; + } - qreal x = (args->length() > 1) ? (v = (*args)[1])->asDouble() : 0; - qreal y = (args->length() > 2) ? (v = (*args)[2])->asDouble() : 0; + qreal x = vx->asDouble(); + qreal y = vy->asDouble(); QVariant result; if (args->length() > 3) { - qreal w = (v = (*args)[3])->asDouble(); - qreal h = (args->length() > 4) ? (v = (*args)[4])->asDouble() : 0; + QV4::ScopedValue vw(scope, (*args)[3]); + QV4::ScopedValue vh(scope, (*args)[4]); + if (!vw->isNumber() || !vh->isNumber()) { + args->v4engine()->throwTypeError(); + return; + } + qreal w = vw->asDouble(); + qreal h = vh->asDouble(); + result = mapRectFromItem(itemObj, QRectF(x, y, w, h)); } else { result = mapFromItem(itemObj, QPointF(x, y)); @@ -4350,8 +4366,10 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const */ void QQuickItem::mapToItem(QQmlV4Function *args) const { - if (args->length() == 0) + if (args->length() != 3 && args->length() != 5) { + args->v4engine()->throwTypeError(); return; + } QV4::ExecutionEngine *v4 = args->v4engine(); QV4::Scope scope(v4); @@ -4367,18 +4385,32 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const if (!itemObj && !item->isNull()) { qmlInfo(this) << "mapToItem() given argument \"" << item->toQStringNoThrow() << "\" which is neither null nor an Item"; + args->v4engine()->throwTypeError(); return; } - QV4::ScopedValue v(scope); - QVariant result; + QV4::ScopedValue vx(scope, (*args)[1]); + QV4::ScopedValue vy(scope, (*args)[2]); + + if (!vx->isNumber() || !vy->isNumber()) { + args->v4engine()->throwTypeError(); + return; + } - qreal x = (args->length() > 1) ? (v = (*args)[1])->asDouble() : 0; - qreal y = (args->length() > 2) ? (v = (*args)[2])->asDouble() : 0; + qreal x = vx->asDouble(); + qreal y = vy->asDouble(); + + QVariant result; if (args->length() > 3) { - qreal w = (v = (*args)[3])->asDouble(); - qreal h = (args->length() > 4) ? (v = (*args)[4])->asDouble() : 0; + QV4::ScopedValue vw(scope, (*args)[3]); + QV4::ScopedValue vh(scope, (*args)[4]); + if (!vw->isNumber() || !vh->isNumber()) { + args->v4engine()->throwTypeError(); + return; + } + qreal w = vw->asDouble(); + qreal h = vh->asDouble(); result = mapRectToItem(itemObj, QRectF(x, y, w, h)); } else { diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 955e1f1e00..8384d5b58c 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -81,6 +81,8 @@ public: bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) Q_DECL_OVERRIDE; void visibleItemsChanged() Q_DECL_OVERRIDE; + void removeItem(FxViewItem *item); + FxViewItem *newViewItem(int index, QQuickItem *item) Q_DECL_OVERRIDE; void initializeViewItem(FxViewItem *item) Q_DECL_OVERRIDE; bool releaseItem(FxViewItem *item) Q_DECL_OVERRIDE; @@ -249,7 +251,7 @@ public: } inline QQuickItem *section() const { - return attached ? static_cast<QQuickListViewAttached*>(attached)->m_sectionItem : 0; + return item && attached ? static_cast<QQuickListViewAttached*>(attached)->m_sectionItem : 0; } void setSection(QQuickItem *s) { static_cast<QQuickListViewAttached*>(attached)->m_sectionItem = s; @@ -699,6 +701,18 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal return changed; } +void QQuickListViewPrivate::removeItem(FxViewItem *item) +{ + if (item->transitionScheduledOrRunning()) { + qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << (QObject *)(item->item); + item->releaseAfterTransition = true; + releasePendingTransition.append(item); + } else { + qCDebug(lcItemViewDelegateLifecycle) << "\treleasing stationary item" << item->index << (QObject *)(item->item); + releaseItem(item); + } +} + bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) { FxViewItem *item = 0; @@ -721,13 +735,7 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer if (item->index != -1) visibleIndex++; visibleItems.removeAt(index); - if (item->transitionScheduledOrRunning()) { - qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << (QObject *)(item->item); - item->releaseAfterTransition = true; - releasePendingTransition.append(item); - } else { - releaseItem(item); - } + removeItem(item); if (index == 0) break; item = visibleItems.at(--index); @@ -743,13 +751,7 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer break; qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position() << (QObject *)(item->item); visibleItems.removeLast(); - if (item->transitionScheduledOrRunning()) { - qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << (QObject *)(item->item); - item->releaseAfterTransition = true; - releasePendingTransition.append(item); - } else { - releaseItem(item); - } + removeItem(item); changed = true; } @@ -1302,7 +1304,7 @@ bool QQuickListViewPrivate::showHeaderForIndex(int index) const bool QQuickListViewPrivate::showFooterForIndex(int index) const { - return index == model->count()-1; + return model && index == model->count()-1; } void QQuickListViewPrivate::updateFooter() diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h index 5f8be2ab02..74bdad2d69 100644 --- a/src/quick/items/qquicklistview_p.h +++ b/src/quick/items/qquicklistview_p.h @@ -196,7 +196,7 @@ public: ~QQuickListViewAttached() {} public: - QQuickItem *m_sectionItem; + QPointer<QQuickItem> m_sectionItem; }; diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index 13ace44f9a..9e658cc668 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -502,8 +502,9 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event) else if (event->type() == QEvent::MouseButtonRelease) _mouseQpaTouchPoint.setState(Qt::TouchPointReleased); else { // QEvent::MouseButtonPress + addTouchPoint(me); + started = true; _mouseQpaTouchPoint.setState(Qt::TouchPointPressed); - _pressedTouchPoints.append(_mouseTouchPoint); } touchPoints << _mouseQpaTouchPoint; isMouseEvent = true; @@ -729,9 +730,7 @@ void QQuickMultiPointTouchArea::mousePressEvent(QMouseEvent *event) return; if (_touchPoints.count() >= _minimumTouchPoints - 1 && _touchPoints.count() < _maximumTouchPoints) { - addTouchPoint(event); updateTouchData(event); - emit pressed(_pressedTouchPoints); } } @@ -762,10 +761,7 @@ void QQuickMultiPointTouchArea::mouseReleaseEvent(QMouseEvent *event) if (_mouseTouchPoint) { updateTouchData(event); - _mouseTouchPoint->setPressed(false); _mouseTouchPoint->setInUse(false); - _releasedTouchPoints.append(_mouseTouchPoint); - emit released(_releasedTouchPoints); _releasedTouchPoints.removeAll(_mouseTouchPoint); _mouseTouchPoint = Q_NULLPTR; } diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h index 792724a9c8..034fe6df89 100644 --- a/src/quick/items/qquickmultipointtoucharea_p.h +++ b/src/quick/items/qquickmultipointtoucharea_p.h @@ -83,6 +83,7 @@ public: _qmlDefined(qmlDefined), _inUse(false), _pressed(false), + _startX(0.0), _startY(0.0), _previousX(0.0), _previousY(0.0), _sceneX(0.0), _sceneY(0.0) {} diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index feca74cb41..7cd4868f4a 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickPen : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickPen : public QObject { Q_OBJECT diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index fe18fc2231..37b8b12fdd 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1536,7 +1536,8 @@ bool QQuickTextInput::event(QEvent* ev) || ke == QKeySequence::SelectEndOfBlock || ke == QKeySequence::SelectStartOfDocument || ke == QKeySequence::SelectAll - || ke == QKeySequence::SelectEndOfDocument) { + || ke == QKeySequence::SelectEndOfDocument + || ke == QKeySequence::DeleteCompleteLine) { ke->accept(); return true; } else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier @@ -4328,6 +4329,14 @@ void QQuickTextInputPrivate::processKeyEvent(QKeyEvent* event) else if (event == QKeySequence::DeleteStartOfWord) { if (!m_readOnly) deleteStartOfWord(); + } else if (event == QKeySequence::DeleteCompleteLine) { + if (!m_readOnly) { + selectAll(); +#ifndef QT_NO_CLIPBOARD + copy(); +#endif + del(); + } } #endif // QT_NO_SHORTCUT else { diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 9224c071fd..2ba802a19e 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1407,6 +1407,10 @@ bool QQuickWindow::event(QEvent *e) d->deliverNativeGestureEvent(d->contentItem, static_cast<QNativeGestureEvent*>(e)); break; #endif + case QEvent::ShortcutOverride: + if (d->activeFocusItem) + sendEvent(d->activeFocusItem, static_cast<QKeyEvent *>(e)); + return true; default: break; } @@ -2600,6 +2604,9 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e) QCoreApplication::sendEvent(item, e); } break; + case QEvent::ShortcutOverride: + QCoreApplication::sendEvent(item, e); + break; case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 875b68b3ac..063386ed8e 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -705,6 +705,7 @@ void QQuickWidgetPrivate::handleContextCreationFailure(const QSurfaceFormat &for void QQuickWidgetPrivate::createContext() { + Q_Q(QQuickWidget); // On hide-show we invalidate() but our context is kept. // We nonetheless need to initialize() again. const bool reinit = context && !offscreenWindow->openglContext(); @@ -716,10 +717,11 @@ void QQuickWidgetPrivate::createContext() context = new QOpenGLContext; context->setFormat(offscreenWindow->requestedFormat()); - if (qt_gl_global_share_context()) { + if (qt_gl_global_share_context()) context->setShareContext(qt_gl_global_share_context()); - context->setScreen(context->shareContext()->screen()); - } + else + context->setShareContext(QWidgetPrivate::get(q->window())->shareContext()); + context->setScreen(context->shareContext()->screen()); if (!context->create()) { const bool isEs = context->isOpenGLES(); diff --git a/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml b/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml index f723dc3e2e..d35ec84e23 100644 --- a/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml +++ b/tests/auto/qml/qqmlvaluetypeproviders/data/qtquickValueTypes.qml @@ -112,7 +112,7 @@ QtObject { if (m != Qt.matrix4x4(4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7)) qtquickTypeSuccess = false; if (m.toString() != "QMatrix4x4(4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7)") qtquickTypeSuccess = false; c = "blue"; - if (c.toString() != Qt.rgba(0,0,1,0).toString()) qtquickTypeSuccess = false; + if (c.toString() != Qt.rgba(0,0,1,1).toString()) qtquickTypeSuccess = false; if (c.toString() != "#0000FF" && c.toString() != "#0000ff") qtquickTypeSuccess = false; // color string converter is special // no string converter for fonts. } diff --git a/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml b/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml index 8701dae612..141404b067 100644 --- a/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml +++ b/tests/auto/qml/qqmlvaluetypes/data/color_compare.qml @@ -15,12 +15,12 @@ MyTypeObject { // compare different color.toString()s property bool colorToStringEqualsColorString: (color.toString() == colorToString) // true - property bool colorToStringEqualsDifferentAlphaString: (color.toString() == Qt.rgba(0.2, 0.88, 0.6, 0.44).toString()) // true + property bool colorToStringEqualsDifferentAlphaString: (color.toString() == Qt.rgba(0.2, 0.88, 0.6, 0.34).toString()) // true property bool colorToStringEqualsDifferentRgbaString: (color.toString() == Qt.rgba(0.3, 0.98, 0.7, 0.44).toString()) // false // compare colors to strings property bool colorEqualsColorString: (color == colorToString) // false - property bool colorEqualsDifferentAlphaString: (color == Qt.rgba(0.2, 0.88, 0.6, 0.44).toString()) // false + property bool colorEqualsDifferentAlphaString: (color == Qt.rgba(0.2, 0.88, 0.6, 0.34).toString()) // false property bool colorEqualsDifferentRgbaString: (color == Qt.rgba(0.3, 0.98, 0.7, 0.44).toString()) // false // compare colors to various value types diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index c8107e58bf..58755927b5 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -937,7 +937,7 @@ void tst_qqmlvaluetypes::color() QQmlComponent component(&engine, testFileUrl("color_compare.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); - QString colorString("#33e199"); + QString colorString("#5733e199"); QCOMPARE(object->property("colorToString").toString(), colorString); QCOMPARE(object->property("colorEqualsIdenticalRgba").toBool(), true); QCOMPARE(object->property("colorEqualsDifferentAlpha").toBool(), false); diff --git a/tests/auto/quick/qquickbehaviors/data/Accelerator.qml b/tests/auto/quick/qquickbehaviors/data/Accelerator.qml new file mode 100644 index 0000000000..a2b5146c3f --- /dev/null +++ b/tests/auto/quick/qquickbehaviors/data/Accelerator.qml @@ -0,0 +1,18 @@ +import QtQuick 2.3 + +Rectangle { + property alias value: range.width + color: "yellow" + Text { + text: 'value: ' + value + } + + Rectangle { + id: range + objectName: "range" + color: "red" + width: 0 + height: 5 + anchors.bottom: parent.bottom + } +} diff --git a/tests/auto/quick/qquickbehaviors/data/aliased.qml b/tests/auto/quick/qquickbehaviors/data/aliased.qml new file mode 100644 index 0000000000..e65e035d83 --- /dev/null +++ b/tests/auto/quick/qquickbehaviors/data/aliased.qml @@ -0,0 +1,39 @@ +import QtQuick 2.3 + +Rectangle { + width: 400 + height: 400 + id: rect + property bool accelerating : false + + Text { + anchors.centerIn: parent + text: "Press anywere to accelerate" + } + + Accelerator { + id: acc + objectName: "acc" + anchors.fill: parent + value: accelerating ? 400 : 0 + Behavior on value { + NumberAnimation { + duration: 500 + } + } + } + + MouseArea { + id: clicker + anchors.fill: parent + } + + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + accelerating: true + } + } +} diff --git a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp index 643bed4376..635958314f 100644 --- a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp +++ b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp @@ -76,6 +76,7 @@ private slots: void multipleChangesToValueType(); void currentValue(); void disabledWriteWhileRunning(); + void aliasedProperty(); }; void tst_qquickbehaviors::simpleBehavior() @@ -576,6 +577,23 @@ void tst_qquickbehaviors::disabledWriteWhileRunning() } } +void tst_qquickbehaviors::aliasedProperty() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("aliased.qml")); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create())); + QVERIFY2(!rect.isNull(), qPrintable(c.errorString())); + + QQuickItemPrivate::get(rect.data())->setState("moved"); + QScopedPointer<QQuickRectangle> acc(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("acc"))); + QScopedPointer<QQuickRectangle> range(qobject_cast<QQuickRectangle*>(acc->findChild<QQuickRectangle*>("range"))); + QTRY_VERIFY(acc->property("value").toDouble() > 0); + QTRY_VERIFY(range->width() > 0); + QTRY_VERIFY(acc->property("value").toDouble() < 400); + QTRY_VERIFY(range->width() < 400); + //i.e. the behavior has been triggered +} + QTEST_MAIN(tst_qquickbehaviors) #include "tst_qquickbehaviors.moc" diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp index 071ea0b494..265579ead2 100644 --- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp +++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp @@ -123,7 +123,7 @@ void tst_qquickborderimage::imageSource_data() << "<Unknown File>:2:1: QML BorderImage: Cannot open: " + testFileUrl("no-such-file.png").toString(); QTest::newRow("remote") << "/colors.png" << true << ""; QTest::newRow("remote not found") << "/no-such-file.png" << true - << "<Unknown File>:2:1: QML BorderImage: Error downloading {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; + << "<Unknown File>:2:1: QML BorderImage: Error transferring {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; } void tst_qquickborderimage::imageSource() diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp index 71e9d747f4..3975654694 100644 --- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp +++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp @@ -154,7 +154,7 @@ void tst_qquickimage::imageSource_data() if (QImageReader::supportedImageFormats().contains("svgz")) QTest::newRow("remote svgz") << "/heart.svgz" << 550.0 << 500.0 << true << false << false << ""; QTest::newRow("remote not found") << "/no-such-file.png" << 0.0 << 0.0 << true - << false << true << "<Unknown File>:2:1: QML Image: Error downloading {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; + << false << true << "<Unknown File>:2:1: QML Image: Error transferring {{ServerBaseUrl}}/no-such-file.png - server replied: Not found"; } diff --git a/tests/auto/quick/qquickitem2/data/mapCoordinates.qml b/tests/auto/quick/qquickitem2/data/mapCoordinates.qml index 0b0b15a767..a9c5030e12 100644 --- a/tests/auto/quick/qquickitem2/data/mapCoordinates.qml +++ b/tests/auto/quick/qquickitem2/data/mapCoordinates.qml @@ -65,12 +65,20 @@ Item { } function checkMapAToInvalid(x, y) { - var pos = itemA.mapToItem(1122, x, y) - return pos == undefined; + try { + itemA.mapToItem(1122, x, y) + } catch (e) { + return e instanceof TypeError + } + return false } function checkMapAFromInvalid(x, y) { - var pos = itemA.mapFromItem(1122, x, y) - return pos == undefined; + try { + itemA.mapFromItem(1122, x, y) + } catch (e) { + return e instanceof TypeError + } + return false } } diff --git a/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml b/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml index e21aab1f01..c127407eae 100644 --- a/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml +++ b/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml @@ -66,12 +66,20 @@ Item { } function checkMapAToInvalid(x, y, w, h) { - var pos = itemA.mapToItem(1122, x, y, w, h) - return pos == undefined; + try { + itemA.mapToItem(1122, x, y, w, h) + } catch (e) { + return e instanceof TypeError + } + return false; } function checkMapAFromInvalid(x, y, w, h) { - var pos = itemA.mapFromItem(1122, x, y, w, h) - return pos == undefined; + try { + itemA.mapFromItem(1122, x, y, w, h) + } catch (e) { + return e instanceof TypeError + } + return false; } } diff --git a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp index 0064212a78..0fc8a7f001 100644 --- a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp +++ b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp @@ -148,7 +148,7 @@ void tst_qquickpixmapcache::single() QString expectedError; if (neterror) { - expectedError = "Error downloading " + target.toString() + " - server replied: Not found"; + expectedError = "Error transferring " + target.toString() + " - server replied: Not found"; } else if (!exists) { expectedError = "Cannot open: " + target.toString(); } diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 3f37cf233b..46eae89024 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -2050,7 +2050,7 @@ void tst_qquicktext::embeddedImages_data() QTest::newRow("local") << testFileUrl("embeddedImagesLocalRelative.qml") << ""; QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << ""; QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml") - << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error downloading {{ServerBaseUrl}}/notexists.png - server replied: Not found"; + << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error transferring {{ServerBaseUrl}}/notexists.png - server replied: Not found"; QTest::newRow("remote-relative") << testFileUrl("embeddedImagesRemoteRelative.qml") << ""; } diff --git a/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml b/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml index 017bab97a7..1280a655f0 100644 --- a/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml +++ b/tests/auto/quick/qquicktextedit/data/hAlignVisual.qml @@ -10,5 +10,6 @@ Rectangle { anchors.centerIn: parent horizontalAlignment: Text.AlignLeft font.pointSize: 12 + font.family: "Times New Roman" } } diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index b0ab58538a..c7de73da88 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -2368,8 +2368,8 @@ void tst_qquicktextedit::positionAt() secondLine.setLineWidth(texteditObject->width()); layout.endLayout(); - qreal y0; - qreal y1; + qreal y0 = 0; + qreal y1 = 0; switch (verticalAlignment) { case QQuickTextEdit::AlignTop: @@ -5263,8 +5263,8 @@ void tst_qquicktextedit::embeddedImages_data() QTest::newRow("local") << testFileUrl("embeddedImagesLocalRelative.qml") << ""; QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << ""; QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml") - << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML TextEdit: Error downloading {{ServerBaseUrl}}/notexists.png - server replied: Not found"; - QTest::newRow("remote-relative") << testFileUrl("embeddedImagesRemoteRelative.qml") << ""; + << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML TextEdit: Error transferring {{ServerBaseUrl}}/notexists.png - server replied: Not found"; + QTest::newRow("remote") << testFileUrl("embeddedImagesRemoteRelative.qml") << ""; } void tst_qquicktextedit::embeddedImages() diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 493c03d00e..2a687b3c69 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -5087,6 +5087,10 @@ void tst_qquicktextinput::keySequence_data() << standard.at(0) << QKeySequence(QKeySequence::DeleteStartOfWord) << 7 << 7 << 4 << (standard.at(0).mid(0, 4) + standard.at(0).mid(7)) << QString() << QQuickTextInput::Normal << Qt::Key_Direction_L; + QTest::newRow("delete complete line") + << standard.at(0) << QKeySequence(QKeySequence::DeleteCompleteLine) << 0 << 0 + << 0 << QString() << QString() + << QQuickTextInput::Normal << Qt::Key_Direction_L; } void tst_qquicktextinput::keySequence() diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 240ddde6f1..ff559e7076 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -332,9 +332,8 @@ void printUsage() printf("\t-desktop.......................Force use of desktop GL (AA_UseDesktopOpenGL)\n"); printf("\t-gles..........................Force use of GLES (AA_UseOpenGLES)\n"); printf("\t-software......................Force use of software rendering (AA_UseOpenGLES)\n"); -#if 0 // FIXME: 5.6: Re-enable once attribute naming is final (QTBUG-46615) - printf("\t-no-scaling....................Disable High DPI scaling (AA_NoHighDpiScaling)\n"); -#endif + printf("\t-scaling.......................Enable High DPI scaling (AA_EnableHighDpiScaling)\n"); + printf("\t-no-scaling....................Disable High DPI scaling (AA_DisableHighDpiScaling)\n"); printf("\tDebugging options:\n"); printf("\t-verbose ..................... Print information about what qml is doing, like specific file urls being loaded.\n"); printf("\t-translation [file] .......... Load the given file as the translations file.\n"); @@ -506,10 +505,10 @@ int main(int argc, char *argv[]) QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); } else if (arg == QLatin1String("-desktop")) { QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); -#if 0 // FIXME: 5.6: Re-enable once attribute naming is final (QTBUG-46615) + } else if (arg == QLatin1String("-scaling")) { + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); } else if (arg == QLatin1String("-no-scaling")) { - QCoreApplication::setAttribute(Qt::AA_NoHighDpiScaling); -#endif + QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); } else { files << arg; } diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 36a5c5ab76..0f73afcc7b 100644 --- a/tools/qmlplugindump/main.cpp +++ b/tools/qmlplugindump/main.cpp @@ -75,6 +75,10 @@ #include <qt_windows.h> #endif + +static const uint qtQmlMajorVersion = 2; +static const uint qtQmlMinorVersion = 2; + QString pluginImportPath; bool verbose = false; bool creatable = true; @@ -1056,9 +1060,13 @@ int main(int argc, char *argv[]) getDependencies(engine, pluginImportUri, pluginImportVersion, &dependencies); compactDependencies(&dependencies); - // load the QtQml 2.2 builtins and the dependencies + QString qtQmlImportString = QString::fromLatin1("import QtQml %1.%2") + .arg(qtQmlMajorVersion) + .arg(qtQmlMinorVersion); + + // load the QtQml builtins and the dependencies { - QByteArray code("import QtQml 2.2"); + QByteArray code(qtQmlImportString.toUtf8()); foreach (const QString &moduleToImport, dependencies) { code.append("\nimport "); code.append(moduleToImport.toUtf8()); @@ -1089,14 +1097,40 @@ int main(int argc, char *argv[]) QSet<const QMetaObject *> metas; if (action == Builtins) { + foreach (const QMetaObject *m, defaultReachable) { + if (m->className() == QLatin1String("Qt")) { + metas.insert(m); + break; + } + } + } else if (pluginImportUri == QLatin1String("QtQml")) { + bool ok = false; + const uint major = pluginImportVersion.split('.')[0].toUInt(&ok, 10); + if (!ok) { + std::cerr << "Malformed version string \""<< qPrintable(pluginImportVersion) << "\"." + << std::endl; + return EXIT_INVALIDARGUMENTS; + } + if (major != qtQmlMajorVersion) { + std::cerr << "Unsupported version \"" << qPrintable(pluginImportVersion) + << "\": Major version number must be \"" << qtQmlMajorVersion << "\"." + << std::endl; + return EXIT_INVALIDARGUMENTS; + } metas = defaultReachable; + foreach (const QMetaObject *m, defaultReachable) { + if (m->className() == QLatin1String("Qt")) { + metas.remove(m); + break; + } + } } else { // find a valid QtQuick import QByteArray importCode; QQmlType *qtObjectType = QQmlMetaType::qmlType(&QObject::staticMetaObject); if (!qtObjectType) { std::cerr << "Could not find QtObject type" << std::endl; - importCode = QByteArray("import QtQml 2.2"); + importCode = qtQmlImportString.toUtf8(); } else { QString module = qtObjectType->qmlTypeName(); module = module.mid(0, module.lastIndexOf(QLatin1Char('/'))); diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp index 53bd0bfbad..fc4fc3e167 100644 --- a/tools/qmlscene/main.cpp +++ b/tools/qmlscene/main.cpp @@ -356,9 +356,8 @@ static void usage() puts(" --desktop..........................Force use of desktop GL (AA_UseDesktopOpenGL)"); puts(" --gles.............................Force use of GLES (AA_UseOpenGLES)"); puts(" --software.........................Force use of software rendering (AA_UseOpenGLES)"); -#if 0 // FIXME: 5.6: Re-enable once attribute naming is final (QTBUG-46615) - puts(" --no-scaling.......................Disable High DPI scaling (AA_NoHighDpiScaling)"); -#endif + puts(" --scaling..........................Enable High DPI scaling (AA_EnableHighDpiScaling)"); + puts(" --no-scaling.......................Disable High DPI scaling (AA_DisableHighDpiScaling)"); puts(" --verbose..........................Print version and graphical diagnostics for the run-time"); puts(" -I <path> ........................ Add <path> to the list of import paths"); puts(" -P <path> ........................ Add <path> to the list of plugin paths"); @@ -453,10 +452,10 @@ int main(int argc, char ** argv) options.applicationAttributes.append(Qt::AA_UseSoftwareOpenGL); else if (!qstrcmp(arg, "--desktop")) options.applicationAttributes.append(Qt::AA_UseDesktopOpenGL); -#if 0 // FIXME: 5.6: Re-enable once attribute naming is final (QTBUG-46615) + else if (!qstrcmp(arg, "--scaling")) + options.applicationAttributes.append(Qt::AA_EnableHighDpiScaling); else if (!qstrcmp(arg, "--no-scaling")) - options.applicationAttributes.append(Qt::AA_NoHighDpiScaling); -#endif + options.applicationAttributes.append(Qt::AA_DisableHighDpiScaling); } foreach (Qt::ApplicationAttribute a, options.applicationAttributes) |