From 1079096a57112d9615812771adba18d2e9297320 Mon Sep 17 00:00:00 2001
From: Alan Alpert <alan.alpert@nokia.com>
Date: Mon, 24 May 2010 20:02:57 +1000
Subject: Added autotest for Component.createObject() without
 Qt.createComponent()

Also augmented the docs for both functions a little.

Task-number: QTBUG-10926
---
 doc/src/declarative/declarativeui.qdoc             |  2 +-
 doc/src/declarative/dynamicobjects.qdoc            |  4 ++--
 doc/src/snippets/declarative/Sprite.qml            |  2 ++
 doc/src/snippets/declarative/createComponent.qml   |  2 ++
 src/declarative/qml/qdeclarativecomponent.cpp      | 10 +++++---
 src/declarative/qml/qdeclarativeengine.cpp         |  4 ++--
 .../qdeclarativecomponent/data/createObject.qml    | 16 +++++++++++++
 .../tst_qdeclarativecomponent.cpp                  | 28 ++++++++++++++++++++++
 8 files changed, 60 insertions(+), 8 deletions(-)
 create mode 100644 tests/auto/declarative/qdeclarativecomponent/data/createObject.qml

diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc
index 5283ba8..1199b26 100644
--- a/doc/src/declarative/declarativeui.qdoc
+++ b/doc/src/declarative/declarativeui.qdoc
@@ -98,7 +98,7 @@ application or to build completely new applications.  QML is fully \l
 \o \l {qdeclarativemodules.html}{Modules}
 \o \l {qdeclarativefocus.html}{Keyboard Focus}
 \o \l {Extending types from QML}
-\o \l {Dynamic Object Creation}
+\o \l {qdeclarativedynamicobjects.html}{Dynamic Object Creation}
 \o \l {qmlruntime.html}{The Qt Declarative Runtime}
 \endlist
 
diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc
index 2688ee5..633489b 100644
--- a/doc/src/declarative/dynamicobjects.qdoc
+++ b/doc/src/declarative/dynamicobjects.qdoc
@@ -75,12 +75,12 @@ the parent later you can safely pass null to this function.
 
 Here is an example. Here is a \c Sprite.qml, which defines a simple QML component:
 
-\quotefile doc/src/snippets/declarative/Sprite.qml
+\snippet doc/src/snippets/declarative/Sprite.qml 0
 
 Our main application file, \c main.qml, imports a \c componentCreation.js JavaScript file
 that will create \c Sprite objects:
 
-\quotefile doc/src/snippets/declarative/createComponent.qml
+\snippet doc/src/snippets/declarative/createComponent.qml 0
 
 Here is \c componentCreation.js. Remember that QML files that might be loaded
 over the network cannot be expected to be ready immediately:
diff --git a/doc/src/snippets/declarative/Sprite.qml b/doc/src/snippets/declarative/Sprite.qml
index b306cb0..5f32b0a 100644
--- a/doc/src/snippets/declarative/Sprite.qml
+++ b/doc/src/snippets/declarative/Sprite.qml
@@ -39,6 +39,8 @@
 **
 ****************************************************************************/
 
+//![0]
 import Qt 4.7
 
 Rectangle { width: 80; height: 50; color: "red" }
+//![0]
diff --git a/doc/src/snippets/declarative/createComponent.qml b/doc/src/snippets/declarative/createComponent.qml
index 910ea95..3686188 100644
--- a/doc/src/snippets/declarative/createComponent.qml
+++ b/doc/src/snippets/declarative/createComponent.qml
@@ -39,6 +39,7 @@
 **
 ****************************************************************************/
 
+//![0]
 import Qt 4.7
 import "componentCreation.js" as MyModule
 
@@ -48,3 +49,4 @@ Rectangle {
 
     Component.onCompleted: MyModule.createSpriteObjects();
 }
+//![0]
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 3b782e7..7aa17e8 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -549,15 +549,19 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
     Returns an object instance from this component, or null if object creation fails.
 
     The object will be created in the same context as the one in which the component
-    was created.
+    was created. This function will always return null when called on components
+    which were not created in QML.
 
     Note that if the returned object is to be displayed, its \c parent must be set to
