diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-06-09 03:51:40 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-06-09 03:51:40 (GMT) |
commit | 9d9cf497c1d21fe80b5bdd0db2a2fa145ebe9ab0 (patch) | |
tree | 13ca8dc78969c32ff5cf19deb21adabd3f778113 | |
parent | 60e291e39040fa4d59a646427dcea8ddf108bf5c (diff) | |
parent | db4addcf3408140bb34fa8884c7192c1d9667be8 (diff) | |
download | Qt-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.cpp | 18 | ||||
-rw-r--r-- | src/declarative/qml/qmlcomponent.h | 11 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 122 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.h | 9 |
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(); |