aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlproperty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlproperty.cpp')
-rw-r--r--src/qml/qml/qqmlproperty.cpp184
1 files changed, 90 insertions, 94 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 087fbaa9bf..7af7848ddb 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -337,11 +337,44 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name)
QString signalName = terminal.mid(2);
signalName[0] = signalName.at(0).toLower();
- QMetaMethod method = findSignalByName(currentObject->metaObject(), signalName.toLatin1().constData());
- if (method.isValid()) {
- object = currentObject;
- core.load(method);
- return;
+ // XXX - this code treats methods as signals
+
+ QQmlData *ddata = QQmlData::get(currentObject, false);
+ if (ddata && ddata->propertyCache) {
+
+ // Try method
+ QQmlPropertyData *d = ddata->propertyCache->property(signalName);
+ while (d && !d->isFunction())
+ d = ddata->propertyCache->overrideData(d);
+
+ if (d) {
+ object = currentObject;
+ core = *d;
+ return;
+ }
+
+ // Try property
+ if (signalName.endsWith(QLatin1String("Changed"))) {
+ QString propName = signalName.mid(0, signalName.length() - 7);
+ QQmlPropertyData *d = ddata->propertyCache->property(propName);
+ while (d && d->isFunction())
+ d = ddata->propertyCache->overrideData(d);
+
+ if (d && d->notifyIndex != -1) {
+ object = currentObject;
+ core = *ddata->propertyCache->method(d->notifyIndex);
+ return;
+ }
+ }
+
+ } else {
+ QMetaMethod method = findSignalByName(currentObject->metaObject(),
+ signalName.toLatin1().constData());
+ if (method.isValid()) {
+ object = currentObject;
+ core.load(method);
+ return;
+ }
}
}
@@ -735,8 +768,7 @@ QQmlPropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex)
QQmlPropertyData *propertyData =
data->propertyCache?data->propertyCache->property(coreIndex):0;
if (propertyData && propertyData->isAlias()) {
- const QQmlVMEMetaObject *vme =
- static_cast<const QQmlVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex) || aCoreIndex == -1)
@@ -777,8 +809,8 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex,
QQmlPropertyData *propertyData =
data->propertyCache?data->propertyCache->property(coreIndex):0;
if (propertyData && propertyData->isAlias()) {
- const QQmlVMEMetaObject *vme =
- static_cast<const QQmlVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
+
QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
if (vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
// This will either be a value type sub-reference or an alias to a value-type sub-reference not both
@@ -811,8 +843,7 @@ QQmlPropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeInd
QQmlPropertyData *propertyData =
data->propertyCache?data->propertyCache->property(coreIndex):0;
if (propertyData && propertyData->isAlias()) {
- const QQmlVMEMetaObject *vme =
- static_cast<const QQmlVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
@@ -871,8 +902,7 @@ QQmlPropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valu
QQmlPropertyData *propertyData =
data->propertyCache?data->propertyCache->property(coreIndex):0;
if (propertyData && propertyData->isAlias()) {
- const QQmlVMEMetaObject *vme =
- static_cast<const QQmlVMEMetaObject *>(metaObjectForProperty(object->metaObject(), coreIndex));
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex);
QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1;
if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) {
@@ -988,7 +1018,7 @@ QQmlPropertyPrivate::takeSignalExpression(const QQmlProperty &that,
return signalHandler->takeExpression(expr);
if (expr) {
- QQmlBoundSignal *signal = new QQmlBoundSignal(that.d->object, that.method(), that.d->object,
+ QQmlBoundSignal *signal = new QQmlBoundSignal(that.d->object, that.index(), that.d->object,
expr->context()->engine);
signal->takeExpression(expr);
}
@@ -1096,8 +1126,23 @@ QVariant QQmlPropertyPrivate::readValueProperty()
} else {
- return object->metaObject()->property(core.coreIndex).read(object.data());
+ if (!core.propType) // Unregistered type
+ return object->metaObject()->property(core.coreIndex).read(object);
+
+ QVariant value;
+ int status = -1;
+ void *args[] = { 0, &value, &status };
+ if (core.propType == QMetaType::QVariant) {
+ args[0] = &value;
+ } else {
+ value = QVariant(core.propType, (void*)0);
+ args[0] = value.data();
+ }
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, core.coreIndex, args);
+ if (core.propType != QMetaType::QVariant && args[0] != value.data())
+ return QVariant((QVariant::Type)core.propType, args[0]);
+ return value;
}
}
@@ -1293,34 +1338,33 @@ bool QQmlPropertyPrivate::write(QObject *object,
} else if (property.isQObject()) {
- const QMetaObject *valMo = rawMetaObjectForType(enginePriv, value.userType());
+ QQmlMetaObject valMo = rawMetaObjectForType(enginePriv, value.userType());
- if (!valMo)
+ if (valMo.isNull())
return false;
QObject *o = *(QObject **)value.constData();
- const QMetaObject *propMo = rawMetaObjectForType(enginePriv, propertyType);
+ QQmlMetaObject propMo = rawMetaObjectForType(enginePriv, propertyType);
- if (o) valMo = o->metaObject();
+ if (o) valMo = o;
- if (canConvert(valMo, propMo)) {
+ if (QQmlMetaObject::canConvert(valMo, propMo)) {
void *args[] = { &o, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
- args);
- } else if (!o && canConvert(propMo, valMo)) {
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, args);
+ } else if (!o && QQmlMetaObject::canConvert(propMo, valMo)) {
// In the case of a null QObject, we assign the null if there is
// any change that the null variant type could be up or down cast to
// the property type.
void *args[] = { &o, 0, &status, &flags };
- QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx,
- args);
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, args);
} else {
return false;
}
} else if (property.isQList()) {
- const QMetaObject *listType = 0;
+ QQmlMetaObject listType;
+
if (enginePriv) {
listType = enginePriv->rawMetaObjectForType(enginePriv->listType(property.propType));
} else {
@@ -1328,7 +1372,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
if (!type) return false;
listType = type->baseMetaObject();
}
- if (!listType) return false;
+ if (listType.isNull()) return false;
QQmlListProperty<void> prop;
void *args[] = { &prop, 0 };
@@ -1343,7 +1387,7 @@ bool QQmlPropertyPrivate::write(QObject *object,
for (int ii = 0; ii < qdlr.count(); ++ii) {
QObject *o = qdlr.at(ii);
- if (o && !canConvert(o->metaObject(), listType))
+ if (o && !QQmlMetaObject::canConvert(o, listType))
o = 0;
prop.append(&prop, (void *)o);
}
@@ -1352,13 +1396,13 @@ bool QQmlPropertyPrivate::write(QObject *object,
for (int ii = 0; ii < list.count(); ++ii) {
QObject *o = list.at(ii);
- if (o && !canConvert(o->metaObject(), listType))
+ if (o && !QQmlMetaObject::canConvert(o, listType))
o = 0;
prop.append(&prop, (void *)o);
}
} else {
QObject *o = enginePriv?enginePriv->toQObject(value):QQmlMetaType::toQObject(value);
- if (o && !canConvert(o->metaObject(), listType))
+ if (o && !QQmlMetaObject::canConvert(o, listType))
o = 0;
prop.append(&prop, (void *)o);
}
@@ -1481,7 +1525,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
QQmlJavaScriptExpression::DeleteWatcher watcher(expression);
QVariant value;
- bool isVmeProperty = core.isVMEProperty();
+ bool isVarProperty = core.isVarProperty();
if (isUndefined) {
} else if (core.isQList()) {
@@ -1490,13 +1534,13 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
value = QVariant::fromValue((QObject *)0);
} else if (core.propType == qMetaTypeId<QList<QUrl> >()) {
value = resolvedUrlSequence(v8engine->toVariant(result, qMetaTypeId<QList<QUrl> >()), context);
- } else if (!isVmeProperty && type != qMetaTypeId<QJSValue>()) {
+ } else if (!isVarProperty && type != qMetaTypeId<QJSValue>()) {
value = v8engine->toVariant(result, type);
}
if (expression->hasError()) {
return false;
- } else if (isVmeProperty) {
+ } else if (isVarProperty) {
if (!result.IsEmpty() && result->IsFunction()
&& !result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) {
// we explicitly disallow this case to avoid confusion. Users can still store one
@@ -1504,6 +1548,8 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
expression->delayedError()->error.setDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
return false;
}
+
+ typedef QQmlVMEMetaObject VMEMO;
QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
Q_ASSERT(vmemo);
vmemo->setVMEProperty(core.coreIndex, result);
@@ -1540,9 +1586,9 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
if (QObject *o = *(QObject **)value.constData()) {
valueType = o->metaObject()->className();
- if (const QMetaObject *propertyMetaObject = rawMetaObjectForType(QQmlEnginePrivate::get(engine), type)) {
- propertyType = propertyMetaObject->className();
- }
+ QQmlMetaObject propertyMetaObject = rawMetaObjectForType(QQmlEnginePrivate::get(engine), type);
+ if (!propertyMetaObject.isNull())
+ propertyType = propertyMetaObject.className();
}
} else if (value.userType() != QVariant::Invalid) {
valueType = QMetaType::typeName(value.userType());
@@ -1563,13 +1609,13 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
return true;
}
-const QMetaObject *QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engine, int userType)
+QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engine, int userType)
{
if (engine) {
return engine->rawMetaObjectForType(userType);
} else {
QQmlType *type = QQmlMetaType::qmlType(userType);
- return type?type->baseMetaObject():0;
+ return QQmlMetaObject(type?type->baseMetaObject():0);
}
}
@@ -1762,14 +1808,13 @@ int QQmlPropertyPrivate::bindingIndex(const QQmlPropertyData &that)
}
QQmlPropertyData
-QQmlPropertyPrivate::saveValueType(const QMetaObject *metaObject, int index,
- const QMetaObject *subObject, int subIndex,
- QQmlEngine *)
+QQmlPropertyPrivate::saveValueType(const QQmlPropertyData &base,
+ const QMetaObject *subObject, int subIndex,
+ QQmlEngine *)
{
QMetaProperty subProp = subObject->property(subIndex);
- QQmlPropertyData core;
- core.load(metaObject->property(index));
+ QQmlPropertyData core = base;
core.setFlags(core.getFlags() | QQmlPropertyData::IsValueTypeVirtual);
core.valueTypeFlags = QQmlPropertyData::flagsForProperty(subProp);
core.valueTypeCoreIndex = subIndex;
@@ -1795,31 +1840,6 @@ QQmlPropertyPrivate::restore(QObject *object, const QQmlPropertyData &data,
}
/*!
- Returns true if lhs and rhs refer to the same metaobject data
-*/
-bool QQmlPropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rhs)
-{
- return lhs == rhs || (1 && lhs && rhs && lhs->d.stringdata == rhs->d.stringdata);
-}
-
-/*!
- Returns true if from inherits to.
-*/
-bool QQmlPropertyPrivate::canConvert(const QMetaObject *from, const QMetaObject *to)
-{
- if (from && to == &QObject::staticMetaObject)
- return true;
-
- while (from) {
- if (equal(from, to))
- return true;
- from = from->superClass();
- }
-
- return false;
-}
-
-/*!
Return the signal corresponding to \a name
*/
QMetaMethod QQmlPropertyPrivate::findSignalByName(const QMetaObject *mo, const QByteArray &name)
@@ -1883,17 +1903,8 @@ static inline void flush_vme_signal(const QObject *object, int index)
QQmlPropertyData *property = data->propertyCache->method(index);
if (property && property->isVMESignal()) {
- const QMetaObject *metaObject = object->metaObject();
- int methodOffset = metaObject->methodOffset();
-
- while (methodOffset > index) {
- metaObject = metaObject->d.superdata;
- methodOffset -= QMetaObject_methods(metaObject);
- }
-
- QQmlVMEMetaObject *vme =
- static_cast<QQmlVMEMetaObject *>(const_cast<QMetaObject *>(metaObject));
-
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForMethod(const_cast<QObject *>(object),
+ index);
vme->connectAliasSignal(index);
}
}
@@ -1921,19 +1932,4 @@ void QQmlPropertyPrivate::flushSignal(const QObject *sender, int signal_index)
flush_vme_signal(sender, signal_index);
}
-/*!
-Return \a metaObject's [super] meta object that provides data for \a property.
-*/
-const QMetaObject *QQmlPropertyPrivate::metaObjectForProperty(const QMetaObject *metaObject, int property)
-{
- int propertyOffset = metaObject->propertyOffset();
-
- while (propertyOffset > property) {
- metaObject = metaObject->d.superdata;
- propertyOffset -= QMetaObject_properties(metaObject);
- }
-
- return metaObject;
-}
-
QT_END_NAMESPACE