From c4fab1011b9de42f43a95d598743da505847e139 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 17 Apr 2012 13:54:20 +1000 Subject: [PATCH] Remove QQmlData::objectNameChanged callback. The objectName property now has a proper NOTIFY signal. Also remove the objectName accessor, as it is no longer required. Task-number: QTBUG-23526 Change-Id: Ib18ba7335bf62a2fe2a9e489cb4c0f1fb142d74c Reviewed-by: Chris Adams --- src/qml/qml/qqmlaccessors.cpp | 20 ---------------- src/qml/qml/qqmldata_p.h | 6 +---- src/qml/qml/qqmlengine.cpp | 17 ------------- src/qml/qml/qqmlpropertycache.cpp | 28 +++++++++++++--------- src/qml/qml/v8/qv8qobjectwrapper.cpp | 9 ++----- .../qml/qqmlecmascript/data/destroyedSignal.qml | 6 +++++ .../data/objectNameChangedSignal.qml | 8 +++++++ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 24 +++++++++++++++++++ 8 files changed, 58 insertions(+), 60 deletions(-) create mode 100644 tests/auto/qml/qqmlecmascript/data/destroyedSignal.qml create mode 100644 tests/auto/qml/qqmlecmascript/data/objectNameChangedSignal.qml diff --git a/src/qml/qml/qqmlaccessors.cpp b/src/qml/qml/qqmlaccessors.cpp index ceb4f44..65d6cce 100644 --- a/src/qml/qml/qqmlaccessors.cpp +++ b/src/qml/qml/qqmlaccessors.cpp @@ -55,20 +55,6 @@ struct AccessorProperties { Q_GLOBAL_STATIC(AccessorProperties, accessorProperties) -QML_PRIVATE_ACCESSOR(QObject, QString, objectName, objectName) - -static void QObject_objectNameNotifier(QObject *object, intptr_t, QQmlNotifier **notifier) -{ - *notifier = QQmlData::get(object, true)->objectNameNotifier(); -} - -static QQmlAccessors QObject_objectName = { QObject_objectNameRead, - QObject_objectNameNotifier }; - -QML_DECLARE_PROPERTIES(QObject) { - { QML_PROPERTY_NAME(objectName), 0, &QObject_objectName } -}; - static void buildNameMask(QQmlAccessorProperties::Properties &properties) { quint32 mask = 0; @@ -85,12 +71,6 @@ static void buildNameMask(QQmlAccessorProperties::Properties &properties) AccessorProperties::AccessorProperties() { - // Pre-seed QObject::objectName accessor - typedef QQmlAccessorProperties::Properties P; - properties.insert(&QObject::staticMetaObject, - P(qqml_accessor_properties_QObject, - sizeof(qqml_accessor_properties_QObject) / - sizeof(QQmlAccessorProperties::Property))); } QQmlAccessorProperties::Properties::Properties(Property *properties, int count) diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 4849db0..08f68b6 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -92,7 +92,6 @@ public: initialized = true; QAbstractDeclarativeData::destroyed = destroyed; QAbstractDeclarativeData::parentChanged = parentChanged; - QAbstractDeclarativeData::objectNameChanged = objectNameChanged; QAbstractDeclarativeData::signalEmitted = signalEmitted; QAbstractDeclarativeData::receivers = receivers; } @@ -100,13 +99,11 @@ public: static void destroyed(QAbstractDeclarativeData *, QObject *); static void parentChanged(QAbstractDeclarativeData *, QObject *, QObject *); - static void objectNameChanged(QAbstractDeclarativeData *, QObject *); static void signalEmitted(QAbstractDeclarativeData *, QObject *, int, void **); static int receivers(QAbstractDeclarativeData *, const QObject *, int); void destroyed(QObject *); void parentChanged(QObject *, QObject *); - void objectNameChanged(QObject *); void setImplicitDestructible() { if (!explicitIndestructibleSet) indestructible = false; @@ -191,7 +188,6 @@ public: } bool hasExtendedData() const { return extendedData != 0; } - QQmlNotifier *objectNameNotifier() const; QHash *attachedProperties() const; static inline bool wasDeleted(QObject *); @@ -200,7 +196,7 @@ public: static inline void setQueuedForDeletion(QObject *); private: - // For objectNameNotifier and attachedProperties + // For attachedProperties mutable QQmlDataExtended *extendedData; }; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 1c00269..22d2845 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -439,11 +439,6 @@ void QQmlData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p static_cast(d)->parentChanged(o, p); } -void QQmlData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o) -{ - static_cast(d)->objectNameChanged(o); -} - void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int index, void **a) { QQmlData *ddata = QQmlData::get(object, false); @@ -1080,7 +1075,6 @@ public: ~QQmlDataExtended(); QHash attachedProperties; - QQmlNotifier objectNameNotifier; }; QQmlDataExtended::QQmlDataExtended() @@ -1180,12 +1174,6 @@ bool QQmlData::signalHasEndpoint(int index) return notifyList && (notifyList->connectionMask & (1ULL << quint64(index % 64))); } -QQmlNotifier *QQmlData::objectNameNotifier() const -{ - if (!extendedData) extendedData = new QQmlDataExtended; - return &extendedData->objectNameNotifier; -} - QHash *QQmlData::attachedProperties() const { if (!extendedData) extendedData = new QQmlDataExtended; @@ -1262,11 +1250,6 @@ void QQmlData::parentChanged(QObject *object, QObject *parent) Q_UNUSED(parent); } -void QQmlData::objectNameChanged(QObject *) -{ - if (extendedData) objectNameNotifier()->notify(); -} - bool QQmlData::hasBindingBit(int bit) const { if (bindingBitsSize > bit) diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 4bfe8ae..491629b 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -362,10 +362,7 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject QQmlAccessorProperties::Properties accessorProperties; - // Special case QObject as we don't want to add a qt_HasQmlAccessors classinfo to it - if (metaObject == &QObject::staticMetaObject) { - accessorProperties = QQmlAccessorProperties::properties(metaObject); - } else if (classInfoCount) { + if (classInfoCount) { int classInfoOffset = metaObject->classInfoOffset(); bool hasFastProperty = false; for (int ii = 0; ii < classInfoCount; ++ii) { @@ -392,9 +389,12 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject } } - // qMax(defaultMethods, methodOffset) to block the signals and slots of QObject::staticMetaObject - // incl. destroyed signals, objectNameChanged signal, deleteLater slot, _q_reregisterTimers slot. - int methodOffset = qMax(QObject::staticMetaObject.methodCount(), metaObject->methodOffset()); + //Used to block access to QObject::destroyed() and QObject::deleteLater() from QML + static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)"); + static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()"); + static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()"); + + int methodOffset = metaObject->methodOffset(); int signalOffset = signalCount - QMetaObjectPrivate::get(metaObject)->signalCount; // update() should have reserved enough space in the vector that this doesn't cause a realloc @@ -403,6 +403,8 @@ void QQmlPropertyCache::append(QQmlEngine *engine, const QMetaObject *metaObject signalHandlerIndexCache.resize(signalCount - signalHanderIndexCacheStart); int signalHandlerIndex = signalOffset; for (int ii = methodOffset; ii < methodCount; ++ii) { + if (ii == destroyedIdx1 || ii == destroyedIdx2 || ii == deleteLaterIdx) + continue; QMetaMethod m = metaObject->method(ii); if (m.access() == QMetaMethod::Private) continue; @@ -824,11 +826,15 @@ QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, } } + //Used to block access to QObject::destroyed() and QObject::deleteLater() from QML + static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)"); + static const int destroyedIdx2 = QObject::staticMetaObject.indexOfSignal("destroyed()"); + static const int deleteLaterIdx = QObject::staticMetaObject.indexOfSlot("deleteLater()"); + int methodCount = metaObject->methodCount(); - int defaultMethods = QObject::staticMetaObject.methodCount(); - for (int ii = methodCount - 1; ii >= defaultMethods; --ii) { - // >=defaultMethods to block the signals and slots of QObject::staticMetaObject - // incl. destroyed signals, objectNameChanged signal, deleteLater slot, _q_reregisterTimers slot. + for (int ii = methodCount - 1; ii >= 0; --ii) { + if (ii == destroyedIdx1 || ii == destroyedIdx2 || ii == deleteLaterIdx) + continue; QMetaMethod m = metaObject->method(ii); if (m.access() == QMetaMethod::Private) continue; diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 7e7b6eb..dabd09c 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -567,13 +567,8 @@ v8::Handle QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject return rv; } - if (ep && !result->isConstant()) { - - if (result->coreIndex == 0) - ep->captureProperty(QQmlData::get(object, true)->objectNameNotifier()); - else - ep->captureProperty(object, result->coreIndex, result->notifyIndex); - } + if (ep && !result->isConstant()) + ep->captureProperty(object, result->coreIndex, result->notifyIndex); if (result->isVMEProperty()) { typedef QQmlVMEMetaObject VMEMO; diff --git a/tests/auto/qml/qqmlecmascript/data/destroyedSignal.qml b/tests/auto/qml/qqmlecmascript/data/destroyedSignal.qml new file mode 100644 index 0000000..ac2df17 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/destroyedSignal.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +QtObject { + id: root + onDestroyed: {} //this should cause an error (destroyed should be hidden) +} diff --git a/tests/auto/qml/qqmlecmascript/data/objectNameChangedSignal.qml b/tests/auto/qml/qqmlecmascript/data/objectNameChangedSignal.qml new file mode 100644 index 0000000..a2ac701 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/objectNameChangedSignal.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +QtObject { + id: root + property bool test: false + + onObjectNameChanged: test = true +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 435724c..3740d73 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -215,6 +215,8 @@ private slots: void qobjectConnectionListExceptionHandling(); void nonscriptable(); void deleteLater(); + void objectNameChangedSignal(); + void destroyedSignal(); void in(); void typeOf(); void qtbug_24448(); @@ -5848,6 +5850,28 @@ void tst_qqmlecmascript::deleteLater() delete o; } +// objectNameChanged() should be usable from QML +void tst_qqmlecmascript::objectNameChangedSignal() +{ + QQmlComponent component(&engine, testFileUrl("objectNameChangedSignal.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test").toBool(), false); + o->setObjectName("obj"); + QCOMPARE(o->property("test").toBool(), true); + delete o; +} + +// destroyed() should not be usable from QML +void tst_qqmlecmascript::destroyedSignal() +{ + QQmlComponent component(&engine, testFileUrl("destroyedSignal.qml")); + QVERIFY(component.isError()); + + QString expectedErrorString = component.url().toString() + QLatin1String(":5:5: Cannot assign to non-existent property \"onDestroyed\""); + QCOMPARE(component.errors().at(0).toString(), expectedErrorString); +} + void tst_qqmlecmascript::in() { QQmlComponent component(&engine, testFileUrl("in.qml")); -- 2.7.4