diff options
Diffstat (limited to 'src/declarative/qml/qmlmetaproperty.cpp')
-rw-r--r-- | src/declarative/qml/qmlmetaproperty.cpp | 90 |
1 files changed, 74 insertions, 16 deletions
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 6738370..0603a9c 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -46,10 +46,12 @@ #include "qml.h" #include "qmlbinding.h" #include "qmlcontext.h" +#include "qmlcontext_p.h" #include "qmlboundsignal_p.h" #include "qmlengine.h" #include "qmlengine_p.h" #include "qmldeclarativedata_p.h" +#include "qmlstringconverters_p.h" #include <qfxperf_p_p.h> @@ -160,17 +162,13 @@ void QmlMetaPropertyPrivate::initProperty(QObject *obj, const QString &name) if (enginePrivate && name.at(0).isUpper()) { // Attached property - //### needs to be done in a better way - QmlCompositeTypeData *typeData = - enginePrivate->typeManager.get(context->baseUrl()); - - if (typeData) { - QmlType *t = 0; - enginePrivate->resolveType(typeData->imports, name.toUtf8(), &t, 0, 0, 0, 0); - if (t && t->attachedPropertiesFunction()) { - attachedFunc = t->index(); + // ### What about qualified types? + QmlTypeNameCache *tnCache = QmlContextPrivate::get(context)->imports; + if (tnCache) { + QmlTypeNameCache::Data *d = tnCache->data(name); + if (d && d->type && d->type->attachedPropertiesFunction()) { + attachedFunc = d->type->index(); } - typeData->release(); } return; @@ -438,6 +436,17 @@ bool QmlMetaProperty::isDesignable() const } /*! + Returns true if the property is resettable, otherwise false. +*/ +bool QmlMetaProperty::isResettable() const +{ + if (type() & Property && d->core.isValid() && d->object) + return d->core.flags & QmlPropertyCache::Data::IsResettable; + else + return false; +} + +/*! Returns true if the QmlMetaProperty refers to a valid property, otherwise false. */ @@ -676,7 +685,7 @@ QVariant QmlMetaProperty::read() const return QVariant(); - } else if (type() & Property) { + } else if (type() & Property || type() & Attached) { return d->readValueProperty(); @@ -954,6 +963,14 @@ bool QmlMetaPropertyPrivate::write(QObject *object, const QmlPropertyCache::Data void *a[] = { (void *)v.constData(), 0, &status, &flags}; QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } + } else if (vt == QVariant::String) { + bool ok = false; + QVariant v = QmlStringConverters::variantFromString(value.toString(), t, &ok); + if (!ok) + return false; + + void *a[] = { (void *)v.constData(), 0, &status, &flags}; + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, a); } else { return false; } @@ -970,6 +987,20 @@ bool QmlMetaProperty::write(const QVariant &value) const return write(value, 0); } +/*! + Resets the property value. +*/ +bool QmlMetaProperty::reset() const +{ + if (isResettable()) { + void *args[] = { 0 }; + QMetaObject::metacall(d->object, QMetaObject::ResetProperty, d->core.coreIndex, args); + return true; + } else { + return false; + } +} + bool QmlMetaProperty::write(const QVariant &value, QmlMetaProperty::WriteFlags flags) const { if (d->object && type() & Property && d->core.isValid() && isWritable()) @@ -1122,24 +1153,51 @@ QmlMetaPropertyPrivate::restore(const QByteArray &data, QObject *object, QmlCont Creates a QmlMetaProperty for the property \a name of \a obj. Unlike the QmlMetaProperty(QObject*, QString, QmlContext*) constructor, this static function - will correctly handle dot properties. + will correctly handle dot properties, including value types and attached properties. */ QmlMetaProperty QmlMetaProperty::createProperty(QObject *obj, const QString &name, QmlContext *context) { - QStringList path = name.split(QLatin1Char('.')); + QmlTypeNameCache *typeNameCache = context?QmlContextPrivate::get(context)->imports:0; + QStringList path = name.split(QLatin1Char('.')); QObject *object = obj; for (int jj = 0; jj < path.count() - 1; ++jj) { const QString &pathName = path.at(jj); + + if (QmlTypeNameCache::Data *data = typeNameCache?typeNameCache->data(pathName):0) { + if (data->type) { + QmlAttachedPropertiesFunc func = data->type->attachedPropertiesFunction(); + if (!func) + return QmlMetaProperty(); + object = qmlAttachedPropertiesObjectById(data->type->index(), object); + if (!object) + return QmlMetaProperty(); + continue; + } else { + Q_ASSERT(data->typeNamespace); + ++jj; + data = data->typeNamespace->data(path.at(jj)); + if (!data || !data->type) + return QmlMetaProperty(); + QmlAttachedPropertiesFunc func = data->type->attachedPropertiesFunction(); + if (!func) + return QmlMetaProperty(); + object = qmlAttachedPropertiesObjectById(data->type->index(), object); + if (!object) + return QmlMetaProperty(); + continue; + } + } + QmlMetaProperty prop(object, pathName, context); - if (jj == path.count() - 2 && - prop.propertyType() < (int)QVariant::UserType && + if (jj == path.count() - 2 && prop.propertyType() < (int)QVariant::UserType && qmlValueTypes()->valueTypes[prop.propertyType()]) { - // We're now at a value type property + // We're now at a value type property. We can use a global valuetypes array as we + // never actually use the objects, just look up their properties. QObject *typeObject = qmlValueTypes()->valueTypes[prop.propertyType()]; int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData()); |