diff options
6 files changed, 93 insertions, 13 deletions
diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h index c7857b7..def4188 100644 --- a/src/declarative/qml/qdeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedata_p.h @@ -64,6 +64,7 @@ class QDeclarativeAbstractBinding; class QDeclarativeContext; class QDeclarativePropertyCache; class QDeclarativeContextData; +class QDeclarativeNotifier; // This class is structured in such a way, that simply zero'ing it is the // default state for elemental object allocations. This is crucial in the // workings of the QDeclarativeInstruction::CreateSimpleObject instruction. @@ -75,7 +76,7 @@ public: : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), - attachedProperties(0), scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0) { + scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0), extendedData(0) { init(); } @@ -91,6 +92,7 @@ public: void destroyed(QObject *); void parentChanged(QObject *, QObject *); + void objectNameChanged(QObject *); void setImplicitDestructible() { if (!explicitIndestructibleSet) indestructible = false; @@ -125,8 +127,6 @@ public: QDeclarativeCompiledData *deferredComponent; // Can't this be found from the context? unsigned int deferredIdx; - QHash<int, QObject *> *attachedProperties; - // ### Can we make this QScriptValuePrivate so we incur no additional allocation // cost? QScriptValue *scriptValue; @@ -149,6 +149,18 @@ public: return 0; } } + + QDeclarativeNotifier *objectNameNotifier() const; + QHash<int, QObject *> *attachedProperties() const; + + struct ExtendedData { + ExtendedData(); + ~ExtendedData(); + + QHash<int, QObject *> attachedProperties; + void *objectNameNotifier; + }; + mutable ExtendedData *extendedData; }; template<class T> diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index dfc29c4..7ed925a 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -68,6 +68,7 @@ #include "private/qdeclarativelist_p.h" #include "private/qdeclarativetypenamecache_p.h" #include "private/qdeclarativeinclude_p.h" +#include "private/qdeclarativenotifier_p.h" #include <QtCore/qmetaobject.h> #include <QScriptClass> @@ -470,6 +471,7 @@ void QDeclarativeData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QO void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o) { + static_cast<QDeclarativeData *>(d)->objectNameChanged(o); } void QDeclarativeEnginePrivate::init() @@ -953,7 +955,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre if (!data) return 0; // Attached properties are only on objects created by QML - QObject *rv = data->attachedProperties?data->attachedProperties->value(id):0; + QObject *rv = data->extendedData?data->attachedProperties()->value(id):0; if (rv || !create) return rv; @@ -963,11 +965,8 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre rv = pf(const_cast<QObject *>(object)); - if (rv) { - if (!data->attachedProperties) - data->attachedProperties = new QHash<int, QObject *>(); - data->attachedProperties->insert(id, rv); - } + if (rv) + data->attachedProperties()->insert(id, rv); return rv; } @@ -988,8 +987,6 @@ void QDeclarativeData::destroyed(QObject *object) { if (deferredComponent) deferredComponent->release(); - if (attachedProperties) - delete attachedProperties; if (nextContextObject) nextContextObject->prevContextObject = prevContextObject; @@ -1023,6 +1020,9 @@ void QDeclarativeData::destroyed(QObject *object) if (scriptValue) delete scriptValue; + if (extendedData) + delete extendedData; + if (ownMemory) delete this; } @@ -1032,6 +1032,11 @@ void QDeclarativeData::parentChanged(QObject *, QObject *parent) if (!parent && scriptValue) { delete scriptValue; scriptValue = 0; } } +void QDeclarativeData::objectNameChanged(QObject *) +{ + if (extendedData) objectNameNotifier()->notify(); +} + bool QDeclarativeData::hasBindingBit(int bit) const { if (bindingBitsSize > bit) @@ -1068,6 +1073,28 @@ void QDeclarativeData::setBindingBit(QObject *obj, int bit) bindingBits[bit / 32] |= (1 << (bit % 32)); } +QDeclarativeData::ExtendedData::ExtendedData() +: objectNameNotifier(0) +{ +} + +QDeclarativeData::ExtendedData::~ExtendedData() +{ + ((QDeclarativeNotifier *)&objectNameNotifier)->~QDeclarativeNotifier(); +} + +QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const +{ + if (!extendedData) extendedData = new ExtendedData; + return (QDeclarativeNotifier *)&extendedData->objectNameNotifier; +} + +QHash<int, QObject *> *QDeclarativeData::attachedProperties() const +{ + if (!extendedData) extendedData = new ExtendedData; + return &extendedData->attachedProperties; +} + /*! Creates a QScriptValue allowing you to use \a object in QML script. \a engine is the QDeclarativeEngine it is to be created in. diff --git a/src/declarative/qml/qdeclarativefastproperties.cpp b/src/declarative/qml/qdeclarativefastproperties.cpp index eb69b6a..78e3afd 100644 --- a/src/declarative/qml/qdeclarativefastproperties.cpp +++ b/src/declarative/qml/qdeclarativefastproperties.cpp @@ -51,10 +51,19 @@ QT_BEGIN_NAMESPACE // primarily read from bindings is a candidate for inclusion as a fast // property. +static void QObject_objectName(QObject *object, void *output, QDeclarativeNotifierEndpoint *endpoint) +{ + if (endpoint) + endpoint->connect(QDeclarativeData::get(object, true)->objectNameNotifier()); + *((QString *)output) = object->objectName(); +} + QDeclarativeFastProperties::QDeclarativeFastProperties() { add(&QDeclarativeItem::staticMetaObject, QDeclarativeItem::staticMetaObject.indexOfProperty("parent"), QDeclarativeItemPrivate::parentProperty); + add(&QObject::staticMetaObject, QObject::staticMetaObject.indexOfProperty("objectName"), + QObject_objectName); } int QDeclarativeFastProperties::accessorIndexForProperty(const QMetaObject *metaObject, int propertyIndex) diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index ab6ff74..61a1f55 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -239,8 +239,13 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) } } else { if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) { - enginePriv->capturedProperties << - QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex); + if (lastData->coreIndex == 0) { + enginePriv->capturedProperties << + QDeclarativeEnginePrivate::CapturedProperty(QDeclarativeData::get(obj, true)->objectNameNotifier()); + } else { + enginePriv->capturedProperties << + QDeclarativeEnginePrivate::CapturedProperty(obj, lastData->coreIndex, lastData->notifyIndex); + } } if (QDeclarativeValueTypeFactory::isValueType((uint)lastData->propType)) { diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml b/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml new file mode 100644 index 0000000..ca8c90d --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/objectName.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +QtObject { + objectName: "hello" + + property string test1: objectName + property string test2: objectName.substr(1, 3) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 4feb630..02832f3 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -162,6 +162,7 @@ private slots: void deleteLater(); void in(); void sharedAttachedObject(); + void objectName(); void include(); @@ -2594,6 +2595,24 @@ void tst_qdeclarativeecmascript::sharedAttachedObject() delete o; } +// QTBUG-13999 +void tst_qdeclarativeecmascript::objectName() +{ + QDeclarativeComponent component(&engine, TEST_FILE("objectName.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test1").toString(), QString("hello")); + QCOMPARE(o->property("test2").toString(), QString("ell")); + + o->setObjectName("world"); + + QCOMPARE(o->property("test1").toString(), QString("world")); + QCOMPARE(o->property("test2").toString(), QString("orl")); + + delete o; +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" |