Remove QQmlData::objectNameChanged callback.
authorMichael Brasser <michael.brasser@nokia.com>
Tue, 17 Apr 2012 03:54:20 +0000 (13:54 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 8 May 2012 22:56:16 +0000 (00:56 +0200)
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 <christopher.adams@nokia.com>
src/qml/qml/qqmlaccessors.cpp
src/qml/qml/qqmldata_p.h
src/qml/qml/qqmlengine.cpp
src/qml/qml/qqmlpropertycache.cpp
src/qml/qml/v8/qv8qobjectwrapper.cpp
tests/auto/qml/qqmlecmascript/data/destroyedSignal.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/objectNameChangedSignal.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index ceb4f44..65d6cce 100644 (file)
@@ -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)
index 4849db0..08f68b6 100644 (file)
@@ -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<int, QObject *> *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;
 };
 
index 1c00269..22d2845 100644 (file)
@@ -439,11 +439,6 @@ void QQmlData::parentChanged(QAbstractDeclarativeData *d, QObject *o, QObject *p
     static_cast<QQmlData *>(d)->parentChanged(o, p);
 }
 
-void QQmlData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o)
-{
-    static_cast<QQmlData *>(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<int, QObject *> 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<int, QObject *> *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)
index 4bfe8ae..491629b 100644 (file)
@@ -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;
index 7e7b6eb..dabd09c 100644 (file)
@@ -567,13 +567,8 @@ v8::Handle<v8::Value> 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 (file)
index 0000000..ac2df17
--- /dev/null
@@ -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 (file)
index 0000000..a2ac701
--- /dev/null
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+QtObject {
+    id: root
+    property bool test: false
+
+    onObjectNameChanged: test = true
+}
index 435724c..3740d73 100644 (file)
@@ -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"));