-    an existing item in a scene, or else the object will not be visible.
+    an existing item in a scene, or else the object will not be visible. The parent
+    argument is required to help you avoid this, you must explicitly pass in null if
+    you wish to create an object without setting a parent.
 */
 
 /*!
     \internal
-    A version of create which returns a scriptObject, for use in script
+    A version of create which returns a scriptObject, for use in script.
+    This function will only work on components created in QML.
 
     Sets graphics object parent because forgetting to do this is a frequent
     and serious problem.
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index df9aa59..a7384a9 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -1049,9 +1049,9 @@ If you are certain the files will be local, you could simplify to:
 
 \snippet doc/src/snippets/declarative/componentCreation.js 2
 
-The methods and properties of the Component element are defined in its own
+The methods and properties of the \l {Component} element are defined in its own
 page, but when using it dynamically only two methods are usually used.
-\c Component.createObject() returns the created object or \c null if there is an error.
+ \l {Component::createObject()}{Component.createObject()} returns the created object or \c null if there is an error.
 If there is an error, \l {Component::errorString()}{Component.errorString()} describes
 the error that occurred. Note that createObject() takes exactly one argument, which is set
 to the parent of the created object. Graphical objects without a parent will not appear
diff --git a/tests/auto/declarative/qdeclarativecomponent/data/createObject.qml b/tests/auto/declarative/qdeclarativecomponent/data/createObject.qml
new file mode 100644
index 0000000..4ee1e75
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecomponent/data/createObject.qml
@@ -0,0 +1,16 @@
+import Qt 4.7
+
+Item{
+    id: root
+    property QtObject qobject : null
+    property QtObject declarativeitem : null
+    property QtObject graphicswidget: null
+    Component{id: a; QtObject{} }
+    Component{id: b; Item{} }
+    Component{id: c; QGraphicsWidget{} }
+    Component.onCompleted: {
+        root.qobject = a.createObject(root);
+        root.declarativeitem = b.createObject(root);
+        root.graphicswidget = c.createObject(root);
+    }
+}
diff --git a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
index c9e304c..faa1c21 100644
--- a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
+++ b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
@@ -39,7 +39,9 @@
 **
 ****************************************************************************/
 #include <qtest.h>
+#include <QDebug>
 
+#include <QtGui/qgraphicsitem.h>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
 
@@ -51,6 +53,7 @@ public:
 
 private slots:
     void loadEmptyUrl();
+    void qmlCreateObject();
 
 private:
     QDeclarativeEngine engine;
@@ -70,6 +73,31 @@ void tst_qdeclarativecomponent::loadEmptyUrl()
     QCOMPARE(error.description(), QLatin1String("Invalid empty URL"));
 }
 
+void tst_qdeclarativecomponent::qmlCreateObject()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/createObject.qml"));
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+
+    QObject *testObject1 = object->property("qobject").value<QObject*>();
+    QVERIFY(testObject1);
+    QVERIFY(testObject1->parent() == object);
+
+    QObject *testObject2 = object->property("declarativeitem").value<QObject*>();
+    QVERIFY(testObject2);
+    QVERIFY(testObject2->parent() == object);
+    QCOMPARE(testObject2->metaObject()->className(), "QDeclarativeItem");
+
+    //Note that QGraphicsObjects are not exposed to QML for instantiation, and so can't be used in a component directly
+    //Also this is actually the extended type QDeclarativeGraphicsWidget, but it still doesn't inherit QDeclarativeItem
+    QGraphicsObject *testObject3 = qobject_cast<QGraphicsObject*>(object->property("graphicswidget").value<QObject*>());
+    QVERIFY(testObject3);
+    QVERIFY(testObject3->parent() == object);
+    QVERIFY(testObject3->parentItem() == qobject_cast<QGraphicsObject*>(object));
+    QCOMPARE(testObject3->metaObject()->className(), "QDeclarativeGraphicsWidget");
+}
+
 QTEST_MAIN(tst_qdeclarativecomponent)
 
 #include "tst_qdeclarativecomponent.moc"
-- 
cgit v0.12