aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-12-07 13:20:36 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2015-12-07 13:20:36 +0100
commit4ab7deb923237b0186a211b0326217c480e33848 (patch)
treee277fb616e58e02bb49e0dc62d1ff9a039e8bcdb /src
parentc3f03bbff1db14dc5b5436d8aef834512207d498 (diff)
parentbb921064b966efdaabc2245cad21c3d852848a22 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp3
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp3
-rw-r--r--src/qml/qml/qqmldata_p.h3
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp17
-rw-r--r--src/qml/qml/qqmlpropertyvalueinterceptor_p.h2
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp226
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h56
-rw-r--r--src/qml/types/qqmlbind.cpp46
-rw-r--r--src/quick/items/qquickevents.cpp5
-rw-r--r--src/quick/items/qquickitem.cpp58
-rw-r--r--src/quick/items/qquicklistview.cpp34
-rw-r--r--src/quick/items/qquicklistview_p.h2
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp8
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h1
-rw-r--r--src/quick/items/qquickrectangle_p.h2
-rw-r--r--src/quick/items/qquicktextinput.cpp11
-rw-r--r--src/quick/items/qquickwindow.cpp7
-rw-r--r--src/quickwidgets/qquickwidget.cpp8
19 files changed, 307 insertions, 187 deletions
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();