Reverse lookup ids by object pointer
authorAaron Kennedy <aaron.kennedy@nokia.com>
Mon, 25 Jul 2011 06:24:01 +0000 (16:24 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 25 Jul 2011 07:43:14 +0000 (09:43 +0200)
Task-number: QTBUG-18554

Change-Id: Ia4effb629d19aa36b835f6c09a63d9495e5c26e7
Reviewed-on: http://codereview.qt.nokia.com/2079
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
src/declarative/qml/qdeclarativecontext.cpp
src/declarative/qml/qdeclarativecontext.h
tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp

index caa3b0c..d625a1f 100644 (file)
@@ -402,6 +402,20 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
 }
 
 /*!
+Returns the name of \a object in this context, or an empty string if \a object 
+is not named in the context.  Objects are named by setContextProperty(), or by ids in
+the case of QML created contexts.
+
+If the object has multiple names, the first is returned.
+*/
+QString QDeclarativeContext::nameForObject(QObject *object) const
+{
+    Q_D(const QDeclarativeContext);
+
+    return d->data->findObjectId(object);
+}
+
+/*!
     Resolves the URL \a src relative to the URL of the
     containing component.
 
@@ -693,12 +707,19 @@ void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data)
 
 QString QDeclarativeContextData::findObjectId(const QObject *obj) const
 {
-    if (!idValues || !propertyNames)
+    if (!propertyNames)
         return QString();
 
-    for (int i=0; i<idValueCount; i++) {
-        if (idValues[i] == obj)
-            return propertyNames->findId(i);
+    for (int ii = 0; ii < idValueCount; ii++) {
+        if (idValues[ii] == obj)
+            return propertyNames->findId(ii);
+    }
+
+    if (publicContext) {
+        QDeclarativeContextPrivate *p = QDeclarativeContextPrivate::get(publicContext);
+        for (int ii = 0; ii < p->propertyValues.count(); ++ii)
+            if (p->propertyValues.at(ii) == QVariant::fromValue((QObject *)obj))
+                return propertyNames->findId(ii);
     }
 
     if (linkedContext)
index fd33ccd..d8e8506 100644 (file)
@@ -83,6 +83,8 @@ public:
     void setContextProperty(const QString &, QObject *);
     void setContextProperty(const QString &, const QVariant &);
 
+    QString nameForObject(QObject *) const;
+
     QUrl resolvedUrl(const QUrl &);
 
     void setBaseUrl(const QUrl &);
index fdb8ff7..89d08e0 100644 (file)
@@ -67,6 +67,7 @@ private slots:
     void destruction();
     void idAsContextProperty();
     void readOnlyContexts();
+    void nameForObject();
 
 private:
     QDeclarativeEngine engine;
@@ -463,6 +464,37 @@ void tst_qdeclarativecontext::readOnlyContexts()
     delete obj;
 }
 
+void tst_qdeclarativecontext::nameForObject()
+{
+    QObject o1;
+    QObject o2;
+    QObject o3;
+
+    QDeclarativeEngine engine;
+
+    // As a context property
+    engine.rootContext()->setContextProperty("o1", &o1);
+    engine.rootContext()->setContextProperty("o2", &o2);
+    engine.rootContext()->setContextProperty("o1_2", &o1);
+
+    QCOMPARE(engine.rootContext()->nameForObject(&o1), QString("o1"));
+    QCOMPARE(engine.rootContext()->nameForObject(&o2), QString("o2"));
+    QCOMPARE(engine.rootContext()->nameForObject(&o3), QString());
+
+    // As an id
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 1.0; QtObject { id: root; property QtObject o: QtObject { id: nested } }", QUrl());
+
+    QObject *o = component.create();
+    QVERIFY(o != 0);
+
+    QCOMPARE(qmlContext(o)->nameForObject(o), QString("root"));
+    QCOMPARE(qmlContext(o)->nameForObject(qvariant_cast<QObject*>(o->property("o"))), QString("nested"));
+    QCOMPARE(qmlContext(o)->nameForObject(&o1), QString());
+
+    delete o;
+}
+
 QTEST_MAIN(tst_qdeclarativecontext)
 
 #include "tst_qdeclarativecontext.moc"