summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qml.pri2
-rw-r--r--src/declarative/qml/qmlcompiler.cpp32
-rw-r--r--src/declarative/qml/qmlcompiler_p.h3
-rw-r--r--src/declarative/qml/qmlengine.cpp70
-rw-r--r--src/declarative/qml/qmlengine_p.h3
-rw-r--r--src/declarative/qml/qmlenginedebug.cpp81
-rw-r--r--src/declarative/qml/qmlenginedebug_p.h2
-rw-r--r--src/declarative/qml/qmlexpression.cpp16
-rw-r--r--src/declarative/qml/qmlexpression.h2
-rw-r--r--src/declarative/qml/qmlexpression_p.h4
-rw-r--r--src/declarative/qml/qmlinstruction_p.h6
-rw-r--r--src/declarative/qml/qmlparser.cpp10
-rw-r--r--src/declarative/qml/qmlparser_p.h2
-rw-r--r--src/declarative/qml/qmlscriptstring.cpp154
-rw-r--r--src/declarative/qml/qmlscriptstring.h87
-rw-r--r--src/declarative/qml/qmlsqldatabase.cpp2
-rw-r--r--src/declarative/qml/qmlvme.cpp16
-rw-r--r--src/declarative/qml/qmlvmemetaobject.cpp3
-rw-r--r--src/declarative/qml/qmlvmemetaobject_p.h1
19 files changed, 457 insertions, 39 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 58a18a2..b6e86a8 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -40,6 +40,7 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlpropertycache.cpp \
qml/qmlintegercache.cpp \
qml/qmltypenamecache.cpp \
+ qml/qmlscriptstring.cpp \
qml/qmlobjectscriptclass.cpp \
qml/qmlcontextscriptclass.cpp \
qml/qmlglobalscriptclass.cpp \
@@ -102,6 +103,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlpropertycache_p.h \
qml/qmlintegercache_p.h \
qml/qmltypenamecache_p.h \
+ qml/qmlscriptstring.h \
qml/qmlobjectscriptclass_p.h \
qml/qmlcontextscriptclass_p.h \
qml/qmlglobalscriptclass_p.h \
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index e2fd7cb..726051e 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -69,6 +69,7 @@
#include <private/qmlexpression_p.h>
#include "qmlmetaproperty_p.h"
#include "qmlrewrite_p.h"
+#include <QtDeclarative/qmlscriptstring.h>
#include "qmlscriptparser_p.h"
@@ -860,6 +861,17 @@ void QmlCompiler::genObject(QmlParser::Object *obj)
void QmlCompiler::genObjectBody(QmlParser::Object *obj)
{
+ typedef QPair<Property *, int> PropPair;
+ foreach(const PropPair &prop, obj->scriptStringProperties) {
+ QmlInstruction ss;
+ ss.type = QmlInstruction::StoreScriptString;
+ ss.storeScriptString.propertyIndex = prop.first->index;
+ ss.storeScriptString.value =
+ output->indexForString(prop.first->values.at(0)->value.asScript());
+ ss.storeScriptString.scope = prop.second;
+ output->bytecode << ss;
+ }
+
bool seenDefer = false;
foreach(Property *prop, obj->valueProperties) {
if (prop->isDeferred) {
@@ -1371,6 +1383,10 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
COMPILE_CHECK(buildListProperty(prop, obj, ctxt));
+ } else if (prop->type == qMetaTypeId<QmlScriptString>()) {
+
+ COMPILE_CHECK(buildScriptStringProperty(prop, obj, ctxt));
+
} else {
COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt));
@@ -1823,6 +1839,22 @@ bool QmlCompiler::buildListProperty(QmlParser::Property *prop,
return true;
}
+// Compiles an assignment to a QmlScriptString property
+bool QmlCompiler::buildScriptStringProperty(QmlParser::Property *prop,
+ QmlParser::Object *obj,
+ const BindingContext &ctxt)
+{
+ if (prop->values.count() > 1)
+ COMPILE_EXCEPTION(prop->values.at(1), qApp->translate("QmlCompiler", "Cannot assign multiple values to a script property"));
+
+ if (prop->values.at(0)->object || !prop->values.at(0)->value.isScript())
+ COMPILE_EXCEPTION(prop->values.at(0), qApp->translate("QmlCompiler", "Invalid property assignment: script expected"));
+
+ obj->addScriptStringProperty(prop, ctxt.stack);
+
+ return true;
+}
+
// Compile regular property assignments of the form "property: <value>"
//
// ### The following problems exist
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index cff4937..8a9ca9c 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -197,6 +197,9 @@ private:
bool buildListProperty(QmlParser::Property *prop,
QmlParser::Object *obj,
const BindingContext &ctxt);
+ bool buildScriptStringProperty(QmlParser::Property *prop,
+ QmlParser::Object *obj,
+ const BindingContext &ctxt);
bool buildPropertyAssignment(QmlParser::Property *prop,
QmlParser::Object *obj,
const BindingContext &ctxt);
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 528e8c9..9fad80b 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -76,9 +76,10 @@
#include <QtCore/qdir.h>
#include <QtGui/qcolor.h>
#include <QtGui/qvector3d.h>
+#include <QtGui/qsound.h>
#include <qmlcomponent.h>
-#include "private/qmlcomponentjs_p.h"
-#include "private/qmlmetaproperty_p.h"
+#include <private/qmlcomponentjs_p.h>
+#include <private/qmlmetaproperty_p.h>
#include <private/qmlbinding_p.h>
#include <private/qmlvme_p.h>
#include <private/qmlenginedebug_p.h>
@@ -87,6 +88,7 @@
#include <private/qmlsqldatabase_p.h>
#include <private/qmltypenamescriptclass_p.h>
#include <private/qmllistscriptclass_p.h>
+#include <QtDeclarative/qmlscriptstring.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include "qt_windows.h"
@@ -153,12 +155,14 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
qtObject.setProperty(QLatin1String("darker"), scriptEngine.newFunction(QmlEnginePrivate::darker, 1));
qtObject.setProperty(QLatin1String("tint"), scriptEngine.newFunction(QmlEnginePrivate::tint, 2));
+ //misc methods
+ qtObject.setProperty(QLatin1String("playSound"), scriptEngine.newFunction(QmlEnginePrivate::playSound, 1));
+
scriptEngine.globalObject().setProperty(QLatin1String("createQmlObject"),
scriptEngine.newFunction(QmlEnginePrivate::createQmlObject, 1));
scriptEngine.globalObject().setProperty(QLatin1String("createComponent"),
scriptEngine.newFunction(QmlEnginePrivate::createComponent, 1));
- //scriptEngine.globalObject().setScriptClass(new QmlGlobalScriptClass(&scriptEngine));
globalClass = new QmlGlobalScriptClass(&scriptEngine);
}
@@ -216,6 +220,9 @@ Q_GLOBAL_STATIC(QmlEngineDebugServer, qmlEngineDebugServer);
void QmlEnginePrivate::init()
{
Q_Q(QmlEngine);
+ qRegisterMetaType<QVariant>("QVariant");
+ qRegisterMetaType<QmlScriptString>("QmlScriptString");
+
scriptEngine.installTranslatorFunctions();
contextClass = new QmlContextScriptClass(q);
objectClass = new QmlObjectScriptClass(q);
@@ -281,8 +288,6 @@ QmlEngine::QmlEngine(QObject *parent)
{
Q_D(QmlEngine);
d->init();
-
- qRegisterMetaType<QVariant>("QVariant");
}
/*!
@@ -401,7 +406,12 @@ QmlContext *QmlEngine::contextForObject(const QObject *object)
QmlDeclarativeData *data =
static_cast<QmlDeclarativeData *>(priv->declarativeData);
- return data?data->context:0;
+ if (!data)
+ return 0;
+ else if (data->outerContext)
+ return data->outerContext;
+ else
+ return data->context;
}
/*!
@@ -565,6 +575,17 @@ QScriptValue QmlEnginePrivate::qmlScriptObject(QObject* object,
}
/*!
+ Returns the QmlContext for the executing QScript \a ctxt.
+*/
+QmlContext *QmlEnginePrivate::getContext(QScriptContext *ctxt)
+{
+ QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
+ Q_ASSERT(scopeNode.isValid());
+ Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
+ return contextClass->contextFromValue(scopeNode);
+}
+
+/*!
This function is intended for use inside QML only. In C++ just create a
component object as usual.
@@ -626,7 +647,7 @@ QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt,
static_cast<QmlScriptEngine*>(engine)->p;
QmlEngine* activeEngine = activeEnginePriv->q_func();
- QmlContext* context = activeEnginePriv->currentExpression->context();
+ QmlContext* context = activeEnginePriv->getContext(ctxt);
if(ctxt->argumentCount() != 1) {
c = new QmlComponentJS(activeEngine);
}else{
@@ -647,7 +668,7 @@ QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt,
Example (where targetItem is the id of an existing QML item):
\code
- newObject = createQmlObject('Rectangle {color: "red"; width: 20; height: 20}',
+ newObject = createQmlObject('import Qt 4.6; Rectangle {color: "red"; width: 20; height: 20}',
targetItem, "dynamicSnippet1");
\endcode
@@ -677,9 +698,16 @@ QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngi
QUrl url;
if(ctxt->argumentCount() > 2)
url = QUrl(ctxt->argument(2).toString());
+ else
+ url = QUrl(QLatin1String("DynamicQML"));
QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
QmlContext *qmlCtxt = qmlContext(parentArg);
- url = qmlCtxt->resolvedUrl(url);
+ if (url.isEmpty()) {
+ url = qmlCtxt->resolvedUrl(QUrl(QLatin1String("<Unknown File>")));
+ } else {
+ url = qmlCtxt->resolvedUrl(url);
+ }
+
QmlComponent component(activeEngine, qml.toUtf8(), url);
if(component.isError()) {
QList<QmlError> errors = component.errors();
@@ -836,6 +864,30 @@ QScriptValue QmlEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engin
return qScriptValueFromValue(engine, qVariantFromValue(color));
}
+QScriptValue QmlEnginePrivate::playSound(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ if (ctxt->argumentCount() < 1)
+ return engine->undefinedValue();
+
+ QUrl url(ctxt->argument(0).toString());
+
+ QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine);
+ if (url.isRelative()) {
+ QmlContext *context = enginePriv->getContext(ctxt);
+ if (!context)
+ return engine->undefinedValue();
+
+ url = context->resolvedUrl(url);
+ }
+
+ if (url.scheme() == QLatin1String("file")) {
+
+ QSound::play(url.toLocalFile());
+
+ }
+ return engine->undefinedValue();
+}
+
/*!
This function allows tinting one color with another.
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index a85ac55..a74854d 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -259,10 +259,13 @@ public:
static QScriptValue darker(QScriptContext*, QScriptEngine*);
static QScriptValue tint(QScriptContext*, QScriptEngine*);
+ static QScriptValue playSound(QScriptContext*, QScriptEngine*);
+
static QScriptEngine *getScriptEngine(QmlEngine *e) { return &e->d_func()->scriptEngine; }
static QmlEngine *getEngine(QScriptEngine *e) { return static_cast<QmlScriptEngine*>(e)->p->q_func(); }
static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); }
static QmlEnginePrivate *get(QScriptEngine *e) { return static_cast<QmlScriptEngine*>(e)->p; }
+ QmlContext *getContext(QScriptContext *);
};
diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp
index e20616a..7178e6c 100644
--- a/src/declarative/qml/qmlenginedebug.cpp
+++ b/src/declarative/qml/qmlenginedebug.cpp
@@ -80,7 +80,8 @@ QDataStream &operator>>(QDataStream &ds,
QDataStream &operator<<(QDataStream &ds,
const QmlEngineDebugServer::QmlObjectProperty &data)
{
- ds << (int)data.type << data.name << data.value << data.binding << data.hasNotifySignal;
+ ds << (int)data.type << data.name << data.value << data.valueTypeName
+ << data.binding << data.hasNotifySignal;
return ds;
}
@@ -88,7 +89,8 @@ QDataStream &operator>>(QDataStream &ds,
QmlEngineDebugServer::QmlObjectProperty &data)
{
int type;
- ds >> type >> data.name >> data.value >> data.binding >> data.hasNotifySignal;
+ ds >> type >> data.name >> data.value >> data.valueTypeName
+ >> data.binding >> data.hasNotifySignal;
data.type = (QmlEngineDebugServer::QmlObjectProperty::Type)type;
return ds;
}
@@ -101,6 +103,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx)
QMetaProperty prop = obj->metaObject()->property(propIdx);
rv.type = QmlObjectProperty::Unknown;
+ rv.valueTypeName = QString::fromUtf8(prop.typeName());
rv.name = prop.name();
rv.hasNotifySignal = prop.hasNotifySignal();
QmlAbstractBinding *binding = QmlMetaProperty(obj, rv.name).binding();
@@ -116,6 +119,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx)
QmlMetaType::isQmlList(prop.userType())) {
rv.type = QmlObjectProperty::List;
}
+
return rv;
}
@@ -149,7 +153,7 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message,
int ctxtId = QmlDebugService::idForObject(ctxt);
message << ctxtName << ctxtId;
-
+
int count = 0;
for (QSet<QmlContext *>::ConstIterator iter = p->childContexts.begin();
@@ -184,6 +188,32 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message,
}
}
+QVariant QmlEngineDebugServer::serializableVariant(const QVariant &value)
+{
+ if (value.type() < QVariant::UserType)
+ return value;
+
+ if (!value.toString().isEmpty())
+ return value.toString();
+
+ QVariant v;
+ if (value.type() == QVariant::UserType || QmlMetaType::isObject(value.userType())) {
+ QObject *o = QmlMetaType::toQObject(value);
+ if (o) {
+ QString objectName = o->objectName();
+ if (objectName.isEmpty())
+ objectName = QLatin1String("<unnamed>");
+ v = QString::fromUtf8(o->metaObject()->className()) +
+ QLatin1String(": ") + objectName;
+ }
+ }
+
+ if (v.isNull())
+ v = QString::fromUtf8(value.typeName());
+
+ return v;
+}
+
QmlEngineDebugServer::QmlObjectData
QmlEngineDebugServer::objectData(QObject *object)
{
@@ -310,29 +340,42 @@ void QmlEngineDebugServer::messageReceived(const QByteArray &message)
ds >> queryId;
m_watch->removeWatch(queryId);
+ } else if (type == "EVAL_EXPRESSION") {
+ int queryId;
+ int objectId;
+ QString expr;
+
+ ds >> queryId >> objectId >> expr;
+
+ QObject *object = QmlDebugService::objectForId(objectId);
+ QmlContext *context = qmlContext(object);
+ QVariant result;
+ if (object && context) {
+ QmlExpression *exprObj = new QmlExpression(context, expr, object);
+ bool undefined = false;
+ QVariant value = exprObj->value(&undefined);
+ if (undefined)
+ result = QLatin1String("<undefined>");
+ else
+ result = serializableVariant(value);
+ delete exprObj;
+ } else {
+ result = QLatin1String("<unknown context>");
+ }
+
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result;
+
+ sendMessage(reply);
}
}
void QmlEngineDebugServer::propertyChanged(int id, int objectId, const QByteArray &property, const QVariant &value)
{
QByteArray reply;
- QVariant v;
+ QVariant v = serializableVariant(value);
QDataStream rs(&reply, QIODevice::WriteOnly);
-
- if (value.type() == QVariant::UserType || QmlMetaType::isObject(value.userType())) {
- QObject *o = QmlMetaType::toQObject(value);
- if (o) {
- QString objectName = o->objectName();
- if (objectName.isEmpty())
- objectName = QLatin1String("<unnamed>");
- v = QString::fromUtf8(o->metaObject()->className()) +
- QLatin1String(": ") + objectName;
- }
- if (v.isNull())
- v = value.toString();
- } else {
- v = value;
- }
rs << QByteArray("UPDATE_WATCH") << id << objectId << property << v;
diff --git a/src/declarative/qml/qmlenginedebug_p.h b/src/declarative/qml/qmlenginedebug_p.h
index e2f903c..075a711 100644
--- a/src/declarative/qml/qmlenginedebug_p.h
+++ b/src/declarative/qml/qmlenginedebug_p.h
@@ -85,6 +85,7 @@ public:
Type type;
QString name;
QVariant value;
+ QString valueTypeName;
QString binding;
bool hasNotifySignal;
};
@@ -103,6 +104,7 @@ private:
void buildObjectDump(QDataStream &, QObject *, bool);
QmlObjectData objectData(QObject *);
QmlObjectProperty propertyData(QObject *, int);
+ QVariant serializableVariant(const QVariant &value);
static QList<QmlEngine *> m_engines;
QmlWatcher *m_watch;
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index cfa9469..d2bf4a8 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -281,7 +281,7 @@ void QmlExpressionPrivate::printException(QScriptEngine *scriptEngine)
}
}
-QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope)
+QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined)
{
#ifdef Q_ENABLE_PERFORMANCE_LOG
QFxPerfTimer<QFxPerf::BindValueQt> perfqt;
@@ -318,6 +318,9 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope)
QScriptValue svalue = data->expressionFunction.call();
+ if (isUndefined)
+ *isUndefined = svalue.isUndefined();
+
if (scriptEngine->hasUncaughtException())
printException(scriptEngine);
@@ -355,7 +358,7 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope)
return rv;
}
-QVariant QmlExpressionPrivate::value(QObject *secondaryScope)
+QVariant QmlExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
{
Q_Q(QmlExpression);
@@ -382,7 +385,7 @@ QVariant QmlExpressionPrivate::value(QObject *secondaryScope)
if (data->sse.isValid()) {
rv = evalSSE();
} else {
- rv = evalQtScript(secondaryScope);
+ rv = evalQtScript(secondaryScope, isUndefined);
}
ep->currentExpression = lastCurrentExpression;
@@ -406,11 +409,14 @@ QVariant QmlExpressionPrivate::value(QObject *secondaryScope)
/*!
Returns the value of the expression, or an invalid QVariant if the
expression is invalid or has an error.
+
+ \a isUndefined is set to true if the expression resulted in an
+ undefined value.
*/
-QVariant QmlExpression::value()
+QVariant QmlExpression::value(bool *isUndefined)
{
Q_D(QmlExpression);
- return d->value();
+ return d->value(0, isUndefined);
}
/*!
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index 73682f1..96694d6 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -83,7 +83,7 @@ public:
QObject *scopeObject() const;
public Q_SLOTS:
- QVariant value();
+ QVariant value(bool *isUndefined = 0);
Q_SIGNALS:
virtual void valueChanged();
diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h
index d9bb27b..3ec8d1c 100644
--- a/src/declarative/qml/qmlexpression_p.h
+++ b/src/declarative/qml/qmlexpression_p.h
@@ -140,9 +140,9 @@ public:
QmlExpressionData *data;
- QVariant value(QObject *secondaryScope = 0);
+ QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
QVariant evalSSE();
- QVariant evalQtScript(QObject *secondaryScope);
+ QVariant evalQtScript(QObject *secondaryScope, bool *isUndefined = 0);
void updateGuards(const QPODVector<QmlEnginePrivate::CapturedProperty> &properties);
void clearGuards();
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 5265d42..dc18b05 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -119,6 +119,7 @@ public:
StoreSignal, /* storeSignal */
StoreScript, /* storeScript */
+ StoreScriptString, /* storeScriptString */
//
// Unresolved single assignment
@@ -245,6 +246,11 @@ public:
int value;
} storeString;
struct {
+ int propertyIndex;
+ int value;
+ int scope;
+ } storeScriptString;
+ struct {
int value;
int fileName;
int lineNumber;
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index bae263a..f9e3c50 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -80,6 +80,9 @@ QmlParser::Object::~Object()
prop->release();
foreach(Property *prop, valueTypeProperties)
prop->release();
+ typedef QPair<Property *, int> PropPair;
+ foreach(const PropPair &prop, scriptStringProperties)
+ prop.first->release();
foreach(const DynamicProperty &prop, dynamicProperties)
if (prop.defaultValue) prop.defaultValue->release();
foreach(Object *obj, scriptBlockObjects)
@@ -142,6 +145,13 @@ void QmlParser::Object::addValueTypeProperty(Property *p)
valueTypeProperties << p;
}
+void QmlParser::Object::addScriptStringProperty(Property *p, int stack)
+{
+ p->addref();
+ scriptStringProperties << qMakePair(p, stack);
+}
+
+
Property *QmlParser::Object::getProperty(const QByteArray &name, bool create)
{
if (!properties.contains(name)) {
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 88d7d77..f0867ea 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -160,11 +160,13 @@ namespace QmlParser
void addAttachedProperty(Property *);
void addGroupedProperty(Property *);
void addValueTypeProperty(Property *);
+ void addScriptStringProperty(Property *, int = 0);
QList<Property *> valueProperties;
QList<Property *> signalProperties;
QList<Property *> attachedProperties;
QList<Property *> groupedProperties;
QList<Property *> valueTypeProperties;
+ QList<QPair<Property *, int> > scriptStringProperties;
// Script blocks that were nested under this object
QStringList scriptBlocks;
diff --git a/src/declarative/qml/qmlscriptstring.cpp b/src/declarative/qml/qmlscriptstring.cpp
new file mode 100644
index 0000000..8a6afcc
--- /dev/null
+++ b/src/declarative/qml/qmlscriptstring.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlscriptstring.h"
+
+QT_BEGIN_NAMESPACE
+
+class QmlScriptStringPrivate : public QSharedData
+{
+public:
+ QmlScriptStringPrivate() : context(0), scope(0) {}
+
+ QmlContext *context;
+ QObject *scope;
+ QString script;
+};
+
+/*!
+\class QmlScriptString
+\brief The QmlScriptString class encapsulates a script and its context.
+
+The QmlScriptString is used by properties that want to accept a script "assignment" from QML.
+
+Normally, the following code would result in a binding being established for the \c script
+property. If the property had a type of QmlScriptString, the script - \e {print(1921)} - itself
+would be passed to the property and it could choose how to handle it.
+
+\code
+MyType {
+ script: print(1921)
+}
+\endcode
+*/
+
+/*!
+Construct an empty instance.
+*/
+QmlScriptString::QmlScriptString()
+: d(new QmlScriptStringPrivate)
+{
+}
+
+/*!
+Copy \a other.
+*/
+QmlScriptString::QmlScriptString(const QmlScriptString &other)
+: d(other.d)
+{
+}
+
+/*!
+\internal
+*/
+QmlScriptString::~QmlScriptString()
+{
+}
+
+/*!
+Assign \a other to this.
+*/
+QmlScriptString &QmlScriptString::operator=(const QmlScriptString &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+Return the context for the script.
+*/
+QmlContext *QmlScriptString::context() const
+{
+ return d->context;
+}
+
+/*!
+Sets the \a context for the script.
+*/
+void QmlScriptString::setContext(QmlContext *context)
+{
+ d->context = context;
+}
+
+/*!
+Returns the scope object for the script.
+*/
+QObject *QmlScriptString::scopeObject() const
+{
+ return d->scope;
+}
+
+/*!
+Sets the scope \a object for the script.
+*/
+void QmlScriptString::setScopeObject(QObject *object)
+{
+ d->scope = object;
+}
+
+/*!
+Returns the script text.
+*/
+QString QmlScriptString::script() const
+{
+ return d->script;
+}
+
+/*!
+Sets the \a script text.
+*/
+void QmlScriptString::setScript(const QString &script)
+{
+ d->script = script;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qmlscriptstring.h b/src/declarative/qml/qmlscriptstring.h
new file mode 100644
index 0000000..c6067ce
--- /dev/null
+++ b/src/declarative/qml/qmlscriptstring.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSCRIPTSTRING_H
+#define QMLSCRIPTSTRING_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QObject;
+class QmlContext;
+class QmlScriptStringPrivate;
+class Q_DECLARATIVE_EXPORT QmlScriptString
+{
+public:
+ QmlScriptString();
+ QmlScriptString(const QmlScriptString &);
+ ~QmlScriptString();
+
+ QmlScriptString &operator=(const QmlScriptString &);
+
+ QmlContext *context() const;
+ void setContext(QmlContext *);
+
+ QObject *scopeObject() const;
+ void setScopeObject(QObject *);
+
+ QString script() const;
+ void setScript(const QString &);
+
+private:
+ QSharedDataPointer<QmlScriptStringPrivate> d;
+};
+
+Q_DECLARE_METATYPE(QmlScriptString);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLSCRIPTSTRING_H
+
diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp
index 4a5983d..9e39ffc 100644
--- a/src/declarative/qml/qmlsqldatabase.cpp
+++ b/src/declarative/qml/qmlsqldatabase.cpp
@@ -340,7 +340,7 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *
QString basename = QmlEnginePrivate::get(engine)->offlineStoragePath + QLatin1String("/Databases/");
QDir().mkpath(basename);
basename += dbid;
- database.setDatabaseName(basename+QLatin1String(".sqllite"));
+ database.setDatabaseName(basename+QLatin1String(".sqlite"));
QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat);
ini.setValue(QLatin1String("Name"), dbname);
ini.setValue(QLatin1String("Version"), dbversion);
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 1f3903d..7f673a2 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -67,6 +67,7 @@
#include <private/qmlbinding_p.h>
#include <private/qmlcontext_p.h>
#include <private/qmlbindingoptimizations_p.h>
+#include <QtDeclarative/qmlscriptstring.h>
QT_BEGIN_NAMESPACE
@@ -552,6 +553,21 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
}
break;
+ case QmlInstruction::StoreScriptString:
+ {
+ QObject *target = stack.top();
+ QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope);
+ QmlScriptString ss;
+ ss.setContext(ctxt);
+ ss.setScopeObject(scope);
+ ss.setScript(primitives.at(instr.storeScriptString.value));
+
+ void *a[] = { &ss, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeScriptString.propertyIndex, a);
+ }
+ break;
+
case QmlInstruction::BeginObject:
{
QObject *target = stack.top();
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index e5acc51..62a2a6b 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -55,7 +55,7 @@ QmlVMEMetaObject::QmlVMEMetaObject(QObject *obj,
const QMetaObject *other,
const QmlVMEMetaData *meta,
QmlRefCount *rc)
-: object(obj), ref(rc), metaData(meta), parent(0)
+: object(obj), ref(rc), ctxt(qmlContext(obj)), metaData(meta), parent(0)
{
if (ref)
ref->addref();
@@ -251,7 +251,6 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
(const QChar *)(((const char*)metaData) + data->bodyOffset);
QString code = QString::fromRawData(body, data->bodyLength);
- QmlContext *ctxt = qmlContext(object);
if (0 == (metaData->methodData() + id)->parameterCount) {
QmlExpression expr(ctxt, code, object);
diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h
index d376f4c..de46853 100644
--- a/src/declarative/qml/qmlvmemetaobject_p.h
+++ b/src/declarative/qml/qmlvmemetaobject_p.h
@@ -112,6 +112,7 @@ protected:
private:
QObject *object;
QmlRefCount *ref;
+ QGuard<QmlContext> ctxt;
const QmlVMEMetaData *metaData;
int propOffset;