summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qml.pri2
-rw-r--r--src/declarative/qml/qmlbinding.cpp20
-rw-r--r--src/declarative/qml/qmlbinding.h12
-rw-r--r--src/declarative/qml/qmlbindingoptimizations.cpp32
-rw-r--r--src/declarative/qml/qmlbindingoptimizations_p.h9
-rw-r--r--src/declarative/qml/qmlcompiler.cpp47
-rw-r--r--src/declarative/qml/qmlcompiler_p.h3
-rw-r--r--src/declarative/qml/qmlcomponent.cpp2
-rw-r--r--src/declarative/qml/qmlinstruction.cpp3
-rw-r--r--src/declarative/qml/qmlinstruction_p.h6
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp86
-rw-r--r--src/declarative/qml/qmlmetaproperty.h9
-rw-r--r--src/declarative/qml/qmlmetaproperty_p.h9
-rw-r--r--src/declarative/qml/qmlmetatype.cpp29
-rw-r--r--src/declarative/qml/qmlmetatype.h14
-rw-r--r--src/declarative/qml/qmlparser.cpp3
-rw-r--r--src/declarative/qml/qmlparser_p.h2
-rw-r--r--src/declarative/qml/qmlvaluetype.cpp40
-rw-r--r--src/declarative/qml/qmlvaluetype_p.h19
-rw-r--r--src/declarative/qml/qmlvaluetypescriptclass.cpp2
-rw-r--r--src/declarative/qml/qmlvme.cpp86
-rw-r--r--src/declarative/qml/qmlvmemetaobject.cpp27
-rw-r--r--src/declarative/qml/qmlvmemetaobject_p.h4
23 files changed, 314 insertions, 152 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index a2e2050..2e62a3b 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -10,6 +10,7 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlcontext.cpp \
qml/qmlcustomparser.cpp \
qml/qmlpropertyvaluesource.cpp \
+ qml/qmlpropertyvalueinterceptor.cpp \
qml/qmlproxymetaobject.cpp \
qml/qmlvme.cpp \
qml/qmlcompiler.cpp \
@@ -59,6 +60,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlcustomparser_p.h \
qml/qmlcustomparser_p_p.h \
qml/qmlpropertyvaluesource.h \
+ qml/qmlpropertyvalueinterceptor.h \
qml/qmlboundsignal_p.h \
qml/qmlparserstatus.h \
qml/qmlproxymetaobject_p.h \
diff --git a/src/declarative/qml/qmlbinding.cpp b/src/declarative/qml/qmlbinding.cpp
index 3a34f46..907dcfa 100644
--- a/src/declarative/qml/qmlbinding.cpp
+++ b/src/declarative/qml/qmlbinding.cpp
@@ -97,7 +97,7 @@ QmlMetaProperty QmlBinding::property() const
return d->bindingData()->property;
}
-void QmlBinding::update()
+void QmlBinding::update(QmlMetaProperty::WriteFlags flags)
{
Q_D(QmlBinding);
@@ -119,17 +119,17 @@ void QmlBinding::update()
int idx = data->property.coreIndex();
Q_ASSERT(idx != -1);
- void *a[1];
+
QmlBinding *t = this;
- a[0] = (void *)&t;
- QMetaObject::metacall(data->property.object(),
+ int status = -1;
+ void *a[] = { &t, 0, &status, &flags };
+ QMetaObject::metacall(data->property.object(),
QMetaObject::WriteProperty,
idx, a);
} else {
-
QVariant value = this->value();
- data->property.write(value, QmlMetaProperty::Binding);
+ data->property.write(value, flags);
}
data->updating = false;
@@ -146,17 +146,17 @@ void QmlBinding::valueChanged()
update();
}
-void QmlBinding::setEnabled(bool e)
+void QmlBinding::setEnabled(bool e, QmlMetaProperty::WriteFlags flags)
{
Q_D(QmlBinding);
d->bindingData()->enabled = e;
setTrackChange(e);
- QmlAbstractBinding::setEnabled(e);
+ QmlAbstractBinding::setEnabled(e, flags);
if (e) {
addToObject(d->bindingData()->property.object());
- update();
+ update(flags);
} else {
removeFromObject();
}
@@ -231,7 +231,7 @@ QString QmlAbstractBinding::expression() const
return QLatin1String("<Unknown>");
}
-void QmlAbstractBinding::setEnabled(bool e)
+void QmlAbstractBinding::setEnabled(bool e, QmlMetaProperty::WriteFlags)
{
if (e) m_mePtr = 0;
}
diff --git a/src/declarative/qml/qmlbinding.h b/src/declarative/qml/qmlbinding.h
index e3a297c..bc5a42f 100644
--- a/src/declarative/qml/qmlbinding.h
+++ b/src/declarative/qml/qmlbinding.h
@@ -47,6 +47,7 @@
#include <QtDeclarative/qml.h>
#include <QtDeclarative/qmlpropertyvaluesource.h>
#include <QtDeclarative/qmlexpression.h>
+#include <QtCore/QMetaProperty>
QT_BEGIN_HEADER
@@ -62,10 +63,12 @@ public:
virtual QString expression() const;
- virtual void setEnabled(bool) = 0;
+ void setEnabled(bool e) { setEnabled(e, QmlMetaProperty::DontRemoveBinding); }
+ virtual void setEnabled(bool, QmlMetaProperty::WriteFlags) = 0;
virtual int propertyIndex() = 0;
- virtual void update() = 0;
+ void update() { update(QmlMetaProperty::DontRemoveBinding); }
+ virtual void update(QmlMetaProperty::WriteFlags) = 0;
void addToObject(QObject *);
void removeFromObject();
@@ -99,12 +102,13 @@ public:
bool enabled() const;
// Inherited from QmlAbstractBinding
- virtual void setEnabled(bool);
+ virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags);
virtual int propertyIndex();
+ virtual void update(QmlMetaProperty::WriteFlags flags);
virtual QString expression() const;
public Q_SLOTS:
- void update();
+ void update() { update(QmlMetaProperty::DontRemoveBinding); }
protected:
virtual void valueChanged();
diff --git a/src/declarative/qml/qmlbindingoptimizations.cpp b/src/declarative/qml/qmlbindingoptimizations.cpp
index e4ca358..6dc221e 100644
--- a/src/declarative/qml/qmlbindingoptimizations.cpp
+++ b/src/declarative/qml/qmlbindingoptimizations.cpp
@@ -69,16 +69,16 @@ QmlBinding_Id::~QmlBinding_Id()
removeFromContext();
}
-void QmlBinding_Id::setEnabled(bool e)
+void QmlBinding_Id::setEnabled(bool e, QmlMetaProperty::WriteFlags flags)
{
if (e) {
addToObject(m_object);
- update();
+ update(flags);
} else {
removeFromObject();
}
- QmlAbstractBinding::setEnabled(e);
+ QmlAbstractBinding::setEnabled(e, flags);
}
int QmlBinding_Id::propertyIndex()
@@ -86,7 +86,7 @@ int QmlBinding_Id::propertyIndex()
return m_propertyIdx;
}
-void QmlBinding_Id::update()
+void QmlBinding_Id::update(QmlMetaProperty::WriteFlags flags)
{
QmlContextPrivate *ctxtPriv =
static_cast<QmlContextPrivate *>(QObjectPrivate::get(context()));
@@ -102,7 +102,8 @@ void QmlBinding_Id::update()
}
QObject *o = ctxtPriv->idValues[m_id].data();
- void *a[] = { &o, 0 };
+ int status = -1;
+ void *a[] = { &o, 0, &status, &flags };
QMetaObject::metacall(m_object, QMetaObject::WriteProperty,
m_propertyIdx, a);
}
@@ -123,7 +124,9 @@ void QmlBinding_Id::reset()
removeFromContext();
QObject *o = 0;
- void *a[] = { &o, 0 };
+ int status = -1;
+ QmlMetaProperty::WriteFlags flags = QmlMetaProperty::DontRemoveBinding;
+ void *a[] = { &o, 0, &status, &flags };
QMetaObject::metacall(m_object, QMetaObject::WriteProperty,
m_propertyIdx, a);
}
@@ -150,17 +153,17 @@ QmlBinding_ObjProperty::QmlBinding_ObjProperty(QObject *object, int propertyIdx,
{
}
-void QmlBinding_ObjProperty::setEnabled(bool e)
+void QmlBinding_ObjProperty::setEnabled(bool e, QmlMetaProperty::WriteFlags flags)
{
m_enabled = e;
if (e) {
addToObject(m_object);
- update();
+ update(flags);
} else {
removeFromObject();
}
- QmlAbstractBinding::setEnabled(e);
+ QmlAbstractBinding::setEnabled(e, flags);
}
int QmlBinding_ObjProperty::propertyIndex()
@@ -168,21 +171,24 @@ int QmlBinding_ObjProperty::propertyIndex()
return m_propertyIdx;
}
-void QmlBinding_ObjProperty::update()
+void QmlBinding_ObjProperty::update(QmlMetaProperty::WriteFlags flags)
{
if (!m_enabled)
return;
QObject *value = 0;
- void *a[] = { &value, 0 };
+ int status = -1;
+ void *ra[] = { &value, 0, &status };
// Read
QMetaObject::metacall(m_context, QMetaObject::ReadProperty,
- m_contextIdx, a);
+ m_contextIdx, ra);
+
+ void *wa[] = { &value, 0, &status, &flags };
// Write
QMetaObject::metacall(m_object, QMetaObject::WriteProperty,
- m_propertyIdx, a);
+ m_propertyIdx, wa);
// Connect notify if needed. Only need to connect once, so we set
// m_notifyIdx back to -1 afterwards
diff --git a/src/declarative/qml/qmlbindingoptimizations_p.h b/src/declarative/qml/qmlbindingoptimizations_p.h
index 4862007..d0a4df4 100644
--- a/src/declarative/qml/qmlbindingoptimizations_p.h
+++ b/src/declarative/qml/qmlbindingoptimizations_p.h
@@ -69,9 +69,9 @@ public:
virtual ~QmlBinding_Id();
// Inherited from QmlAbstractBinding
- virtual void setEnabled(bool);
+ virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags);
virtual int propertyIndex();
- virtual void update();
+ virtual void update(QmlMetaProperty::WriteFlags flags);
void reset();
@@ -96,11 +96,12 @@ public:
QObject *context, int contextIdx, int notifyIdx);
// Inherited from QmlAbstractBinding
- virtual void setEnabled(bool);
+ virtual void setEnabled(bool, QmlMetaProperty::WriteFlags flags);
virtual int propertyIndex();
+ virtual void update(QmlMetaProperty::WriteFlags flags);
private Q_SLOTS:
- virtual void update();
+ void update() { update(QmlMetaProperty::DontRemoveBinding); }
private:
bool m_enabled;
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 12e8101..71f86d9 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -1521,6 +1521,24 @@ void QmlCompiler::genPropertyAssignment(QmlParser::Property *prop,
store.assignValueSource.castValue = valueType->propertyValueSourceCast();
output->bytecode << store;
+ } else if (v->type == Value::ValueInterceptor) {
+ genObject(v->object);
+
+ QmlInstruction store;
+ store.type = QmlInstruction::StoreValueInterceptor;
+ store.line = v->object->location.start.line;
+ if (valueTypeProperty) {
+ store.assignValueInterceptor.property = QmlMetaPropertyPrivate::saveValueType(valueTypeProperty->index, prop->index);
+ store.assignValueInterceptor.owner = 1;
+ } else {
+ store.assignValueInterceptor.property =
+ QmlMetaPropertyPrivate::saveProperty(prop->index);
+ store.assignValueInterceptor.owner = 0;
+ }
+ QmlType *valueType = QmlMetaType::qmlType(v->object->metatype);
+ store.assignValueInterceptor.castValue = valueType->propertyValueInterceptorCast();
+ output->bytecode << store;
+
} else if (v->type == Value::PropertyBinding) {
genBindingAssignment(v, prop, obj, valueTypeProperty);
@@ -1625,7 +1643,7 @@ bool QmlCompiler::buildAttachedProperty(QmlParser::Property *prop,
// font.pointSize: 12
// font.family: "Helvetica"
// }
-// font is a nested property. size and family are not.
+// font is a nested property. pointSize and family are not.
bool QmlCompiler::buildGroupedProperty(QmlParser::Property *prop,
QmlParser::Object *obj,
const BindingContext &ctxt)
@@ -1638,7 +1656,7 @@ bool QmlCompiler::buildGroupedProperty(QmlParser::Property *prop,
static_cast<QmlEnginePrivate *>(QObjectPrivate::get(engine));
if (ep->valueTypes[prop->type]) {
COMPILE_CHECK(buildValueTypeProperty(ep->valueTypes[prop->type],
- prop->value, ctxt.incr()));
+ prop->value, obj, ctxt.incr()));
obj->addValueTypeProperty(prop);
} else {
COMPILE_EXCEPTION(prop, "Invalid property access");
@@ -1662,6 +1680,7 @@ bool QmlCompiler::buildGroupedProperty(QmlParser::Property *prop,
bool QmlCompiler::buildValueTypeProperty(QObject *type,
QmlParser::Object *obj,
+ QmlParser::Object *baseObj,
const BindingContext &ctxt)
{
if (obj->defaultProperty)
@@ -1683,13 +1702,16 @@ bool QmlCompiler::buildValueTypeProperty(QObject *type,
if (value->object) {
bool isPropertyValue = output->types.at(value->object->type).type->propertyValueSourceCast() != -1;
- if (!isPropertyValue) {
+ bool isPropertyInterceptor = output->types.at(value->object->type).type->propertyValueInterceptorCast() != -1;
+ if (!isPropertyValue && !isPropertyInterceptor) {
COMPILE_EXCEPTION(prop, "Invalid property use");
} else {
COMPILE_CHECK(buildObject(value->object, ctxt));
- value->type = Value::ValueSource;
- }
+ if (isPropertyInterceptor && prop->parent->synthdata.isEmpty())
+ buildDynamicMeta(baseObj, ForceCreation);
+ value->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
+ }
} else if (value->value.isScript()) {
// ### Check for writability
BindingReference reference;
@@ -1854,8 +1876,12 @@ bool QmlCompiler::buildPropertyObjectAssignment(QmlParser::Property *prop,
// Will be true if the assigned type inherits QmlPropertyValueSource
bool isPropertyValue = false;
- if (QmlType *valueType = QmlMetaType::qmlType(v->object->metatype))
+ // Will be true if the assigned type inherits QmlPropertyValueInterceptor
+ bool isPropertyInterceptor = false;
+ if (QmlType *valueType = QmlMetaType::qmlType(v->object->metatype)) {
isPropertyValue = valueType->propertyValueSourceCast() != -1;
+ isPropertyInterceptor = valueType->propertyValueInterceptorCast() != -1;
+ }
// We want to raw metaObject here as the raw metaobject is the
// actual property type before we applied any extensions that might
@@ -1892,11 +1918,13 @@ bool QmlCompiler::buildPropertyObjectAssignment(QmlParser::Property *prop,
component->getDefaultProperty()->addValue(componentValue);
v->object = component;
COMPILE_CHECK(buildPropertyObjectAssignment(prop, obj, v, ctxt));
- } else if (isPropertyValue) {
+ } else if (isPropertyValue || isPropertyInterceptor) {
// Assign as a property value source
COMPILE_CHECK(buildObject(v->object, ctxt));
- v->type = Value::ValueSource;
+ if (isPropertyInterceptor && prop->parent->synthdata.isEmpty())
+ buildDynamicMeta(prop->parent, ForceCreation);
+ v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
} else {
COMPILE_EXCEPTION(v->object, "Cannot assign object to property");
}
@@ -2002,7 +2030,8 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode)
Q_ASSERT(obj);
Q_ASSERT(obj->metatype);
- if (obj->dynamicProperties.isEmpty() &&
+ if (mode != ForceCreation &&
+ obj->dynamicProperties.isEmpty() &&
obj->dynamicSignals.isEmpty() &&
obj->dynamicSlots.isEmpty())
return true;
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 1d27342..3a35d58 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -191,6 +191,7 @@ private:
const BindingContext &ctxt);
bool buildValueTypeProperty(QObject *type,
QmlParser::Object *obj,
+ QmlParser::Object *baseObj,
const BindingContext &ctxt);
bool buildListProperty(QmlParser::Property *prop,
QmlParser::Object *obj,
@@ -209,7 +210,7 @@ private:
bool doesPropertyExist(QmlParser::Property *prop, QmlParser::Object *obj);
bool testLiteralAssignment(const QMetaProperty &prop,
QmlParser::Value *value);
- enum DynamicMetaMode { IgnoreAliases, ResolveAliases };
+ enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation };
bool mergeDynamicMetaProperties(QmlParser::Object *obj);
bool buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode);
bool checkDynamicMeta(QmlParser::Object *obj);
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index 5b1cbeb..9a761b2 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -573,7 +573,7 @@ void QmlComponentPrivate::completeCreate()
bindValues.at(ii);
for (int jj = 0; jj < bv.count; ++jj) {
if(bv.at(jj))
- bv.at(jj)->setEnabled(true);
+ bv.at(jj)->setEnabled(true, QmlMetaProperty::BypassInterceptor | QmlMetaProperty::DontRemoveBinding);
}
QmlEnginePrivate::clear(bv);
}
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 18439f4..a465445 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -149,6 +149,9 @@ void QmlCompiledData::dump(QmlInstruction *instr, int idx)
case QmlInstruction::StoreValueSource:
qWarning() << idx << "\t" << line << "\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property << "\t" << instr->assignValueSource.castValue;
break;
+ case QmlInstruction::StoreValueInterceptor:
+ qWarning() << idx << "\t" << line << "\t" << "STORE_VALUE_INTERCEPTOR\t" << instr->assignValueInterceptor.property << "\t" << instr->assignValueInterceptor.castValue;
+ break;
case QmlInstruction::BeginObject:
qWarning() << idx << "\t" << line << "\t" << "BEGIN\t\t\t" << instr->begin.castValue;
break;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 1dcdace..88dff2d 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -130,6 +130,7 @@ public:
StoreIdOptBinding, /* assignIdOptBinding */
StoreObjPropBinding, /* assignObjPropBinding */
StoreValueSource, /* assignValueSource */
+ StoreValueInterceptor, /* assignValueInterceptor */
BeginObject, /* begin */
@@ -190,6 +191,11 @@ public:
} assignValueSource;
struct {
int property;
+ int owner;
+ int castValue;
+ } assignValueInterceptor; //### merge with above
+ struct {
+ int property;
int value;
short context;
short owner;
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index 302ce8c..7a7e074 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -559,17 +559,17 @@ QmlAbstractBinding *QmlMetaProperty::binding() const
is assumed by the caller.
*/
QmlAbstractBinding *
-QmlMetaProperty::setBinding(QmlAbstractBinding *newBinding) const
+QmlMetaProperty::setBinding(QmlAbstractBinding *newBinding, QmlMetaProperty::WriteFlags flags) const
{
if (!isProperty() || (type() & Attached) || !d->object)
return 0;
- return d->setBinding(d->object, d->core, newBinding);
+ return d->setBinding(d->object, d->core, newBinding, flags);
}
QmlAbstractBinding *
QmlMetaPropertyPrivate::setBinding(QObject *object, const QmlPropertyCache::Data &core,
- QmlAbstractBinding *newBinding)
+ QmlAbstractBinding *newBinding, QmlMetaProperty::WriteFlags flags)
{
QmlDeclarativeData *data = QmlDeclarativeData::get(object, 0 != newBinding);
@@ -581,7 +581,7 @@ QmlMetaPropertyPrivate::setBinding(QObject *object, const QmlPropertyCache::Data
binding->setEnabled(false);
if (newBinding)
- newBinding->setEnabled(true);
+ newBinding->setEnabled(true, flags);
return binding; // ### QmlAbstractBinding;
}
@@ -591,7 +591,7 @@ QmlMetaPropertyPrivate::setBinding(QObject *object, const QmlPropertyCache::Data
}
if (newBinding)
- newBinding->setEnabled(true);
+ newBinding->setEnabled(true, flags);
return 0;
}
@@ -752,11 +752,52 @@ QVariant QmlMetaPropertyPrivate::readValueProperty()
}
}
+//###
+//writeEnumProperty MIRRORS the relelvant bit of QMetaProperty::write AND MUST BE KEPT IN SYNC!
+//###
+bool QmlMetaPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags)
+{
+ if (!object || !prop.isWritable())
+ return false;
+
+ QVariant v = value;
+ uint t = QVariant::Invalid;
+ if (prop.isEnumType()) {
+ QMetaEnum menum = prop.enumerator();
+ if (v.type() == QVariant::String
+#ifdef QT3_SUPPORT
+ || v.type() == QVariant::CString
+#endif
+ ) {
+ if (prop.isFlagType())
+ v = QVariant(menum.keysToValue(value.toByteArray()));
+ else
+ v = QVariant(menum.keyToValue(value.toByteArray()));
+ } else if (v.type() != QVariant::Int && v.type() != QVariant::UInt) {
+ int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope()) + "::" + menum.name());
+ if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData())
+ return false;
+ v = QVariant(*reinterpret_cast<const int *>(v.constData()));
+ }
+ v.convert(QVariant::Int);
+ }
+
+ // the status variable is changed by qt_metacall to indicate what it did
+ // this feature is currently only used by QtDBus and should not be depended
+ // upon. Don't change it without looking into QDBusAbstractInterface first
+ // -1 (unchanged): normal qt_metacall, result stored in argv[0]
+ // changed: result stored directly in value, return the value of status
+ int status = -1;
+ void *argv[] = { v.data(), &v, &status, &flags };
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, idx, argv);
+ return status;
+}
+
void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
- QmlMetaProperty::WriteSource source)
+ QmlMetaProperty::WriteFlags flags)
{
// Remove any existing bindings on this property
- if (source != QmlMetaProperty::Binding)
+ if (!(flags & QmlMetaProperty::DontRemoveBinding))
delete q->setBinding(0);
uint type = q->type();
@@ -776,22 +817,23 @@ void QmlMetaPropertyPrivate::writeValueProperty(const QVariant &value,
QmlPropertyCache::Data data = core;
data.coreIndex = valueTypeCoreIdx;
data.propType = valueTypePropType;
- write(writeBack, data, value, context);
+ write(writeBack, data, value, context, flags);
- writeBack->write(object, core.coreIndex);
+ writeBack->write(object, core.coreIndex, flags);
if (!ep) delete writeBack;
} else {
- write(object, core, value, context);
+ write(object, core, value, context, flags);
}
}
void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data &property,
- const QVariant &value, QmlContext *context)
+ const QVariant &value, QmlContext *context, QmlMetaProperty::WriteFlags flags)
{
int coreIdx = property.coreIndex;
+ int status = -1; //for dbus
if (property.flags & QmlPropertyCache::Data::IsEnumType) {
QMetaProperty prop = object->metaObject()->property(property.coreIndex);
@@ -803,7 +845,7 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
if (qFuzzyCompare(fractional, (double)0.0))
v.convert(QVariant::Int);
}
- prop.write(object, v);
+ writeEnumProperty(prop, coreIdx, object, v, flags);
return;
}
@@ -836,14 +878,12 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
} else if (vt == t) {
- void *a[1];
- a[0] = (void *)value.constData();
+ void *a[] = { (void *)value.constData(), 0, &status, &flags };
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
} else if (qMetaTypeId<QVariant>() == t) {
- void *a[1];
- a[0] = (void *)&value;
+ void *a[] = { (void *)&value, 0, &status, &flags };
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
} else if (property.flags & QmlPropertyCache::Data::IsQObjectDerived) {
@@ -867,7 +907,7 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
if (valMo || !o) {
- void *args[] = { &o, 0 };
+ void *args[] = { &o, 0, &status, &flags };
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
args);
@@ -933,16 +973,14 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
QVariant v = value;
if (v.convert((QVariant::Type)t)) {
- void *a[1];
- a[0] = (void *)v.constData();
+ void *a[] = { (void *)v.constData(), 0, &status, &flags};
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
} else if ((uint)t >= QVariant::UserType && vt == QVariant::String) {
QmlMetaType::StringConverter con = QmlMetaType::customStringConverter(t);
if (con) {
QVariant v = con(value.toString());
if (v.userType() == t) {
- void *a[1];
- a[0] = (void *)v.constData();
+ void *a[] = { (void *)v.constData(), 0, &status, &flags};
QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a);
}
}
@@ -955,10 +993,10 @@ void QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data
*/
void QmlMetaProperty::write(const QVariant &value) const
{
- write(value, Other);
+ write(value, 0);
}
-void QmlMetaProperty::write(const QVariant &value, WriteSource source) const
+void QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const
{
if (!d->object)
return;
@@ -969,7 +1007,7 @@ void QmlMetaProperty::write(const QVariant &value, WriteSource source) const
} else if (d->core.isValid()) {
- d->writeValueProperty(value, source);
+ d->writeValueProperty(value, flags);
}
}
diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h
index 8c34ece..b0ae28c 100644
--- a/src/declarative/qml/qmlmetaproperty.h
+++ b/src/declarative/qml/qmlmetaproperty.h
@@ -88,8 +88,9 @@ public:
QVariant read() const;
void write(const QVariant &) const;
- enum WriteSource { Animation, Binding, Other };
- void write(const QVariant &, WriteSource) const;
+ enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02 };
+ Q_DECLARE_FLAGS(WriteFlags, WriteFlag)
+ void write(const QVariant &, QmlMetaProperty::WriteFlags) const;
bool hasChangedNotifier() const;
bool needsChangedNotifier() const;
@@ -126,7 +127,8 @@ public:
QMetaProperty property() const;
QmlAbstractBinding *binding() const;
- QmlAbstractBinding *setBinding(QmlAbstractBinding *) const;
+ QmlAbstractBinding *setBinding(QmlAbstractBinding *,
+ QmlMetaProperty::WriteFlags flags = QmlMetaProperty::DontRemoveBinding) const;
QmlExpression *signalExpression() const;
QmlExpression *setSignalExpression(QmlExpression *) const;
@@ -139,6 +141,7 @@ private:
QmlMetaPropertyPrivate *d;
};
typedef QList<QmlMetaProperty> QmlMetaProperties;
+ Q_DECLARE_OPERATORS_FOR_FLAGS(QmlMetaProperty::WriteFlags)
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlmetaproperty_p.h b/src/declarative/qml/qmlmetaproperty_p.h
index 00b9c3a..a856b90 100644
--- a/src/declarative/qml/qmlmetaproperty_p.h
+++ b/src/declarative/qml/qmlmetaproperty_p.h
@@ -99,9 +99,12 @@ public:
void writeSignalProperty(const QVariant &);
QVariant readValueProperty();
- void writeValueProperty(const QVariant &, QmlMetaProperty::WriteSource);
- static void write(QObject *, const QmlPropertyCache::Data &, const QVariant &, QmlContext *);
- static QmlAbstractBinding *setBinding(QObject *, const QmlPropertyCache::Data &, QmlAbstractBinding *);
+ void writeValueProperty(const QVariant &, QmlMetaProperty::WriteFlags);
+ static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object, const QVariant &value, int flags);
+ static void write(QObject *, const QmlPropertyCache::Data &, const QVariant &, QmlContext *,
+ QmlMetaProperty::WriteFlags flags = 0);
+ static QmlAbstractBinding *setBinding(QObject *, const QmlPropertyCache::Data &, QmlAbstractBinding *,
+ QmlMetaProperty::WriteFlags flags = QmlMetaProperty::DontRemoveBinding);
static quint32 saveValueType(int, int);
static quint32 saveProperty(int);
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index c40232f..5198f9f 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -128,6 +128,7 @@ public:
const QMetaObject *m_attachedPropertiesType;
int m_parserStatusCast;
int m_propertyValueSourceCast;
+ int m_propertyValueInterceptorCast;
QmlPrivate::CreateFunc m_extFunc;
const QMetaObject *m_extMetaObject;
int m_index;
@@ -140,8 +141,8 @@ public:
QmlTypePrivate::QmlTypePrivate()
: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_qmlListId(0),
m_opFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0),
- m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_extFunc(0), m_extMetaObject(0),
- m_index(-1), m_customParser(0), m_isSetup(false)
+ m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_propertyValueInterceptorCast(-1),
+ m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), m_isSetup(false)
{
}
@@ -169,7 +170,8 @@ QmlType::QmlType(int type, int listType, int qmlListType,
const QMetaObject *metaObject,
QmlAttachedPropertiesFunc attachedPropertiesFunc,
const QMetaObject *attachedType,
- int parserStatusCast, int propertyValueSourceCast, QmlPrivate::CreateFunc extFunc,
+ int parserStatusCast, int propertyValueSourceCast, int propertyValueInterceptorCast,
+ QmlPrivate::CreateFunc extFunc,
const QMetaObject *extMetaObject, int index,
QmlCustomParser *customParser)
: d(new QmlTypePrivate)
@@ -187,6 +189,7 @@ QmlType::QmlType(int type, int listType, int qmlListType,
d->m_attachedPropertiesType = attachedType;
d->m_parserStatusCast = parserStatusCast;
d->m_propertyValueSourceCast = propertyValueSourceCast;
+ d->m_propertyValueInterceptorCast = propertyValueInterceptorCast;
d->m_extFunc = extFunc;
d->m_index = index;
d->m_customParser = customParser;
@@ -412,6 +415,11 @@ int QmlType::propertyValueSourceCast() const
return d->m_propertyValueSourceCast;
}
+int QmlType::propertyValueInterceptorCast() const
+{
+ return d->m_propertyValueInterceptorCast;
+}
+
QVariant QmlType::fromObject(QObject *obj) const
{
QVariant rv;
@@ -467,7 +475,7 @@ int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id,
int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Func func,
const char *uri, int version_maj, int version_min_from, int version_min_to, const char *cname,
const QMetaObject *mo, QmlAttachedPropertiesFunc attach, const QMetaObject *attachMo,
- int pStatus, int object, int valueSource, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *parser)
+ int pStatus, int object, int valueSource, int valueInterceptor, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *parser)
{
Q_UNUSED(object);
@@ -492,7 +500,7 @@ int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Fun
QmlType *type = new QmlType(id.typeId, id.listId, id.qmlListId,
func, name, version_maj, version_min_from, version_min_to, mo, attach, attachMo, pStatus,
- valueSource, extFunc, extmo, index, parser);
+ valueSource, valueInterceptor, extFunc, extmo, index, parser);
data->types.append(type);
data->idToType.insert(type->typeId(), type);
@@ -539,6 +547,17 @@ int QmlMetaType::qmlPropertyValueSourceCast(int userType)
return -1;
}
+int QmlMetaType::qmlPropertyValueInterceptorCast(int userType)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QmlMetaTypeData *data = metaTypeData();
+ QmlType *type = data->idToType.value(userType);
+ if (type && type->typeId() == userType)
+ return type->propertyValueInterceptorCast();
+ else
+ return -1;
+}
+
QObject *QmlMetaType::toQObject(const QVariant &v)
{
if (!isObject(v.userType()))
diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h
index 02c817d..42c278c 100644
--- a/src/declarative/qml/qmlmetatype.h
+++ b/src/declarative/qml/qmlmetatype.h
@@ -48,6 +48,7 @@
#include <QtDeclarative/qmlprivate.h>
#include <QtDeclarative/qmlparserstatus.h>
#include <QtDeclarative/qmlpropertyvaluesource.h>
+#include <QtDeclarative/qmlpropertyvalueinterceptor.h>
QT_BEGIN_HEADER
@@ -60,7 +61,7 @@ class QmlCustomParser;
class Q_DECLARATIVE_EXPORT QmlMetaType
{
public:
- static int registerType(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *, int vmaj, int vmin_from, int vmin_to, const char *qmlName, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int pStatus, int object, int valueSource, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *);
+ static int registerType(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *, int vmaj, int vmin_from, int vmin_to, const char *qmlName, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int pStatus, int object, int valueSource, int valueInterceptor, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *);
static int registerInterface(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *);
static bool copy(int type, void *data, const void *copy = 0);
@@ -80,6 +81,7 @@ public:
static QObject *toQObject(const QVariant &);
static int qmlParserStatusCast(int);
static int qmlPropertyValueSourceCast(int);
+ static int qmlPropertyValueInterceptorCast(int);
static int listType(int);
static bool clear(const QVariant &);
static bool append(const QVariant &, const QVariant &);
@@ -146,6 +148,7 @@ public:
QVariant fromObject(QObject *) const;
const char *interfaceIId() const;
int propertyValueSourceCast() const;
+ int propertyValueInterceptorCast() const;
int index() const;
private:
@@ -153,7 +156,7 @@ private:
friend class QmlTypePrivate;
friend class QmlMetaTypeData;
QmlType(int, int, int, QmlPrivate::Func, const char *, int);
- QmlType(int, int, int, QmlPrivate::Func, const char *, int, int, int, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *);
+ QmlType(int, int, int, QmlPrivate::Func, const char *, int, int, int, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int, int, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *);
~QmlType();
QmlTypePrivate *d;
@@ -176,6 +179,7 @@ int qmlRegisterType(const char *typeName)
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueInterceptor>::cast(),
0, 0, 0);
}
@@ -196,7 +200,8 @@ int qmlRegisterType(const char *uri, int version_maj, int version_min_from, int
QmlPrivate::attachedPropertiesMetaObject<T>(),
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
- QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueInterceptor>::cast(),
0, 0, 0);
}
@@ -224,6 +229,7 @@ int qmlRegisterExtendedType(const char *typeName)
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueInterceptor>::cast(),
&QmlPrivate::CreateParent<E>::create, &E::staticMetaObject, 0);
}
@@ -253,6 +259,7 @@ int qmlRegisterExtendedType(const char *uri, int version_maj, int version_min_fr
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueInterceptor>::cast(),
&QmlPrivate::CreateParent<E>::create,
&E::staticMetaObject, 0);
}
@@ -290,6 +297,7 @@ int qmlRegisterCustomType(const char *uri, int version_maj, int version_min_from
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueInterceptor>::cast(),
0, 0, parser);
}
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index 8c46939..bae263a 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -282,6 +282,9 @@ void QmlParser::Value::dump(int indent) const
case Value::ValueSource:
type = "ValueSource";
break;
+ case Value::ValueInterceptor:
+ type = "ValueInterceptor";
+ break;
case Value::CreatedObject:
type = "CreatedObject";
break;
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 16862eb..e11e164 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -273,6 +273,8 @@ namespace QmlParser
PropertyBinding,
// This is used as a QmlPropertyValueSource assignment
ValueSource,
+ // This is used as a QmlPropertyValueInterceptor assignment
+ ValueInterceptor,
// This is used as a property QObject assignment
CreatedObject,
// This is used as a signal object assignment
diff --git a/src/declarative/qml/qmlvaluetype.cpp b/src/declarative/qml/qmlvaluetype.cpp
index 4ae2070..84c9ecb 100644
--- a/src/declarative/qml/qmlvaluetype.cpp
+++ b/src/declarative/qml/qmlvaluetype.cpp
@@ -97,9 +97,10 @@ void QmlPointFValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlPointFValueType::write(QObject *obj, int idx)
+void QmlPointFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &point, 0 };
+ int status = -1;
+ void *a[] = { &point, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
@@ -144,9 +145,10 @@ void QmlPointValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlPointValueType::write(QObject *obj, int idx)
+void QmlPointValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &point, 0 };
+ int status = -1;
+ void *a[] = { &point, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
@@ -191,9 +193,10 @@ void QmlSizeFValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlSizeFValueType::write(QObject *obj, int idx)
+void QmlSizeFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &size, 0 };
+ int status = -1;
+ void *a[] = { &size, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
@@ -238,9 +241,10 @@ void QmlSizeValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlSizeValueType::write(QObject *obj, int idx)
+void QmlSizeValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &size, 0 };
+ int status = -1;
+ void *a[] = { &size, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
@@ -285,9 +289,10 @@ void QmlRectFValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlRectFValueType::write(QObject *obj, int idx)
+void QmlRectFValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &rect, 0 };
+ int status = -1;
+ void *a[] = { &rect, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
@@ -352,9 +357,10 @@ void QmlRectValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlRectValueType::write(QObject *obj, int idx)
+void QmlRectValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &rect, 0 };
+ int status = -1;
+ void *a[] = { &rect, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
@@ -419,9 +425,10 @@ void QmlVector3DValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlVector3DValueType::write(QObject *obj, int idx)
+void QmlVector3DValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &vector, 0 };
+ int status = -1;
+ void *a[] = { &vector, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
@@ -476,9 +483,10 @@ void QmlFontValueType::read(QObject *obj, int idx)
QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a);
}
-void QmlFontValueType::write(QObject *obj, int idx)
+void QmlFontValueType::write(QObject *obj, int idx, QmlMetaProperty::WriteFlags flags)
{
- void *a[] = { &font, 0 };
+ int status = -1;
+ void *a[] = { &font, 0, &status, &flags };
QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a);
}
diff --git a/src/declarative/qml/qmlvaluetype_p.h b/src/declarative/qml/qmlvaluetype_p.h
index da5e972..d3adf1e 100644
--- a/src/declarative/qml/qmlvaluetype_p.h
+++ b/src/declarative/qml/qmlvaluetype_p.h
@@ -58,6 +58,7 @@
#include <QtCore/qvariant.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qfont.h>
+#include <QmlMetaProperty>
QT_BEGIN_NAMESPACE
@@ -67,7 +68,7 @@ class QmlValueType : public QObject
public:
QmlValueType(QObject *parent = 0);
virtual void read(QObject *, int) = 0;
- virtual void write(QObject *, int) = 0;
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags flags) = 0;
virtual QVariant value() = 0;
virtual void setValue(QVariant) = 0;
};
@@ -92,7 +93,7 @@ public:
QmlPointFValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
@@ -114,7 +115,7 @@ public:
QmlPointValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
@@ -136,7 +137,7 @@ public:
QmlSizeFValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
@@ -158,7 +159,7 @@ public:
QmlSizeValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
@@ -182,7 +183,7 @@ public:
QmlRectFValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
@@ -211,7 +212,7 @@ public:
QmlRectValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
@@ -239,7 +240,7 @@ public:
QmlVector3DValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
@@ -267,7 +268,7 @@ public:
QmlFontValueType(QObject *parent = 0);
virtual void read(QObject *, int);
- virtual void write(QObject *, int);
+ virtual void write(QObject *, int, QmlMetaProperty::WriteFlags);
virtual QVariant value();
virtual void setValue(QVariant value);
diff --git a/src/declarative/qml/qmlvaluetypescriptclass.cpp b/src/declarative/qml/qmlvaluetypescriptclass.cpp
index 6fd674a..6a7bdeb 100644
--- a/src/declarative/qml/qmlvaluetypescriptclass.cpp
+++ b/src/declarative/qml/qmlvaluetypescriptclass.cpp
@@ -132,7 +132,7 @@ void QmlValueTypeScriptClass::setProperty(QScriptValue &object,
ref.type->read(ref.object, ref.property);
QMetaProperty p = ref.type->metaObject()->property(id);
p.write(ref.type, v);
- ref.type->write(ref.object, ref.property);
+ ref.type->write(ref.object, ref.property, 0);
}
QVariant QmlValueTypeScriptClass::toVariant(const QScriptValue &val)
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index e4eef64..93c02b3 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -155,6 +155,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
QmlEnginePrivate *ep = QmlEnginePrivate::get(ctxt->engine());
QmlContextPrivate *cp = (QmlContextPrivate *)QObjectPrivate::get(ctxt);
+ int status = -1; //for dbus
+ QmlMetaProperty::WriteFlags flags = QmlMetaProperty::BypassInterceptor;
+
for (int ii = start; !isError() && ii < (start + count); ++ii) {
QmlInstruction &instr = comp->bytecode[ii];
@@ -275,10 +278,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreVariant:
{
QObject *target = stack.top();
- void *a[1];
// XXX - can be more efficient
QVariant v = QmlStringConverters::variantFromString(primitives.at(instr.storeString.value));
- a[0] = (void *)&v;
+ void *a[] = { &v, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeString.propertyIndex, a);
}
@@ -287,8 +289,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreString:
{
QObject *target = stack.top();
- void *a[1];
- a[0] = (void *)&primitives.at(instr.storeString.value);
+ void *a[] = { (void *)&primitives.at(instr.storeString.value), 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeString.propertyIndex, a);
}
@@ -297,9 +298,8 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreUrl:
{
QObject *target = stack.top();
- void *a[1];
QUrl u(primitives.at(instr.storeUrl.value));
- a[0] = (void *)&u;
+ void *a[] = { &u, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeUrl.propertyIndex, a);
}
@@ -309,8 +309,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
{
QObject *target = stack.top();
float f = instr.storeFloat.value;
- void *a[1];
- a[0] = &f;
+ void *a[] = { &f, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeFloat.propertyIndex, a);
}
@@ -320,8 +319,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
{
QObject *target = stack.top();
double d = instr.storeDouble.value;
- void *a[1];
- a[0] = &d;
+ void *a[] = { &d, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeDouble.propertyIndex, a);
}
@@ -330,8 +328,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreBool:
{
QObject *target = stack.top();
- void *a[1];
- a[0] = (void *)&instr.storeBool.value;
+ void *a[] = { (void *)&instr.storeBool.value, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeBool.propertyIndex, a);
}
@@ -340,8 +337,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreInteger:
{
QObject *target = stack.top();
- void *a[1];
- a[0] = (void *)&instr.storeInteger.value;
+ void *a[] = { (void *)&instr.storeInteger.value, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeInteger.propertyIndex, a);
}
@@ -350,9 +346,8 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreColor:
{
QObject *target = stack.top();
- void *a[1];
QColor c = QColor::fromRgba(instr.storeColor.value);
- a[0] = (void *)&c;
+ void *a[] = { &c, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeColor.propertyIndex, a);
}
@@ -361,9 +356,8 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreDate:
{
QObject *target = stack.top();
- void *a[1];
QDate d = QDate::fromJulianDay(instr.storeDate.value);
- a[0] = (void *)&d;
+ void *a[] = { &d, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeDate.propertyIndex, a);
}
@@ -372,13 +366,12 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreTime:
{
QObject *target = stack.top();
- void *a[1];
QTime t;
t.setHMS(intData.at(instr.storeTime.valueIndex),
intData.at(instr.storeTime.valueIndex+1),
intData.at(instr.storeTime.valueIndex+2),
intData.at(instr.storeTime.valueIndex+3));
- a[0] = (void *)&t;
+ void *a[] = { &t, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeTime.propertyIndex, a);
}
@@ -387,14 +380,13 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreDateTime:
{
QObject *target = stack.top();
- void *a[1];
QTime t;
t.setHMS(intData.at(instr.storeDateTime.valueIndex+1),
intData.at(instr.storeDateTime.valueIndex+2),
intData.at(instr.storeDateTime.valueIndex+3),
intData.at(instr.storeDateTime.valueIndex+4));
QDateTime dt(QDate::fromJulianDay(intData.at(instr.storeDateTime.valueIndex)), t);
- a[0] = (void *)&dt;
+ void *a[] = { &dt, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeDateTime.propertyIndex, a);
}
@@ -403,10 +395,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StorePoint:
{
QObject *target = stack.top();
- void *a[1];
QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex),
floatData.at(instr.storeRealPair.valueIndex+1)).toPoint();
- a[0] = (void *)&p;
+ void *a[] = { &p, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeRealPair.propertyIndex, a);
}
@@ -415,10 +406,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StorePointF:
{
QObject *target = stack.top();
- void *a[1];
QPointF p(floatData.at(instr.storeRealPair.valueIndex),
floatData.at(instr.storeRealPair.valueIndex+1));
- a[0] = (void *)&p;
+ void *a[] = { &p, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeRealPair.propertyIndex, a);
}
@@ -427,10 +417,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreSize:
{
QObject *target = stack.top();
- void *a[1];
QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex),
floatData.at(instr.storeRealPair.valueIndex+1)).toSize();
- a[0] = (void *)&p;
+ void *a[] = { &p, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeRealPair.propertyIndex, a);
}
@@ -439,10 +428,9 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreSizeF:
{
QObject *target = stack.top();
- void *a[1];
QSizeF s(floatData.at(instr.storeRealPair.valueIndex),
floatData.at(instr.storeRealPair.valueIndex+1));
- a[0] = (void *)&s;
+ void *a[] = { &s, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeRealPair.propertyIndex, a);
}
@@ -451,12 +439,11 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreRect:
{
QObject *target = stack.top();
- void *a[1];
QRect r = QRectF(floatData.at(instr.storeRect.valueIndex),
floatData.at(instr.storeRect.valueIndex+1),
floatData.at(instr.storeRect.valueIndex+2),
floatData.at(instr.storeRect.valueIndex+3)).toRect();
- a[0] = (void *)&r;
+ void *a[] = { &r, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeRect.propertyIndex, a);
}
@@ -465,12 +452,11 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreRectF:
{
QObject *target = stack.top();
- void *a[1];
QRectF r(floatData.at(instr.storeRect.valueIndex),
floatData.at(instr.storeRect.valueIndex+1),
floatData.at(instr.storeRect.valueIndex+2),
floatData.at(instr.storeRect.valueIndex+3));
- a[0] = (void *)&r;
+ void *a[] = { &r, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeRect.propertyIndex, a);
}
@@ -479,11 +465,10 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreVector3D:
{
QObject *target = stack.top();
- void *a[1];
QVector3D p(floatData.at(instr.storeVector3D.valueIndex),
floatData.at(instr.storeVector3D.valueIndex+1),
floatData.at(instr.storeVector3D.valueIndex+2));
- a[0] = (void *)&p;
+ void *a[] = { &p, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeVector3D.propertyIndex, a);
}
@@ -494,9 +479,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
QObject *assignObj = stack.pop();
QObject *target = stack.top();
- void *a[1];
- a[0] = (void *)&assignObj;
-
+ void *a[] = { (void *)&assignObj, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeObject.propertyIndex, a);
}
@@ -506,7 +489,6 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::AssignCustomType:
{
QObject *target = stack.top();
- void *a[1];
QmlCompiledData::CustomTypeData data = customTypeData.at(instr.assignCustomType.valueIndex);
const QString &primitive = primitives.at(data.index);
QmlMetaType::StringConverter converter =
@@ -518,7 +500,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
if (v.isNull() || ((int)prop.type() != data.type && prop.userType() != data.type))
VME_EXCEPTION("Cannot assign value" << primitive << "to property" << prop.name());
- a[0] = (void *)v.data();
+ void *a[] = { (void *)v.data(), 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.assignCustomType.propertyIndex, a);
}
@@ -654,6 +636,20 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
}
break;
+ case QmlInstruction::StoreValueInterceptor:
+ {
+ QObject *obj = stack.pop();
+ QmlPropertyValueInterceptor *vi = reinterpret_cast<QmlPropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.assignValueInterceptor.castValue);
+ QObject *target = stack.at(stack.count() - 1 - instr.assignValueInterceptor.owner);
+ QmlMetaProperty prop;
+ prop.restore(instr.assignValueInterceptor.property, target, ctxt);
+ obj->setParent(target);
+ vi->setTarget(prop);
+ QmlVMEMetaObject *mo = static_cast<QmlVMEMetaObject *>((QMetaObject*)target->metaObject());
+ mo->registerInterceptor(prop.coreIndex(), vi);
+ }
+ break;
+
case QmlInstruction::StoreObjectQmlList:
{
QObject *assign = stack.pop();
@@ -705,8 +701,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
QObject *target = stack.top();
QVariant v = QVariant::fromValue(assign);
- void *a[1];
- a[0] = (void *)&v;
+ void *a[] = { &v, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.storeObject.propertyIndex, a);
}
@@ -725,8 +720,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
if (iid) {
void *ptr = assign->qt_metacast(iid);
if (ptr) {
- void *a[1];
- a[0] = &ptr;
+ void *a[] = { &ptr, 0, &status, &flags };
QMetaObject::metacall(target,
QMetaObject::WriteProperty,
coreIdx, a);
@@ -848,7 +842,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
QmlValueType *valueHandler =
static_cast<QmlValueType *>(stack.pop());
QObject *target = stack.top();
- valueHandler->write(target, instr.fetchValue.property);
+ valueHandler->write(target, instr.fetchValue.property, QmlMetaProperty::BypassInterceptor);
}
break;
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index f473743..5ef1158 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -100,6 +100,24 @@ QmlVMEMetaObject::~QmlVMEMetaObject()
int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
{
int id = _id;
+ if(c == QMetaObject::WriteProperty) {
+ int flags = *reinterpret_cast<int*>(a[3]);
+ if (!(flags & QmlMetaProperty::BypassInterceptor)
+ && !aInterceptors.isEmpty()
+ && aInterceptors.testBit(id)) {
+ QmlPropertyValueInterceptor *vi = interceptors.value(id);
+ if (id >= propOffset) {
+ id -= propOffset;
+ if (id < metaData->propertyCount) {
+ vi->write(QVariant(data[id].type(), a[0]));
+ return -1;
+ }
+ } else {
+ vi->write(QVariant(property(id).type(), a[0]));
+ return -1;
+ }
+ }
+ }
if(c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty) {
if (id >= propOffset) {
id -= propOffset;
@@ -253,4 +271,13 @@ void QmlVMEMetaObject::listChanged(int id)
activate(object, methodOffset + id, 0);
}
+void QmlVMEMetaObject::registerInterceptor(int index, QmlPropertyValueInterceptor *interceptor)
+{
+ if (aInterceptors.isEmpty())
+ aInterceptors.resize(propertyCount() + metaData->propertyCount);
+ aInterceptors.setBit(index);
+ interceptors.insert(index, interceptor);
+}
+
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h
index 1c26241..d376f4c 100644
--- a/src/declarative/qml/qmlvmemetaobject_p.h
+++ b/src/declarative/qml/qmlvmemetaobject_p.h
@@ -104,6 +104,8 @@ public:
QmlRefCount * = 0);
~QmlVMEMetaObject();
+ void registerInterceptor(int index, QmlPropertyValueInterceptor *interceptor);
+
protected:
virtual int metaCall(QMetaObject::Call _c, int _id, void **_a);
@@ -117,6 +119,8 @@ private:
QVariant *data;
QBitArray aConnected;
+ QBitArray aInterceptors;
+ QHash<int, QmlPropertyValueInterceptor*> interceptors;
QAbstractDynamicMetaObject *parent;