summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qdeclarativemetaproperty.cpp190
-rw-r--r--src/declarative/qml/qdeclarativemetaproperty.h2
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp2
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp2
-rw-r--r--src/declarative/util/qdeclarativestate.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp2
-rw-r--r--tests/auto/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp26
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[] = { &currentObject, 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<PropertyObject*>(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));