summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brasser <michael.brasser@nokia.com>2009-06-09 03:51:40 (GMT)
committerMichael Brasser <michael.brasser@nokia.com>2009-06-09 03:51:40 (GMT)
commit9d9cf497c1d21fe80b5bdd0db2a2fa145ebe9ab0 (patch)
tree13ca8dc78969c32ff5cf19deb21adabd3f778113
parent60e291e39040fa4d59a646427dcea8ddf108bf5c (diff)
parentdb4addcf3408140bb34fa8884c7192c1d9667be8 (diff)
downloadQt-9d9cf497c1d21fe80b5bdd0db2a2fa145ebe9ab0.zip
Qt-9d9cf497c1d21fe80b5bdd0db2a2fa145ebe9ab0.tar.gz
Qt-9d9cf497c1d21fe80b5bdd0db2a2fa145ebe9ab0.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
-rw-r--r--src/declarative/qml/qmlcomponent.cpp18
-rw-r--r--src/declarative/qml/qmlcomponent.h11
-rw-r--r--src/declarative/qml/qmlengine.cpp122
-rw-r--r--src/declarative/qml/qmlengine.h9
4 files changed, 156 insertions, 4 deletions
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index 78137e8..267fba8 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -387,6 +387,24 @@ QmlComponent::QmlComponent(QmlComponentPrivate &dd, QObject *parent)
}
/*!
+ Create a script object instance from this component. Returns a null
+ script object if creation failed. It will create the instance in the
+ engine's \l {QmlEngine::rootContext()}{root context}.
+
+ Similar to QmlComponent::create(), but creates an object suitable
+ for usage within scripts.
+*/
+QScriptValue QmlComponent::createObject()
+{
+ Q_D(QmlComponent);
+ QObject* ret = create();
+ if(ret)
+ return QmlEngine::qmlScriptObject(ret, d->engine);
+ else
+ return d->engine->scriptEngine()->nullValue();
+}
+
+/*!
Create an object instance from this component. Returns 0 if creation
failed. \a context specifies the context within which to create the object
instance.
diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h
index e7386d9..bb76c8b 100644
--- a/src/declarative/qml/qmlcomponent.h
+++ b/src/declarative/qml/qmlcomponent.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qstring.h>
+#include <QtScript/qscriptvalue.h>
#include <QtDeclarative/qfxglobal.h>
#include <QtDeclarative/qml.h>
#include <QtDeclarative/qmlerror.h>
@@ -70,18 +71,20 @@ public:
const QUrl &baseUrl=QUrl(), QObject *parent=0);
virtual ~QmlComponent();
+ Q_ENUMS( Status );
enum Status { Null, Ready, Loading, Error };
Status status() const;
- bool isNull() const;
- bool isReady() const;
- bool isError() const;
- bool isLoading() const;
+ Q_INVOKABLE bool isNull() const;
+ Q_INVOKABLE bool isReady() const;
+ Q_INVOKABLE bool isError() const;
+ Q_INVOKABLE bool isLoading() const;
QList<QmlError> errors() const;
QUrl url() const;
+ Q_INVOKABLE QScriptValue createObject();
virtual QObject *create(QmlContext *context = 0);
virtual QObject *beginCreate(QmlContext *);
virtual void completeCreate();
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 18f28ed..d8ca809 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -203,6 +203,13 @@ void QmlEnginePrivate::init()
debugger->attachTo(&scriptEngine);
}
#endif
+ //###needed for the other funcs, but should it be exposed?
+ scriptEngine.globalObject().setProperty(QLatin1String("qmlEngine"),
+ scriptEngine.newQObject(q));
+ scriptEngine.globalObject().setProperty(QLatin1String("evalQml"),
+ scriptEngine.newFunction(QmlEngine::createQMLObject, 1));
+ scriptEngine.globalObject().setProperty(QLatin1String("createComponent"),
+ scriptEngine.newFunction(QmlEngine::createComponent, 1));
}
QmlContext *QmlEnginePrivate::setCurrentBindContext(QmlContext *c)
@@ -808,7 +815,122 @@ QmlEngine *QmlEngine::activeEngine()
return engines->top();
}
+/*!
+ Creates a QScriptValue allowing you to use \a object in QML script.
+ \a engine is the QmlEngine it is to be created in.
+
+ The QScriptValue returned is a QtScript Object, not a QtScript QObject, due
+ to the special needs of QML requiring more functionality than a standard
+ QtScript QObject.
+
+ You'll want to use this function if you are writing C++ code which
+ dynamically creates and returns objects when called from QtScript,
+ and these objects are visual items in the QML tree.
+
+ \sa QmlEngine::newQObject()
+*/
+QScriptValue QmlEngine::qmlScriptObject(QObject* object, QmlEngine* engine)
+{
+ return engine->scriptEngine()->newObject(new QmlObjectScriptClass(engine),
+ engine->scriptEngine()->newQObject(object));
+}
+
+/*!
+ This function is intended for use inside QML only. In C++ just create a
+ component object as usual.
+
+ This function takes the URL of a QML file as its only argument. It returns
+ a component object which can be used to create and load that QML file.
+
+ Example JavaScript:
+ \code
+ component = createComponent("Sprite.qml");
+ if(component.isReady()){
+ sprite = component.create();
+ if(sprite == 0){
+ // Error Handling
+ }else{
+ sprite.parent = page;
+ sprite.x = 200;
+ //...
+ }
+ }else{
+ // The finishCreation function does the same thing as the above
+ // if(component.isReady()) branch
+ component.statusChanged.connect(finishCreation);
+ }
+ \endcode
+
+ Remember that QML files that might be loaded over the network cannot be
+ expected to be ready immediately.
+*/
+QScriptValue QmlEngine::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ QmlComponent* c;
+ QmlEngine* activeEngine = qobject_cast<QmlEngine*>(
+ engine->globalObject().property(QLatin1String("qmlEngine")).toQObject());
+ if(ctxt->argumentCount() != 1 || !activeEngine){
+ c = new QmlComponent(activeEngine);
+ }else{
+ c = new QmlComponent(activeEngine, QUrl(ctxt->argument(0).toString()),
+ activeEngine);
+ }
+ return engine->newQObject(c);
+}
+/*!
+ Creates a new object from the specified string of qml. If a second argument
+ is provided, this is treated as the filepath that the qml came from.
+
+ This function is intended for use inside QML only. It is intended to behave
+ similarly to eval, but for creating QML elements. Thus, it is called as
+ evalQml() in QtScript.
+
+ Returns the created object, or null if there is an error. In the case of an
+ error, details of the error are output using qWarning().
+*/
+QScriptValue QmlEngine::createQMLObject(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ QmlEngine* activeEngine = qobject_cast<QmlEngine*>(
+ engine->globalObject().property(QLatin1String("qmlEngine")).toQObject());
+ if(ctxt->argumentCount() < 1 || !activeEngine){
+ if(ctxt->argumentCount() < 1){
+ qWarning() << "createQMLObject requires a string argument.";
+ }else{
+ qWarning() << "createQMLObject failed inexplicably.";
+ }
+ return engine->nullValue();
+ }
+
+ QString qml = ctxt->argument(0).toString();
+ QUrl url;
+ if(ctxt->argumentCount() > 1)
+ url = QUrl(ctxt->argument(1).toString());
+ QmlComponent component(activeEngine, qml.toUtf8(), url);
+ if(component.isError()) {
+ QList<QmlError> errors = component.errors();
+ foreach (const QmlError &error, errors) {
+ qWarning() << error;
+ }
+
+ return engine->nullValue();
+ }
+
+ QObject *obj = component.create();
+ if(component.isError()) {
+ QList<QmlError> errors = component.errors();
+ foreach (const QmlError &error, errors) {
+ qWarning() << error;
+ }
+
+ return engine->nullValue();
+ }
+
+ if(obj){
+ return qmlScriptObject(obj, activeEngine);
+ }
+ return engine->nullValue();
+}
QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b)
: q(b), ctxt(0), sseData(0), proxy(0), me(0), trackChange(false), line(-1), id(0), log(0)
diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h
index 9382389..ca66097 100644
--- a/src/declarative/qml/qmlengine.h
+++ b/src/declarative/qml/qmlengine.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qmap.h>
+#include <QtScript/qscriptvalue.h>
QT_BEGIN_HEADER
@@ -57,6 +58,7 @@ class QmlExpression;
class QmlContext;
class QUrl;
class QScriptEngine;
+class QScriptContext;
class QNetworkAccessManager;
class Q_DECLARATIVE_EXPORT QmlEngine : public QObject
{
@@ -85,6 +87,13 @@ public:
static QmlContext *contextForObject(const QObject *);
static void setContextForObject(QObject *, QmlContext *);
+
+ static QScriptValue qmlScriptObject(QObject*, QmlEngine*);
+
+ // Below two functions provide a way to dynamically create objects from JS
+ static QScriptValue createComponent(QScriptContext*, QScriptEngine*);
+ static QScriptValue createQMLObject(QScriptContext*, QScriptEngine*);
+
private:
// LK: move to the private class
QScriptEngine *scriptEngine();