summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-11-30 05:52:09 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-11-30 05:52:09 (GMT)
commitc4cd2138ea46f9e7990bd732b63d7322f21a2f38 (patch)
tree0a7409383632a29b95ea48087be6935b6b494139
parent541c254ce91ea7dea01081f0b093b902527c3476 (diff)
parent68e3cab8a8183a5a88e5be092471a05692e05afe (diff)
downloadQt-c4cd2138ea46f9e7990bd732b63d7322f21a2f38.zip
Qt-c4cd2138ea46f9e7990bd732b63d7322f21a2f38.tar.gz
Qt-c4cd2138ea46f9e7990bd732b63d7322f21a2f38.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
-rwxr-xr-xdemos/declarative/samegame/content/samegame.js1
-rw-r--r--demos/declarative/twitter/content/HomeTitleBar.qml1
-rw-r--r--doc/src/declarative/globalobject.qdoc10
-rw-r--r--examples/declarative/listview/dummydata/MyPetsModel.qml2
-rw-r--r--examples/declarative/tutorials/helloworld/tutorial3.qml2
-rwxr-xr-xexamples/declarative/tutorials/samegame/samegame4/content/samegame.js1
-rw-r--r--src/declarative/qml/qmlcompiler.cpp54
-rw-r--r--src/declarative/qml/qmlcompiler_p.h1
-rw-r--r--src/declarative/qml/qmlcontext.cpp15
-rw-r--r--src/declarative/qml/qmlcontext_p.h3
-rw-r--r--src/declarative/qml/qmlengine.cpp22
-rw-r--r--src/declarative/qml/qmlengine_p.h2
-rw-r--r--src/declarative/qml/qmlinstruction.cpp2
-rw-r--r--src/declarative/qml/qmlinstruction_p.h2
-rw-r--r--src/declarative/qml/qmlparser.cpp54
-rw-r--r--src/declarative/qml/qmlparser_p.h11
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp8
-rw-r--r--src/declarative/qml/qmlvme.cpp7
-rw-r--r--src/declarative/qml/qmlxmlhttprequest.cpp14
-rw-r--r--src/declarative/util/qmlbehavior.cpp34
-rw-r--r--src/declarative/util/qmlbehavior_p.h7
-rw-r--r--src/declarative/util/qmllistmodel.cpp2
-rw-r--r--tests/auto/declarative/behaviors/data/disabled.qml27
-rw-r--r--tests/auto/declarative/behaviors/tst_behaviors.cpp15
-rw-r--r--tests/auto/declarative/qmlecmascript/data/externalScript.1.qml11
-rw-r--r--tests/auto/declarative/qmlecmascript/data/externalScript.2.js8
-rw-r--r--tests/auto/declarative/qmlecmascript/data/externalScript.2.qml11
-rw-r--r--tests/auto/declarative/qmlecmascript/data/externalScript.3.qml13
-rw-r--r--tests/auto/declarative/qmlecmascript/data/externalScript.4.qml15
-rw-r--r--tests/auto/declarative/qmlecmascript/data/externalScript.js6
-rw-r--r--tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp48
-rw-r--r--tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp14
32 files changed, 360 insertions, 63 deletions
diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js
index 3598c26..8651c84 100755
--- a/demos/declarative/samegame/content/samegame.js
+++ b/demos/declarative/samegame/content/samegame.js
@@ -235,6 +235,7 @@ function sendHighScore(name) {
var postData = "name="+name+"&score="+gameCanvas.score
+"&gridSize="+maxX+"x"+maxY +"&time="+Math.floor(timer/1000);
postman.open("POST", scoresURL, true);
+ postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
postman.onreadystatechange = function() {
if (postman.readyState == postman.DONE) {
dialog.show("Your score has been uploaded.");
diff --git a/demos/declarative/twitter/content/HomeTitleBar.qml b/demos/declarative/twitter/content/HomeTitleBar.qml
index e5bdb85..c48befd 100644
--- a/demos/declarative/twitter/content/HomeTitleBar.qml
+++ b/demos/declarative/twitter/content/HomeTitleBar.qml
@@ -24,6 +24,7 @@ Item {
titleBar.update();
}
}
+ postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
postman.send(postData);
editor.text = ""
diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc
index 3eadec2..2bed1c1 100644
--- a/doc/src/declarative/globalobject.qdoc
+++ b/doc/src/declarative/globalobject.qdoc
@@ -42,17 +42,9 @@
/*!
\page qmlglobalobject.html
\title QML Global Object
-Contains all the properties of the ECMAScript global object, plus:
-\list
-\o Qt
-\o createQmlObject
-\o createComponent
-\o XMLHttpRequest
-\o openDatabase
-\endlist
+Contains all the properties of the ECMAScript global object, plus:
-Contents:
\tableofcontents
\section1 Qt Object
diff --git a/examples/declarative/listview/dummydata/MyPetsModel.qml b/examples/declarative/listview/dummydata/MyPetsModel.qml
index 9a00dca..074fc13 100644
--- a/examples/declarative/listview/dummydata/MyPetsModel.qml
+++ b/examples/declarative/listview/dummydata/MyPetsModel.qml
@@ -29,7 +29,7 @@ ListModel {
size: "Medium"
}
ListElement {
- name: "Whiskers"
+ name: "Schrödinger"
type: "Cat"
age: 2
size: "Medium"
diff --git a/examples/declarative/tutorials/helloworld/tutorial3.qml b/examples/declarative/tutorials/helloworld/tutorial3.qml
index 52c3fe8..0f27f86 100644
--- a/examples/declarative/tutorials/helloworld/tutorial3.qml
+++ b/examples/declarative/tutorials/helloworld/tutorial3.qml
@@ -29,7 +29,7 @@ Rectangle {
from: ""; to: "down"; reversible: true
ParallelAnimation {
NumberAnimation { matchProperties: "y,rotation"; duration: 500; easing: "easeInOutQuad" }
- ColorAnimation { property: "color"; duration: 500 }
+ ColorAnimation { duration: 500 }
}
}
//![3]
diff --git a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
index b833385..2a0d718 100755
--- a/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
+++ b/examples/declarative/tutorials/samegame/samegame4/content/samegame.js
@@ -238,6 +238,7 @@ function sendHighScore(name) {
var postData = "name="+name+"&score="+gameCanvas.score
+"&gridSize="+maxX+"x"+maxY +"&time="+Math.floor(timer/1000);
postman.open("POST", scoresURL, true);
+ postman.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
postman.onreadystatechange = function() {
if (postman.readyState == postman.DONE) {
dialog.show("Your score has been uploaded.");
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 9000339..a4e14b2 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -846,13 +846,13 @@ void QmlCompiler::genObject(QmlParser::Object *obj)
}
// Set any script blocks
- for (int ii = 0; ii < obj->scriptBlocks.count(); ++ii) {
+ for (int ii = 0; ii < obj->scripts.count(); ++ii) {
QmlInstruction script;
script.type = QmlInstruction::StoreScript;
script.line = 0; // ###
- script.storeScript.fileName = output->indexForString(obj->scriptBlocksFile.at(ii));
- script.storeScript.lineNumber = obj->scriptBlocksLineNumber.at(ii);
- script.storeScript.value = output->indexForString(obj->scriptBlocks.at(ii));
+ int idx = output->scripts.count();
+ output->scripts << obj->scripts.at(ii);
+ script.storeScript.value = idx;
output->bytecode << script;
}
@@ -1086,9 +1086,7 @@ bool QmlCompiler::buildComponent(QmlParser::Object *obj,
bool QmlCompiler::buildScript(QmlParser::Object *obj, QmlParser::Object *script)
{
- QString scriptCode;
- QString sourceUrl;
- int lineNumber = 1;
+ Object::ScriptBlock scriptBlock;
if (script->properties.count() == 1 &&
script->properties.begin().key() == QByteArray("source")) {
@@ -1098,22 +1096,37 @@ bool QmlCompiler::buildScript(QmlParser::Object *obj, QmlParser::Object *script)
COMPILE_EXCEPTION(source, qApp->translate("QmlCompiler","Invalid Script block. Specify either the source property or inline script"));
if (source->value || source->values.count() != 1 ||
- source->values.at(0)->object || !source->values.at(0)->value.isString())
+ source->values.at(0)->object || !source->values.at(0)->value.isStringList())
COMPILE_EXCEPTION(source, qApp->translate("QmlCompiler","Invalid Script source value"));
- sourceUrl = output->url.resolved(QUrl(source->values.at(0)->value.asString())).toString();
+ QStringList sources = source->values.at(0)->value.asStringList();
- for (int ii = 0; ii < unit->resources.count(); ++ii) {
- if (unit->resources.at(ii)->url == sourceUrl) {
- scriptCode = QString::fromUtf8(unit->resources.at(ii)->data);
- break;
+ for (int jj = 0; jj < sources.count(); ++jj) {
+ QString sourceUrl = output->url.resolved(QUrl(sources.at(jj))).toString();
+ QString scriptCode;
+ int lineNumber = 1;
+
+ for (int ii = 0; ii < unit->resources.count(); ++ii) {
+ if (unit->resources.at(ii)->url == sourceUrl) {
+ scriptCode = QString::fromUtf8(unit->resources.at(ii)->data);
+ break;
+ }
+ }
+
+ if (!scriptCode.isEmpty()) {
+ scriptBlock.codes.append(scriptCode);
+ scriptBlock.files.append(sourceUrl);
+ scriptBlock.lineNumbers.append(lineNumber);
}
}
} else if (!script->properties.isEmpty()) {
COMPILE_EXCEPTION(*script->properties.begin(), qApp->translate("QmlCompiler","Properties cannot be set on Script block"));
} else if (script->defaultProperty) {
- sourceUrl = output->url.toString();
+
+ QString scriptCode;
+ int lineNumber = 1;
+ QString sourceUrl = output->url.toString();
QmlParser::Location currentLocation;
@@ -1141,14 +1154,17 @@ bool QmlCompiler::buildScript(QmlParser::Object *obj, QmlParser::Object *script)
currentLocation = v->location.end;
currentLocation.column++;
}
- }
- if (!scriptCode.isEmpty()) {
- obj->scriptBlocks.append(scriptCode);
- obj->scriptBlocksFile.append(sourceUrl);
- obj->scriptBlocksLineNumber.append(lineNumber);
+ if (!scriptCode.isEmpty()) {
+ scriptBlock.codes.append(scriptCode);
+ scriptBlock.files.append(sourceUrl);
+ scriptBlock.lineNumbers.append(lineNumber);
+ }
}
+ if (!scriptBlock.codes.isEmpty())
+ obj->scripts << scriptBlock;
+
return true;
}
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 9597753..b54a62a 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -116,6 +116,7 @@ public:
QList<QScriptProgram *> programs;
QList<QmlPropertyCache *> propertyCaches;
QList<QmlIntegerCache *> contextCaches;
+ QList<QmlParser::Object::ScriptBlock> scripts;
void dumpInstructions();
private:
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index 42f467b..38cbcfa 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -59,8 +59,7 @@ QmlContextPrivate::QmlContextPrivate()
{
}
-void QmlContextPrivate::addScript(const QString &script, QObject *scopeObject,
- const QString &fileName, int lineNumber)
+void QmlContextPrivate::addScript(const QmlParser::Object::ScriptBlock &script, QObject *scopeObject)
{
Q_Q(QmlContext);
@@ -76,12 +75,14 @@ void QmlContextPrivate::addScript(const QString &script, QObject *scopeObject,
QScriptValue scope = scriptEngine->newObject();
scriptContext->setActivationObject(scope);
- QScriptValue val = scriptEngine->evaluate(script, fileName, lineNumber);
+ for (int ii = 0; ii < script.codes.count(); ++ii) {
+ scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii));
- if (scriptEngine->hasUncaughtException()) {
- QmlError error;
- QmlExpressionPrivate::exceptionToError(scriptEngine, error);
- qWarning().nospace() << qPrintable(error.toString());
+ if (scriptEngine->hasUncaughtException()) {
+ QmlError error;
+ QmlExpressionPrivate::exceptionToError(scriptEngine, error);
+ qWarning().nospace() << qPrintable(error.toString());
+ }
}
scriptEngine->popContext();
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index a9c25a3..c8d0b2d 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -92,8 +92,7 @@ public:
int highPriorityCount;
QList<QScriptValue> scripts;
- void addScript(const QString &script, QObject *scope,
- const QString &fileName = QString(), int lineNumber = 1);
+ void addScript(const QmlParser::Object::ScriptBlock &, QObject *);
QUrl url;
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 0a00092..aa66c17 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -144,6 +144,8 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
qtObject.setProperty(QLatin1String("playSound"), scriptEngine.newFunction(QmlEnginePrivate::playSound, 1));
qtObject.setProperty(QLatin1String("openUrlExternally"),scriptEngine.newFunction(desktopOpenUrl, 1));
qtObject.setProperty(QLatin1String("md5"),scriptEngine.newFunction(md5, 1));
+ qtObject.setProperty(QLatin1String("btoa"),scriptEngine.newFunction(btoa, 1));
+ qtObject.setProperty(QLatin1String("atob"),scriptEngine.newFunction(atob, 1));
//firebug/webkit compat
QScriptValue consoleObject = scriptEngine.newObject();
@@ -818,6 +820,26 @@ QScriptValue QmlEnginePrivate::md5(QScriptContext *ctxt, QScriptEngine *)
return QScriptValue(QLatin1String(result.toHex()));
}
+QScriptValue QmlEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *)
+{
+ QByteArray data;
+
+ if (ctxt->argumentCount() >= 1)
+ data = ctxt->argument(0).toString().toUtf8();
+
+ return QScriptValue(QLatin1String(data.toBase64()));
+}
+
+QScriptValue QmlEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *)
+{
+ QByteArray data;
+
+ if (ctxt->argumentCount() >= 1)
+ data = ctxt->argument(0).toString().toUtf8();
+
+ return QScriptValue(QLatin1String(QByteArray::fromBase64(data)));
+}
+
QScriptValue QmlEnginePrivate::consoleLog(QScriptContext *ctxt, QScriptEngine *e)
{
if(ctxt->argumentCount() < 1)
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index c11a399..cabd0ad 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -269,6 +269,8 @@ public:
static QScriptValue playSound(QScriptContext*, QScriptEngine*);
static QScriptValue desktopOpenUrl(QScriptContext*, QScriptEngine*);
static QScriptValue md5(QScriptContext*, QScriptEngine*);
+ static QScriptValue btoa(QScriptContext*, QScriptEngine*);
+ static QScriptValue atob(QScriptContext*, QScriptEngine*);
static QScriptValue consoleLog(QScriptContext*, QScriptEngine*);
static QScriptEngine *getScriptEngine(QmlEngine *e) { return &e->d_func()->scriptEngine; }
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 6bab1c4..65d070c 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -140,7 +140,7 @@ void QmlCompiledData::dump(QmlInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SIGNAL\t\t" << instr->storeSignal.signalIndex << "\t" << instr->storeSignal.value << "\t\t" << primitives.at(instr->storeSignal.value);
break;
case QmlInstruction::StoreScript:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value << "\t" << instr->storeScript.fileName << "\t" << instr->storeScript.lineNumber;
+ qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value;
break;
case QmlInstruction::StoreScriptString:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 50d4b62..a5fc40c 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -252,8 +252,6 @@ public:
} storeScriptString;
struct {
int value;
- int fileName;
- int lineNumber;
} storeScript;
struct {
int propertyIndex;
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index ee69b14..402c93e 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -54,10 +54,13 @@
#include "private/qmetaobjectbuilder_p.h"
#include <private/qmlvmemetaobject_p.h>
#include <private/qmlcompiler_p.h>
+#include "parser/qmljsast_p.h"
+#include "parser/qmljsengine_p.h"
#include <QtDebug>
QT_BEGIN_NAMESPACE
+using namespace QmlJS;
using namespace QmlParser;
QmlParser::Object::Object()
@@ -327,4 +330,55 @@ QmlJS::AST::Node *QmlParser::Variant::asAST() const
return 0;
}
+bool QmlParser::Variant::isStringList() const
+{
+ if (isString())
+ return true;
+
+ if (type() != Script || !n)
+ return false;
+
+ AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
+ if (!array)
+ return false;
+
+ AST::ElementList *elements = array->elements;
+
+ while (elements) {
+
+ if (!AST::cast<AST::StringLiteral *>(elements->expression))
+ return false;
+
+ elements = elements->next;
+ }
+
+ return true;
+}
+
+QStringList QmlParser::Variant::asStringList() const
+{
+ QStringList rv;
+ if (isString()) {
+ rv << asString();
+ return rv;
+ }
+
+ AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
+ if (!array)
+ return rv;
+
+ AST::ElementList *elements = array->elements;
+ while (elements) {
+
+ AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression);
+ if (!string)
+ return QStringList();
+ rv.append(string->value->asString());
+
+ elements = elements->next;
+ }
+
+ return rv;
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 2ece51f..73bb498 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -169,9 +169,12 @@ namespace QmlParser
QList<QPair<Property *, int> > scriptStringProperties;
// Script blocks that were nested under this object
- QStringList scriptBlocks;
- QStringList scriptBlocksFile;
- QList<int> scriptBlocksLineNumber;
+ struct ScriptBlock {
+ QStringList codes;
+ QStringList files;
+ QList<int> lineNumbers;
+ };
+ QList<ScriptBlock> scripts;
// The bytes to cast instances by to get to the QmlParserStatus
// interface. -1 indicates the type doesn't support this interface.
@@ -243,12 +246,14 @@ namespace QmlParser
bool isNumber() const { return type() == Number; }
bool isString() const { return type() == String; }
bool isScript() const { return type() == Script; }
+ bool isStringList() const;
bool asBoolean() const;
QString asString() const;
double asNumber() const;
QString asScript() const;
QmlJS::AST::Node *asAST() const;
+ QStringList asStringList() const;
private:
Type t;
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index b622c24..23c050c 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -383,10 +383,12 @@ Object *ProcessAST::defineObjectBinding(AST::UiQualifiedId *qualifiedId,
QString propertyName = asString(scriptBinding->qualifiedId);
if (propertyName == QLatin1String("source")) {
if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(scriptBinding->statement)) {
- AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(stmt->expression);
- if (string) {
+ QmlParser::Variant string = getVariant(stmt->expression);
+ if (string.isStringList()) {
+ QStringList urls = string.asStringList();
// We need to add this as a resource
- _parser->_refUrls << QUrl(string->value->asString());
+ for (int ii = 0; ii < urls.count(); ++ii)
+ _parser->_refUrls << QUrl(urls.at(ii));
}
}
}
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index da09288..f2fb217 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -142,7 +142,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
const QList<int> &intData = comp->intData;
const QList<float> &floatData = comp->floatData;
const QList<QmlPropertyCache *> &propertyCaches = comp->propertyCaches;
-
+ const QList<QmlParser::Object::ScriptBlock> &scripts = comp->scripts;
QmlEnginePrivate::SimpleList<QmlAbstractBinding> bindValues;
QmlEnginePrivate::SimpleList<QmlParserStatus> parserStatus;
@@ -224,7 +224,6 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::SetId:
{
QObject *target = stack.top();
-// ctxt->setContextProperty(primitives.at(instr.setId.value), target);
cp->setIdProperty(instr.setId.index, target);
}
break;
@@ -551,9 +550,7 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
case QmlInstruction::StoreScript:
{
QObject *target = stack.top();
- cp->addScript(primitives.at(instr.storeScript.value), target,
- primitives.at(instr.storeScript.fileName),
- instr.storeScript.lineNumber);
+ cp->addScript(scripts.at(instr.storeScript.value), target);
}
break;
diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp
index 642c6de..216db6e 100644
--- a/src/declarative/qml/qmlxmlhttprequest.cpp
+++ b/src/declarative/qml/qmlxmlhttprequest.cpp
@@ -1208,14 +1208,16 @@ void QmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
m_request = QNetworkRequest();
destroyNetwork();
- if (error != QNetworkReply::ContentAccessDenied &&
- error != QNetworkReply::ContentOperationNotPermittedError &&
- error != QNetworkReply::ContentNotFoundError) {
- m_errorFlag = true;
- } else {
+ if (error == QNetworkReply::ContentAccessDenied ||
+ error == QNetworkReply::ContentOperationNotPermittedError ||
+ error == QNetworkReply::ContentNotFoundError ||
+ error == QNetworkReply::AuthenticationRequiredError ||
+ error == QNetworkReply::ContentReSendError) {
m_state = Loading;
dispatchCallback();
- }
+ } else {
+ m_errorFlag = true;
+ }
m_state = Done;
dispatchCallback();
diff --git a/src/declarative/util/qmlbehavior.cpp b/src/declarative/util/qmlbehavior.cpp
index 711c70d..23d3838 100644
--- a/src/declarative/util/qmlbehavior.cpp
+++ b/src/declarative/util/qmlbehavior.cpp
@@ -55,18 +55,21 @@ class QmlBehaviorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QmlBehavior)
public:
- QmlBehaviorPrivate() : animation(0) {}
+ QmlBehaviorPrivate() : animation(0), enabled(true) {}
QmlMetaProperty property;
QVariant currentValue;
QmlAbstractAnimation *animation;
+ bool enabled;
};
/*!
\qmlclass Behavior QmlBehavior
\brief The Behavior element allows you to specify a default animation for a property change.
- In example below, the rect will use a bounce easing curve over 200 millisecond for any changes to its y property:
+ Behaviors provide one way to specify \l{qmlanimation.html}{animations} in QML.
+
+ In the example below, the rect will use a bounce easing curve over 200 millisecond for any changes to its y property:
\code
Rectangle {
width: 20; height: 20
@@ -80,6 +83,9 @@ public:
}
}
\endcode
+
+ Currently only a single Behavior may be specified for a property;
+ this Behavior can be enabled and disabled via the \l{enabled} property.
*/
@@ -118,10 +124,32 @@ void QmlBehavior::setAnimation(QmlAbstractAnimation *animation)
d->animation->setTarget(d->property);
}
+/*!
+ \qmlproperty bool Behavior::enabled
+ Whether the Behavior will be triggered when the property it is tracking changes.
+
+ By default a Behavior is enabled.
+*/
+
+bool QmlBehavior::enabled() const
+{
+ Q_D(const QmlBehavior);
+ return d->enabled;
+}
+
+void QmlBehavior::setEnabled(bool enabled)
+{
+ Q_D(QmlBehavior);
+ if (d->enabled == enabled)
+ return;
+ d->enabled = enabled;
+ emit enabledChanged();
+}
+
void QmlBehavior::write(const QVariant &value)
{
Q_D(QmlBehavior);
- if (!d->animation) {
+ if (!d->animation || !d->enabled) {
d->property.write(value, QmlMetaProperty::BypassInterceptor | QmlMetaProperty::DontRemoveBinding);
return;
}
diff --git a/src/declarative/util/qmlbehavior_p.h b/src/declarative/util/qmlbehavior_p.h
index b61df32..581a0a8 100644
--- a/src/declarative/util/qmlbehavior_p.h
+++ b/src/declarative/util/qmlbehavior_p.h
@@ -63,6 +63,7 @@ class Q_DECLARATIVE_EXPORT QmlBehavior : public QObject, public QmlPropertyValue
Q_INTERFACES(QmlPropertyValueInterceptor)
Q_CLASSINFO("DefaultProperty", "animation")
Q_PROPERTY(QmlAbstractAnimation *animation READ animation WRITE setAnimation)
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
public:
QmlBehavior(QObject *parent=0);
@@ -73,6 +74,12 @@ public:
QmlAbstractAnimation *animation();
void setAnimation(QmlAbstractAnimation *);
+
+ bool enabled() const;
+ void setEnabled(bool enabled);
+
+Q_SIGNALS:
+ void enabledChanged();
};
QT_END_NAMESPACE
diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp
index 5491fd7..8259dcd 100644
--- a/src/declarative/util/qmllistmodel.cpp
+++ b/src/declarative/util/qmllistmodel.cpp
@@ -851,7 +851,7 @@ void QmlListModelParser::setCustomData(QObject *obj, const QByteArray &d)
case ListInstruction::Value:
{
ModelNode *n = nodes.top();
- n->values.append(QByteArray(data + instr.dataIdx));
+ n->values.append(QString::fromUtf8(QByteArray(data + instr.dataIdx)));
}
break;
diff --git a/tests/auto/declarative/behaviors/data/disabled.qml b/tests/auto/declarative/behaviors/data/disabled.qml
new file mode 100644
index 0000000..e7b8d51
--- /dev/null
+++ b/tests/auto/declarative/behaviors/data/disabled.qml
@@ -0,0 +1,27 @@
+import Qt 4.6
+Rectangle {
+ width: 400
+ height: 400
+ Rectangle {
+ id: rect
+ objectName: "MyRect"
+ width: 100; height: 100; color: "green"
+ x: Behavior {
+ objectName: "MyBehavior";
+ enabled: false
+ NumberAnimation { duration: 200; }
+ }
+ }
+ MouseRegion {
+ id: clicker
+ anchors.fill: parent
+ }
+ states: State {
+ name: "moved"
+ when: clicker.pressed
+ PropertyChanges {
+ target: rect
+ x: 200
+ }
+ }
+}
diff --git a/tests/auto/declarative/behaviors/tst_behaviors.cpp b/tests/auto/declarative/behaviors/tst_behaviors.cpp
index 6343968..e1376ce 100644
--- a/tests/auto/declarative/behaviors/tst_behaviors.cpp
+++ b/tests/auto/declarative/behaviors/tst_behaviors.cpp
@@ -64,6 +64,7 @@ private slots:
void emptyBehavior();
void nonSelectingBehavior();
void reassignedAnimation();
+ void disabled();
};
void tst_behaviors::simpleBehavior()
@@ -243,6 +244,20 @@ void tst_behaviors::reassignedAnimation()
rect->findChild<QmlBehavior*>("MyBehavior"))->animation())->duration(), 200);
}
+void tst_behaviors::disabled()
+{
+ QmlEngine engine;
+ QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/disabled.qml"));
+ QmlGraphicsRectangle *rect = qobject_cast<QmlGraphicsRectangle*>(c.create());
+ QVERIFY(rect);
+ QCOMPARE(rect->findChild<QmlBehavior*>("MyBehavior")->enabled(), false);
+
+ rect->setState("moved");
+ qreal x = qobject_cast<QmlGraphicsRectangle*>(rect->findChild<QmlGraphicsRectangle*>("MyRect"))->x();
+ QCOMPARE(x, qreal(200)); //should change immediately
+
+}
+
QTEST_MAIN(tst_behaviors)
#include "tst_behaviors.moc"
diff --git a/tests/auto/declarative/qmlecmascript/data/externalScript.1.qml b/tests/auto/declarative/qmlecmascript/data/externalScript.1.qml
new file mode 100644
index 0000000..2ac7b6e
--- /dev/null
+++ b/tests/auto/declarative/qmlecmascript/data/externalScript.1.qml
@@ -0,0 +1,11 @@
+import Qt 4.6
+
+QtObject {
+ property int test: external_script_func();
+
+ Script {
+ // Single source as non-array literal
+ source: "externalScript.js"
+ }
+}
+
diff --git a/tests/auto/declarative/qmlecmascript/data/externalScript.2.js b/tests/auto/declarative/qmlecmascript/data/externalScript.2.js
new file mode 100644
index 0000000..78c3a86
--- /dev/null
+++ b/tests/auto/declarative/qmlecmascript/data/externalScript.2.js
@@ -0,0 +1,8 @@
+function external_script_func2() {
+ return a;
+}
+
+function is_a_undefined() {
+ return a == undefined;
+}
+
diff --git a/tests/auto/declarative/qmlecmascript/data/externalScript.2.qml b/tests/auto/declarative/qmlecmascript/data/externalScript.2.qml
new file mode 100644
index 0000000..dec657c
--- /dev/null
+++ b/tests/auto/declarative/qmlecmascript/data/externalScript.2.qml
@@ -0,0 +1,11 @@
+import Qt 4.6
+
+QtObject {
+ property int test: external_script_func();
+
+ Script {
+ // Single source as array
+ source: [ "externalScript.js" ]
+ }
+}
+
diff --git a/tests/auto/declarative/qmlecmascript/data/externalScript.3.qml b/tests/auto/declarative/qmlecmascript/data/externalScript.3.qml
new file mode 100644
index 0000000..d7acf38
--- /dev/null
+++ b/tests/auto/declarative/qmlecmascript/data/externalScript.3.qml
@@ -0,0 +1,13 @@
+import Qt 4.6
+
+QtObject {
+ property int test: external_script_func();
+ property int test2: external_script_func2();
+ property bool test3: is_a_undefined();
+
+ Script {
+ // Multiple script
+ source: [ "externalScript.js", "externalScript.2.js" ]
+ }
+}
+
diff --git a/tests/auto/declarative/qmlecmascript/data/externalScript.4.qml b/tests/auto/declarative/qmlecmascript/data/externalScript.4.qml
new file mode 100644
index 0000000..16211aa
--- /dev/null
+++ b/tests/auto/declarative/qmlecmascript/data/externalScript.4.qml
@@ -0,0 +1,15 @@
+import Qt 4.6
+
+QtObject {
+ property int test: external_script_func();
+ property bool test2: is_a_undefined();
+
+ // Disconnected scripts
+ Script {
+ source: "externalScript.js"
+ }
+
+ Script {
+ source: "externalScript.2.js"
+ }
+}
diff --git a/tests/auto/declarative/qmlecmascript/data/externalScript.js b/tests/auto/declarative/qmlecmascript/data/externalScript.js
new file mode 100644
index 0000000..8928652
--- /dev/null
+++ b/tests/auto/declarative/qmlecmascript/data/externalScript.js
@@ -0,0 +1,6 @@
+var a = 92;
+
+function external_script_func() {
+ return a;
+}
+
diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
index fe3ae6b..fb8bfb3 100644
--- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
+++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp
@@ -108,6 +108,7 @@ private slots:
void exceptionClearsOnReeval();
void transientErrors();
void shutdownErrors();
+ void externalScript();
private:
QmlEngine engine;
@@ -946,6 +947,53 @@ void tst_qmlecmascript::shutdownErrors()
QCOMPARE(transientErrorsMsgCount, 0);
}
+// Check that Script::source property works as expected
+void tst_qmlecmascript::externalScript()
+{
+ {
+ QmlComponent component(&engine, TEST_FILE("externalScript.1.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 92);
+
+ delete object;
+ }
+
+ {
+ QmlComponent component(&engine, TEST_FILE("externalScript.2.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 92);
+
+ delete object;
+ }
+
+ {
+ QmlComponent component(&engine, TEST_FILE("externalScript.3.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 92);
+ QCOMPARE(object->property("test2").toInt(), 92);
+ QCOMPARE(object->property("test3").toBool(), false);
+
+ delete object;
+ }
+
+ {
+ QmlComponent component(&engine, TEST_FILE("externalScript.4.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toInt(), 92);
+ QCOMPARE(object->property("test2").toBool(), true);
+
+ delete object;
+ }
+}
+
QTEST_MAIN(tst_qmlecmascript)
#include "tst_qmlecmascript.moc"
diff --git a/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
index f2ffb7b..c7de5d9 100644
--- a/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
+++ b/tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp
@@ -51,12 +51,26 @@ public:
tst_QmlListModel() {}
private slots:
+ void static_i18n();
void dynamic_data();
void dynamic();
void error_data();
void error();
};
+void tst_QmlListModel::static_i18n()
+{
+ QString expect = QString::fromUtf8("na\303\257ve");
+ QString componentStr = "import Qt 4.6\nListModel { ListElement { prop1: \""+expect+"\" } }";
+ QmlEngine engine;
+ QmlComponent component(&engine, componentStr.toUtf8(), QUrl("file://"));
+ QmlListModel *obj = qobject_cast<QmlListModel*>(component.create());
+ QVERIFY(obj != 0);
+ QString prop = obj->get(0).property(QLatin1String("prop1")).toString();
+ QCOMPARE(prop,expect);
+ delete obj;
+}
+
void tst_QmlListModel::dynamic_data()
{
QTest::addColumn<QString>("script");