From c7d38a49bb0c6ea928ce2a54116816ed49dbcfb7 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 27 Nov 2009 14:26:29 +1000 Subject: Doc --- doc/src/declarative/globalobject.qdoc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) 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 -- cgit v0.12 From 696b55195f1ad40a077683dbc533c73baf1536ee Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 27 Nov 2009 15:10:43 +1000 Subject: Handle more HTML non-errors --- src/declarative/qml/qmlxmlhttprequest.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) 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(); -- cgit v0.12 From f9aa040505c5c679bed4181e462fb4d2b9216fa6 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 27 Nov 2009 10:40:08 +0100 Subject: Fix use of XmlHttpRequest in examples --- demos/declarative/samegame/content/samegame.js | 1 + demos/declarative/twitter/content/HomeTitleBar.qml | 1 + examples/declarative/tutorials/samegame/samegame4/content/samegame.js | 1 + 3 files changed, 3 insertions(+) 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/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."); -- cgit v0.12 From d406a899943c6d56d921bc290a009415a3c4eba5 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Sun, 29 Nov 2009 20:46:00 +1000 Subject: Support array-literal Script::source values --- src/declarative/qml/qmlcompiler.cpp | 54 ++++++++++++++-------- src/declarative/qml/qmlcompiler_p.h | 1 + src/declarative/qml/qmlcontext.cpp | 15 +++--- src/declarative/qml/qmlcontext_p.h | 3 +- src/declarative/qml/qmlinstruction.cpp | 2 +- src/declarative/qml/qmlinstruction_p.h | 2 - src/declarative/qml/qmlparser.cpp | 54 ++++++++++++++++++++++ src/declarative/qml/qmlparser_p.h | 11 +++-- src/declarative/qml/qmlscriptparser.cpp | 8 ++-- src/declarative/qml/qmlvme.cpp | 7 +-- .../qmlecmascript/data/externalScript.1.qml | 11 +++++ .../qmlecmascript/data/externalScript.2.js | 8 ++++ .../qmlecmascript/data/externalScript.2.qml | 11 +++++ .../qmlecmascript/data/externalScript.3.qml | 13 ++++++ .../qmlecmascript/data/externalScript.4.qml | 15 ++++++ .../qmlecmascript/data/externalScript.js | 6 +++ .../qmlecmascript/tst_qmlecmascript.cpp | 48 +++++++++++++++++++ 17 files changed, 227 insertions(+), 42 deletions(-) create mode 100644 tests/auto/declarative/qmlecmascript/data/externalScript.1.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/externalScript.2.js create mode 100644 tests/auto/declarative/qmlecmascript/data/externalScript.2.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/externalScript.3.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/externalScript.4.qml create mode 100644 tests/auto/declarative/qmlecmascript/data/externalScript.js 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 programs; QList propertyCaches; QList contextCaches; + QList 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 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/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 #include +#include "parser/qmljsast_p.h" +#include "parser/qmljsengine_p.h" #include 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(n); + if (!array) + return false; + + AST::ElementList *elements = array->elements; + + while (elements) { + + if (!AST::cast(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(n); + if (!array) + return rv; + + AST::ElementList *elements = array->elements; + while (elements) { + + AST::StringLiteral *string = AST::cast(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 > scriptStringProperties; // Script blocks that were nested under this object - QStringList scriptBlocks; - QStringList scriptBlocksFile; - QList scriptBlocksLineNumber; + struct ScriptBlock { + QStringList codes; + QStringList files; + QList lineNumbers; + }; + QList 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(scriptBinding->statement)) { - AST::StringLiteral *string = AST::cast(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 &stack, QmlContext *ctxt, const QList &intData = comp->intData; const QList &floatData = comp->floatData; const QList &propertyCaches = comp->propertyCaches; - + const QList &scripts = comp->scripts; QmlEnginePrivate::SimpleList bindValues; QmlEnginePrivate::SimpleList parserStatus; @@ -224,7 +224,6 @@ QObject *QmlVME::run(QStack &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 &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/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" -- cgit v0.12 From dc59b792119241988cdfe9f31d3aea55dcd5e8fe Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 30 Nov 2009 09:48:13 +1000 Subject: Fix tutorial3. Task-number: QTBUG-6306 --- examples/declarative/tutorials/helloworld/tutorial3.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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] -- cgit v0.12 From 1f8e66b71bc641a9e29f3b3157de2d393d911f23 Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 30 Nov 2009 09:53:03 +1000 Subject: Fix and test ListModel UTF8 reading. --- src/declarative/util/qmllistmodel.cpp | 2 +- tests/auto/declarative/qmllistmodel/tst_qmllistmodel.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) 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/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(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("script"); -- cgit v0.12 From 37cd2eb354e62bf8c3eba0b5edaebe082bf8b3ac Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 30 Nov 2009 09:53:25 +1000 Subject: atob and btoa functions (as per JS window functions) --- src/declarative/qml/qmlengine.cpp | 22 ++++++++++++++++++++++ src/declarative/qml/qmlengine_p.h | 2 ++ 2 files changed, 24 insertions(+) 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; } -- cgit v0.12 From 15145a3b6d675c268b6262d11d390eaf9fc25fee Mon Sep 17 00:00:00 2001 From: Warwick Allison Date: Mon, 30 Nov 2009 09:54:27 +1000 Subject: Some UTF8 --- examples/declarative/listview/dummydata/MyPetsModel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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" -- cgit v0.12 From 68e3cab8a8183a5a88e5be092471a05692e05afe Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 30 Nov 2009 11:29:39 +1000 Subject: Support disabling a Behavior. --- src/declarative/util/qmlbehavior.cpp | 34 ++++++++++++++++++++-- src/declarative/util/qmlbehavior_p.h | 7 +++++ tests/auto/declarative/behaviors/data/disabled.qml | 27 +++++++++++++++++ tests/auto/declarative/behaviors/tst_behaviors.cpp | 15 ++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/behaviors/data/disabled.qml 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/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("MyBehavior"))->animation())->duration(), 200); } +void tst_behaviors::disabled() +{ + QmlEngine engine; + QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/disabled.qml")); + QmlGraphicsRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + QCOMPARE(rect->findChild("MyBehavior")->enabled(), false); + + rect->setState("moved"); + qreal x = qobject_cast(rect->findChild("MyRect"))->x(); + QCOMPARE(x, qreal(200)); //should change immediately + +} + QTEST_MAIN(tst_behaviors) #include "tst_behaviors.moc" -- cgit v0.12