From 9c147ba5e39dffea91d492896cc836529715d7ac Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 25 Feb 2010 14:11:52 +1000 Subject: Remove QDeclarativeMetaProperty::createProperty() method The behavior of createProperty() (to resolve dot properties) is now the behavior of the constructors. --- src/declarative/qml/qdeclarativemetaproperty.cpp | 190 ++++++++++----------- src/declarative/qml/qdeclarativemetaproperty.h | 2 - src/declarative/util/qdeclarativeanimation.cpp | 2 +- .../util/qdeclarativepropertychanges.cpp | 2 +- src/declarative/util/qdeclarativestate.cpp | 8 +- .../tst_qdeclarativelanguage.cpp | 2 +- .../tst_qdeclarativemetaproperty.cpp | 26 +-- 7 files changed, 106 insertions(+), 126 deletions(-) diff --git a/src/declarative/qml/qdeclarativemetaproperty.cpp b/src/declarative/qml/qdeclarativemetaproperty.cpp index 3bbc337..477ef3a 100644 --- a/src/declarative/qml/qdeclarativemetaproperty.cpp +++ b/src/declarative/qml/qdeclarativemetaproperty.cpp @@ -146,50 +146,111 @@ QDeclarativeMetaProperty::QDeclarativeMetaProperty(QObject *obj, const QString & if (!isValid()) { d->object = 0; d->context = 0; } } +Q_GLOBAL_STATIC(QDeclarativeValueTypeFactory, qmlValueTypes); + void QDeclarativeMetaPropertyPrivate::initProperty(QObject *obj, const QString &name) { - QDeclarativeEnginePrivate *enginePrivate = 0; - if (context && context->engine()) - enginePrivate = QDeclarativeEnginePrivate::get(context->engine()); + if (!obj) return; - object = obj; + QDeclarativeEngine *engine = context?context->engine():0; + QDeclarativeTypeNameCache *typeNameCache = context?QDeclarativeContextPrivate::get(context)->imports:0; - if (name.isEmpty() || !obj) - return; + QStringList path = name.split(QLatin1Char('.')); + if (path.isEmpty()) return; + + QObject *currentObject = obj; + + // Everything up to the last property must be an "object type" property + for (int ii = 0; ii < path.count() - 1; ++ii) { + const QString &pathName = path.at(ii); + + if (QDeclarativeTypeNameCache::Data *data = typeNameCache?typeNameCache->data(pathName):0) { + if (data->type) { + QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction(); + if (!func) return; // Not an attachable type + + currentObject = qmlAttachedPropertiesObjectById(data->type->index(), currentObject); + if (!currentObject) return; // Something is broken with the attachable type + } else { + Q_ASSERT(data->typeNamespace); + if ((ii + 1) == path.count()) return; // No type following the namespace + + ++ii; data = data->typeNamespace->data(path.at(ii)); + if (!data || !data->type) return; // Invalid type in namespace + + QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction(); + if (!func) return; // Not an attachable type + + currentObject = qmlAttachedPropertiesObjectById(data->type->index(), currentObject); + if (!currentObject) return; // Something is broken with the attachable type + } + } else { + + QDeclarativePropertyCache::Data local; + QDeclarativePropertyCache::Data *property = + QDeclarativePropertyCache::property(engine, obj, pathName, local); + + if (!property) return; // Not a property + if (property->flags & QDeclarativePropertyCache::Data::IsFunction) + return; // Not an object property + + if (ii == (path.count() - 2) && property->propType < (int)QVariant::UserType) { + // 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[property->propType]; + if (!typeObject) return; // Not a value type + + int idx = typeObject->metaObject()->indexOfProperty(path.last().toUtf8().constData()); + if (idx == -1) return; // Value type property does not exist + + QMetaProperty vtProp = typeObject->metaObject()->property(idx); + + object = currentObject; + core = *property; + valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(vtProp); + valueType.valueTypeCoreIdx = idx; + valueType.valueTypePropType = vtProp.userType(); + + return; + } else { + if (!(property->flags & QDeclarativePropertyCache::Data::IsQObjectDerived)) + return; // Not an object property + + void *args[] = { ¤tObject, 0 }; + QMetaObject::metacall(currentObject, QMetaObject::ReadProperty, property->coreIndex, args); + if (!currentObject) return; // No value - if (enginePrivate && name.at(0).isUpper()) { - // Attached property - // ### What about qualified types? - QDeclarativeTypeNameCache *tnCache = QDeclarativeContextPrivate::get(context)->imports; - if (tnCache) { - QDeclarativeTypeNameCache::Data *d = tnCache->data(name); - if (d && d->type && d->type->attachedPropertiesFunction()) { - attachedFunc = d->type->index(); } } - return; - } else if (name.count() >= 3 && - name.at(0) == QChar(QLatin1Char('o')) && - name.at(1) == QChar(QLatin1Char('n')) && - name.at(2).isUpper()) { - // Signal - QString signalName = name.mid(2); + } + + const QString &terminal = path.last(); + + if (terminal.count() >= 3 && + terminal.at(0) == QLatin1Char('o') && + terminal.at(1) == QLatin1Char('n') && + terminal.at(2).isUpper()) { + + QString signalName = terminal.mid(2); signalName[0] = signalName.at(0).toLower(); - QMetaMethod method = findSignal(obj, signalName); + QMetaMethod method = findSignal(currentObject, signalName); if (method.signature()) { + object = currentObject; core.load(method); return; } - } + } // Property QDeclarativePropertyCache::Data local; QDeclarativePropertyCache::Data *property = - QDeclarativePropertyCache::property(context?context->engine():0, obj, name, local); - if (property && !(property->flags & QDeclarativePropertyCache::Data::IsFunction)) + QDeclarativePropertyCache::property(context?context->engine():0, currentObject, terminal, local); + if (property && !(property->flags & QDeclarativePropertyCache::Data::IsFunction)) { + object = currentObject; core = *property; + } } /*! @@ -1077,8 +1138,6 @@ int QDeclarativeMetaProperty::valueTypeCoreIndex() const return d->valueType.valueTypeCoreIdx; } -Q_GLOBAL_STATIC(QDeclarativeValueTypeFactory, qmlValueTypes); - struct SerializedData { QDeclarativeMetaProperty::Type type; @@ -1141,83 +1200,6 @@ QDeclarativeMetaPropertyPrivate::restore(const QByteArray &data, QObject *object } /*! - \internal - - Creates a QDeclarativeMetaProperty for the property \a name of \a obj. Unlike - the QDeclarativeMetaProperty(QObject*, QString, QDeclarativeContext*) constructor, this static function - will correctly handle dot properties, including value types and attached properties. -*/ -QDeclarativeMetaProperty QDeclarativeMetaProperty::createProperty(QObject *obj, - const QString &name, - QDeclarativeContext *context) -{ - QDeclarativeTypeNameCache *typeNameCache = context?QDeclarativeContextPrivate::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 (QDeclarativeTypeNameCache::Data *data = typeNameCache?typeNameCache->data(pathName):0) { - if (data->type) { - QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction(); - if (!func) - return QDeclarativeMetaProperty(); - object = qmlAttachedPropertiesObjectById(data->type->index(), object); - if (!object) - return QDeclarativeMetaProperty(); - continue; - } else { - Q_ASSERT(data->typeNamespace); - ++jj; - data = data->typeNamespace->data(path.at(jj)); - if (!data || !data->type) - return QDeclarativeMetaProperty(); - QDeclarativeAttachedPropertiesFunc func = data->type->attachedPropertiesFunction(); - if (!func) - return QDeclarativeMetaProperty(); - object = qmlAttachedPropertiesObjectById(data->type->index(), object); - if (!object) - return QDeclarativeMetaProperty(); - continue; - } - } - - QDeclarativeMetaProperty prop(object, pathName, context); - - if (jj == path.count() - 2 && prop.propertyType() < (int)QVariant::UserType && - qmlValueTypes()->valueTypes[prop.propertyType()]) { - // 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()); - if (idx == -1) - return QDeclarativeMetaProperty(); - QMetaProperty vtProp = typeObject->metaObject()->property(idx); - - QDeclarativeMetaProperty p = prop; - p.d->valueType.valueTypeCoreIdx = idx; - p.d->valueType.valueTypePropType = vtProp.userType(); - return p; - } - - QObject *objVal = QDeclarativeMetaType::toQObject(prop.read()); - if (!objVal) - return QDeclarativeMetaProperty(); - object = objVal; - } - - const QString &propName = path.last(); - QDeclarativeMetaProperty prop(object, propName, context); - if (!prop.isValid()) - return QDeclarativeMetaProperty(); - else - return prop; -} - -/*! Returns true if lhs and rhs refer to the same metaobject data */ bool QDeclarativeMetaPropertyPrivate::equal(const QMetaObject *lhs, const QMetaObject *rhs) diff --git a/src/declarative/qml/qdeclarativemetaproperty.h b/src/declarative/qml/qdeclarativemetaproperty.h index 9a3a793..8ea3bcd 100644 --- a/src/declarative/qml/qdeclarativemetaproperty.h +++ b/src/declarative/qml/qdeclarativemetaproperty.h @@ -121,8 +121,6 @@ public: QMetaProperty property() const; - static QDeclarativeMetaProperty createProperty(QObject *, const QString &, QDeclarativeContext *context=0); - int coreIndex() const; int valueTypeCoreIndex() const; private: diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index eb3a376..9e777a0 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -156,7 +156,7 @@ void QDeclarativeAbstractAnimationPrivate::commence() QDeclarativeMetaProperty QDeclarativeAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str, QObject *infoObj) { - QDeclarativeMetaProperty prop = QDeclarativeMetaProperty::createProperty(obj, str, qmlContext(infoObj)); + QDeclarativeMetaProperty prop(obj, str, qmlContext(infoObj)); if (!prop.isValid()) { qmlInfo(infoObj) << QDeclarativeAbstractAnimation::tr("Cannot animate non-existent property \"%1\"").arg(str); return QDeclarativeMetaProperty(); diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index ad39574..6c2e256 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -348,7 +348,7 @@ QDeclarativeMetaProperty QDeclarativePropertyChangesPrivate::property(const QByteArray &property) { Q_Q(QDeclarativePropertyChanges); - QDeclarativeMetaProperty prop = QDeclarativeMetaProperty::createProperty(object, QString::fromUtf8(property)); + QDeclarativeMetaProperty prop(object, QString::fromUtf8(property)); if (!prop.isValid()) { qmlInfo(q) << QDeclarativePropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(property)); return QDeclarativeMetaProperty(); diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index d1dd318..3b06e33 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -65,11 +65,11 @@ QDeclarativeAction::QDeclarativeAction() QDeclarativeAction::QDeclarativeAction(QObject *target, const QString &propertyName, const QVariant &value) -: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), toValue(value), fromBinding(0), - toBinding(0), event(0), specifiedObject(target), - specifiedProperty(propertyName) +: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), + property(target, propertyName), toValue(value), + fromBinding(0), toBinding(0), event(0), + specifiedObject(target), specifiedProperty(propertyName) { - property = QDeclarativeMetaProperty::createProperty(target, propertyName); if (property.isValid()) fromValue = property.read(); } diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index ae07112..2907757 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -747,7 +747,7 @@ void tst_qdeclarativelanguage::valueTypes() // ### #if 0 - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(object, "rectProperty.x"); + QDeclarativeMetaProperty p(object, "rectProperty.x"); QCOMPARE(p.read(), QVariant(12)); p.write(13); QCOMPARE(p.read(), QVariant(13)); diff --git a/tests/auto/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp b/tests/auto/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp index 42d77bb..0740d0f 100644 --- a/tests/auto/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp +++ b/tests/auto/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp @@ -754,19 +754,19 @@ void tst_qdeclarativemetaproperty::name() { PropertyObject o; - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(&o, "rectProperty"); + QDeclarativeMetaProperty p(&o, "rectProperty"); QCOMPARE(p.name(), QString("rectProperty")); } { PropertyObject o; - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(&o, "rectProperty.x"); + QDeclarativeMetaProperty p(&o, "rectProperty.x"); QCOMPARE(p.name(), QString("rectProperty.x")); } { PropertyObject o; - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(&o, "rectProperty.foo"); + QDeclarativeMetaProperty p(&o, "rectProperty.foo"); QCOMPARE(p.name(), QString()); } } @@ -808,14 +808,14 @@ void tst_qdeclarativemetaproperty::read() // Value-type prop { PropertyObject o; - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(&o, "rectProperty.x"); + QDeclarativeMetaProperty p(&o, "rectProperty.x"); QCOMPARE(p.read(), QVariant(10)); } // Invalid value-type prop { PropertyObject o; - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(&o, "rectProperty.foo"); + QDeclarativeMetaProperty p(&o, "rectProperty.foo"); QCOMPARE(p.read(), QVariant()); } @@ -834,7 +834,7 @@ void tst_qdeclarativemetaproperty::read() // Deleted object { PropertyObject *o = new PropertyObject; - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(o, "rectProperty.x"); + QDeclarativeMetaProperty p(o, "rectProperty.x"); QCOMPARE(p.read(), QVariant(10)); delete o; QCOMPARE(p.read(), QVariant()); @@ -847,7 +847,7 @@ void tst_qdeclarativemetaproperty::read() QObject *object = component.create(); QVERIFY(object != 0); - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(object, "MyContainer.foo", qmlContext(object)); + QDeclarativeMetaProperty p(object, "MyContainer.foo", qmlContext(object)); QCOMPARE(p.read(), QVariant(13)); delete object; } @@ -857,7 +857,7 @@ void tst_qdeclarativemetaproperty::read() QObject *object = component.create(); QVERIFY(object != 0); - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(object, "MyContainer.foo", qmlContext(object)); + QDeclarativeMetaProperty p(object, "MyContainer.foo", qmlContext(object)); QCOMPARE(p.read(), QVariant(10)); delete object; } @@ -867,7 +867,7 @@ void tst_qdeclarativemetaproperty::read() QObject *object = component.create(); QVERIFY(object != 0); - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(object, "Foo.MyContainer.foo", qmlContext(object)); + QDeclarativeMetaProperty p(object, "Foo.MyContainer.foo", qmlContext(object)); QCOMPARE(p.read(), QVariant(10)); delete object; } @@ -946,7 +946,7 @@ void tst_qdeclarativemetaproperty::write() QCOMPARE(p.write(QRect(1, 13, 99, 8)), true); QCOMPARE(o.wrectProperty(), QRect(1, 13, 99, 8)); - QDeclarativeMetaProperty p2 = QDeclarativeMetaProperty::createProperty(&o, "wrectProperty.x"); + QDeclarativeMetaProperty p2(&o, "wrectProperty.x"); QCOMPARE(p2.read(), QVariant(1)); QCOMPARE(p2.write(QVariant(6)), true); QCOMPARE(p2.read(), QVariant(6)); @@ -977,7 +977,7 @@ void tst_qdeclarativemetaproperty::write() QObject *object = component.create(); QVERIFY(object != 0); - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(object, "MyContainer.foo", qmlContext(object)); + QDeclarativeMetaProperty p(object, "MyContainer.foo", qmlContext(object)); p.write(QVariant(99)); QCOMPARE(p.read(), QVariant(99)); delete object; @@ -988,7 +988,7 @@ void tst_qdeclarativemetaproperty::write() QObject *object = component.create(); QVERIFY(object != 0); - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(object, "Foo.MyContainer.foo", qmlContext(object)); + QDeclarativeMetaProperty p(object, "Foo.MyContainer.foo", qmlContext(object)); p.write(QVariant(99)); QCOMPARE(p.read(), QVariant(99)); delete object; @@ -1116,7 +1116,7 @@ void tst_qdeclarativemetaproperty::crashOnValueProperty() PropertyObject *obj = qobject_cast(component.create()); QVERIFY(obj != 0); - QDeclarativeMetaProperty p = QDeclarativeMetaProperty::createProperty(obj, "wrectProperty.x", qmlContext(obj)); + QDeclarativeMetaProperty p(obj, "wrectProperty.x", qmlContext(obj)); QCOMPARE(p.name(), QString("wrectProperty.x")); QCOMPARE(p.read(), QVariant(10)); -- cgit v0.12