From 10b440d4621dc5b6b0380c566458facef2942085 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 2 Sep 2009 10:18:14 +1000 Subject: Rework script binding method --- demos/declarative/samegame/content/samegame.js | 3 + src/declarative/qml/qmlengine.cpp | 183 ++++++++++++++----------- src/declarative/qml/qmlengine_p.h | 21 +++ 3 files changed, 126 insertions(+), 81 deletions(-) diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index f04fb4c..91a436f 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -15,6 +15,7 @@ function index(xIdx,yIdx){ function initBoard() { + var a = new Date; for(i = 0; i, bool> FunctionCache; Q_GLOBAL_STATIC(FunctionCache, functionCache); +QScriptClass::QueryFlags +QmlEnginePrivate::queryContext(const QString &propName, uint *id, + QmlContext *bindContext) +{ + resolveData.safetyCheckId++; + *id = resolveData.safetyCheckId; + resolveData.clear(); + + QScriptClass::QueryFlags rv = 0; + QHash::Iterator contextProperty = + bindContext->d_func()->propertyNames.find(propName); + + if (contextProperty != bindContext->d_func()->propertyNames.end()) { + rv |= QScriptClass::HandlesReadAccess; + + resolveData.context = bindContext; + resolveData.contextIndex = *contextProperty; + + return rv; + } + + for (int ii = 0; !rv && ii < bindContext->d_func()->defaultObjects.count(); ++ii) { + rv = queryObject(propName, id, + bindContext->d_func()->defaultObjects.at(ii)); + } + + return rv; +} + +QScriptValue +QmlEnginePrivate::propertyContext(const QScriptString &name, + QmlContext *bindContext, + uint id) +{ + Q_ASSERT(id == resolveData.safetyCheckId); + + + if (resolveData.context) { + QmlContext *bindContext = resolveData.context; + QmlContextPrivate *contextPrivate = bindContext->d_func(); + int index = resolveData.contextIndex; + + QScriptValue rv; + if (index < contextPrivate->idValueCount) { + rv = scriptEngine.newObject(objectClass, scriptEngine.newVariant(QVariant::fromValue(contextPrivate->idValues[index].data()))); + } else { + QVariant value = contextPrivate->propertyValues.at(index); + if (QmlMetaType::isObject(value.userType())) { + rv = scriptEngine.newObject(objectClass, scriptEngine.newVariant(value)); + } else { + rv = scriptEngine.newVariant(value); + } + } + capturedProperties << QmlEnginePrivate::CapturedProperty(bindContext, -1, index + contextPrivate->notifyIndex); + return rv; + + } else { + + return propertyObject(name, resolveData.object, id); + + } + + return QScriptValue(); +} + +void QmlEnginePrivate::setPropertyContext(const QScriptValue &value, uint id) +{ + // As context properties cannot be written, we can assume that the + // write is a object property write + setPropertyObject(value, id); +} + +void QmlEnginePrivate::setPropertyObject(const QScriptValue &value, uint id) +{ + Q_ASSERT(id == resolveData.safetyCheckId); + Q_Q(QmlEngine); + + resolveData.property.write(QmlScriptClass::toVariant(q, value)); +} + QScriptClass::QueryFlags QmlEnginePrivate::queryObject(const QString &propName, uint *id, QObject *obj) { + resolveData.safetyCheckId++; + *id = resolveData.safetyCheckId; + resolveData.clear(); + QScriptClass::QueryFlags rv = 0; QmlContext *ctxt = QmlEngine::contextForObject(obj); if (!ctxt) ctxt = rootContext; QmlMetaProperty prop(obj, propName, ctxt); + if (prop.type() == QmlMetaProperty::Invalid) { QPair key = qMakePair(obj->metaObject(), propName); @@ -232,12 +317,13 @@ QmlEnginePrivate::queryObject(const QString &propName, } if (isFunction) { - *id = QmlScriptClass::FunctionId; + resolveData.object = obj; + resolveData.isFunction = true; rv |= QScriptClass::HandlesReadAccess; - } + } } else { - *id = QmlScriptClass::PropertyId; - *id |= prop.save(); + resolveData.object = obj; + resolveData.property = prop; rv |= QScriptClass::HandlesReadAccess; if (prop.isWritable()) @@ -257,15 +343,16 @@ Q_DECLARE_METATYPE(QmlValueTypeReference); QScriptValue QmlEnginePrivate::propertyObject(const QScriptString &propName, QObject *obj, uint id) { - if (id == QmlScriptClass::FunctionId) { + Q_ASSERT(id == resolveData.safetyCheckId); + Q_ASSERT(resolveData.object); + + if (resolveData.isFunction) { + // ### Optimize QScriptValue sobj = scriptEngine.newQObject(obj); QScriptValue func = sobj.property(propName); return func; } else { - QmlMetaProperty prop; - prop.restore(id, obj); - if (!prop.isValid()) - return QScriptValue(); + const QmlMetaProperty &prop = resolveData.property; if (prop.needsChangedNotifier()) capturedProperties << CapturedProperty(prop); @@ -856,23 +943,11 @@ QmlContextScriptClass::queryProperty(const QScriptValue &object, Q_UNUSED(flags); QmlContext *bindContext = static_cast(object.data().toQObject()); - QueryFlags rv = 0; QString propName = name.toString(); - *id = InvalidId; - if (bindContext->d_func()->propertyNames.contains(propName)) { - rv |= HandlesReadAccess; - *id = VariantPropertyId; - } - - for (int ii = 0; !rv && ii < bindContext->d_func()->defaultObjects.count(); ++ii) { - rv = QmlEnginePrivate::get(engine)->queryObject(propName, id, bindContext->d_func()->defaultObjects.at(ii)); - if (rv) - *id |= (ii << 24); - } - - return rv; + QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); + return ep->queryContext(propName, id, bindContext); } QScriptValue QmlContextScriptClass::property(const QScriptValue &object, @@ -882,46 +957,8 @@ QScriptValue QmlContextScriptClass::property(const QScriptValue &object, QmlContext *bindContext = static_cast(object.data().toQObject()); - uint basicId = id & QmlScriptClass::ClassIdMask; - - QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); - - switch (basicId) { - case VariantPropertyId: - { - QmlContextPrivate *contextPrivate = bindContext->d_func(); - QString propName = name.toString(); - int index = contextPrivate->propertyNames.value(propName); - - QScriptValue rv; - if (index < contextPrivate->idValueCount) { - rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(QVariant::fromValue(contextPrivate->idValues[index].data()))); - } else { - QVariant value = contextPrivate->propertyValues.at(index); - if (QmlMetaType::isObject(value.userType())) { - rv = scriptEngine->newObject(ep->objectClass, scriptEngine->newVariant(value)); - } else { - rv = scriptEngine->newVariant(value); - } - } - ep->capturedProperties << QmlEnginePrivate::CapturedProperty(bindContext, -1, index + bindContext->d_func()->notifyIndex); - return rv; - } - default: - { - int objId = (id & ClassIdSelectorMask) >> 24; - QObject *obj = bindContext->d_func()->defaultObjects.at(objId); - QScriptValue rv = ep->propertyObject(name, obj, - id & ~QmlScriptClass::ClassIdSelectorMask); - if (rv.isValid()) { - return rv; - } - break; - } - } - - return QScriptValue(); + return ep->propertyContext(name, bindContext, id); } void QmlContextScriptClass::setProperty(QScriptValue &object, @@ -931,17 +968,7 @@ void QmlContextScriptClass::setProperty(QScriptValue &object, { Q_UNUSED(name); - QmlContext *bindContext = - static_cast(object.data().toQObject()); - - int objIdx = (id & QmlScriptClass::ClassIdSelectorMask) >> 24; - QObject *obj = bindContext->d_func()->defaultObjects.at(objIdx); - - QmlMetaProperty prop; - prop.restore(id, obj); - - QVariant v = QmlScriptClass::toVariant(engine, value); - prop.write(v); + QmlEnginePrivate::get(engine)->setPropertyContext(value, id); } ///////////////////////////////////////////////////////////// @@ -1119,14 +1146,8 @@ void QmlObjectScriptClass::setProperty(QScriptValue &object, const QScriptValue &value) { Q_UNUSED(name); - - QObject *obj = object.data().toQObject(); - - QmlMetaProperty prop; - prop.restore(id, obj); - - QVariant v = QmlScriptClass::toVariant(engine, value); - prop.write(v); + Q_UNUSED(object); + QmlEnginePrivate::get(engine)->setPropertyObject(value, id); } diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index b595e7c..2c7409b 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -97,10 +97,17 @@ public: void init(); + QScriptClass::QueryFlags queryContext(const QString &name, uint *id, + QmlContext *); + QScriptValue propertyContext(const QScriptString &propName, QmlContext *, + uint id); + void setPropertyContext(const QScriptValue &, uint id); QScriptClass::QueryFlags queryObject(const QString &name, uint *id, QObject *); QScriptValue propertyObject(const QScriptString &propName, QObject *, uint id = 0); + void setPropertyObject(const QScriptValue &, uint id); + struct CapturedProperty { CapturedProperty(QObject *o, int c, int n) @@ -120,6 +127,20 @@ public: QScriptEngineDebugger *debugger; #endif + struct ResolveData { + ResolveData() : safetyCheckId(0) {} + int safetyCheckId; + + void clear() { + object = 0; context = 0; contextIndex = -1; isFunction = false; + } + QObject *object; + QmlContext *context; + + int contextIndex; + bool isFunction; + QmlMetaProperty property; + } resolveData; QmlContextScriptClass *contextClass; QmlObjectScriptClass *objectClass; QmlValueTypeScriptClass *valueTypeClass; -- cgit v0.12 From 1ccca16e3e032cb90d09dc4a161fe35114d8360d Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 12:59:09 +1000 Subject: SameGame high score server support. This commit contains all the functionality for sending high scores to a server, and the server. The server files have been installed at http://qtfx-nokia.trolltech.com.au/samegame for internal testing. --- demos/declarative/samegame/content/samegame.js | 46 +++++++++++++++++++++- demos/declarative/samegame/highscores/README | 1 + .../declarative/samegame/highscores/score_data.xml | 2 + .../samegame/highscores/score_style.xsl | 27 +++++++++++++ demos/declarative/samegame/highscores/scores.php | 34 ++++++++++++++++ 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 demos/declarative/samegame/highscores/README create mode 100755 demos/declarative/samegame/highscores/score_data.xml create mode 100755 demos/declarative/samegame/highscores/score_style.xsl create mode 100755 demos/declarative/samegame/highscores/scores.php diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index f04fb4c..355dbfd 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -6,13 +6,22 @@ var tileSize = 40; var maxIndex = maxX*maxY; var board = new Array(maxIndex); var tileSrc = "content/BoomBlock.qml"; +var scoresURL = "http://qtfx-nokia.trolltech.com.au/samegame/scores.php"; +var timer; var component; //Index function used instead of a 2D array -function index(xIdx,yIdx){ +function index(xIdx,yIdx) { return xIdx + (yIdx * maxX); } +function timeStr(msecs) { + var secs = Math.floor(msecs/1000); + var m = Math.floor(secs/60); + var ret = "" + m + "m " + (secs%60) + "s"; + return ret; +} + function initBoard() { for(i = 0; i1000000Alan the Tester0x00 +6213Alan12x1751 diff --git a/demos/declarative/samegame/highscores/score_style.xsl b/demos/declarative/samegame/highscores/score_style.xsl new file mode 100755 index 0000000..7dcf07e --- /dev/null +++ b/demos/declarative/samegame/highscores/score_style.xsl @@ -0,0 +1,27 @@ + + + + + SameGame High Scores + +

SameGame High Scores

+ + + + + + + + + + + + + + + +
NameScoreGrid SizeTime, s
+ + +
+
diff --git a/demos/declarative/samegame/highscores/scores.php b/demos/declarative/samegame/highscores/scores.php new file mode 100755 index 0000000..3cceb2d --- /dev/null +++ b/demos/declarative/samegame/highscores/scores.php @@ -0,0 +1,34 @@ +"; + echo "SameGame High Scores"; + if($score > 0){#Sending in a new high score + $name = $_POST["name"]; + $grid = $_POST["gridSize"]; + $time = $_POST["time"]; + if($name == "") + $name = "Anonymous"; + //if($grid != "10x10"){ + //Need a standard, so as to reject others? + //} + $file = fopen("score_data.xml", "a"); #It's XML. Happy? + $ret = fwrite($file, "". $score . "" + . $name . "" . $grid . "" + . $time . "\n"); + echo "Your score has been recorded. Thanks for playing!"; + if($ret == False) + echo "
There was an error though, so don't expect to see that score again."; + }else{#Read high score list + #Now uses XSLT to display. So just print the file. With XML cruft added. + #Note that firefox at least won't apply the XSLT on a php file. So redirecting + $file = fopen("scores.xml", "w"); + $ret = fwrite($file, '' . "\n" + . '' . "\n" + . "\n" . file_get_contents("score_data.xml") . "\n"); + if($ret == False) + echo "There was an internal error. Sorry."; + else + echo ''; + } + echo ""; +?> -- cgit v0.12 From c67b9e5e9925d422dca0c5243f91c3e08fe90304 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 13:25:52 +1000 Subject: SameGame now asks for a name and saves your score. Included a rewriting of the Dialog item to be half-decent. Watch http://qtfx-nokia.trolltech.com.au/samegame/scores.php on the internal network for highscores! --- demos/declarative/samegame/SameGame.qml | 13 +++++++++++++ demos/declarative/samegame/content/Dialog.qml | 18 ++++++++++++------ demos/declarative/samegame/content/samegame.js | 12 +++++------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/demos/declarative/samegame/SameGame.qml b/demos/declarative/samegame/SameGame.qml index 0da5679..877c1cc 100644 --- a/demos/declarative/samegame/SameGame.qml +++ b/demos/declarative/samegame/SameGame.qml @@ -34,6 +34,19 @@ Rectangle { } Dialog { id: dialog; anchors.centerIn: parent; z: 21 } + Dialog { + id: scoreName; anchors.centerIn: parent; z: 22; + TextInput { + id: Editor + onAccepted: { + if(scoreName.opacity==1&&Editor.text!="") + sendHighScore(Editor.text); + scoreName.forceClose(); + } + anchors.verticalCenter: parent.verticalCenter + x:160; width: 200; height:20; focus: true + } + } Rectangle { id: ToolBar diff --git a/demos/declarative/samegame/content/Dialog.qml b/demos/declarative/samegame/content/Dialog.qml index 72c7900..401d211 100644 --- a/demos/declarative/samegame/content/Dialog.qml +++ b/demos/declarative/samegame/content/Dialog.qml @@ -2,14 +2,20 @@ import Qt 4.6 Rectangle { id: page + function forceClose() { + page.closed(); + page.opacity = 0; + } + function show(txt) { + MyText.text = txt; + page.opacity = 1; + } + signal closed(); color: "white"; border.width: 1; width: MyText.width + 20; height: 60; - property string text: "Hello World!" opacity: 0 opacity: Behavior { - SequentialAnimation { - NumberAnimation {property: "opacity"; from: 0; duration: 1500 } - NumberAnimation {property: "opacity"; to: 0; duration: 1500 } - } + NumberAnimation { duration: 1000 } } - Text { id: MyText; anchors.centerIn: parent; text: parent.text } + Text { id: MyText; anchors.centerIn: parent; text: "Hello World!" } + MouseRegion { id: mr; anchors.fill: parent; onClicked: forceClose(); } } diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index 355dbfd..d890cd2 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -144,10 +144,10 @@ function victoryCheck() gameCanvas.score += 500; //Checks for game over if(deservesBonus || !(floodMoveCheck(0,maxY-1, -1))){ - dialog.text = "Game Over. Your score is " + gameCanvas.score; - dialog.opacity = 1; + dialog.show("Game Over. Your score is " + gameCanvas.score); timer = new Date() - timer; - //if(scoresURL != "") sendHighScore(name); + if(scoresURL != "") + scoreName.show("Please enter your name: "); } } @@ -233,8 +233,7 @@ function tweetHighScore(twitterName, twitterPass) { postman.open("POST", "http://twitter.com/statuses/update.xml", true, twitterName, twitterPass); postman.onreadystatechange = function() { if (postman.readyState == postman.DONE) { - dialog.text = "Your score has been tweeted for you."; - dialog.opacity = 1; + dialog.show("Your score has been tweeted for you."); } } postman.send(postData); @@ -247,8 +246,7 @@ function sendHighScore(name) { postman.open("POST", scoresURL, true); postman.onreadystatechange = function() { if (postman.readyState == postman.DONE) { - dialog.text = "Your score has been uploaded."; - dialog.opacity = 1; + dialog.show("Your score has been uploaded."); } } postman.send(postData); -- cgit v0.12 From 5477cb3bbc97e4b419c5ea5bbe4f137959b9140d Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 13:29:08 +1000 Subject: Don't need to tweet high scores too --- demos/declarative/samegame/content/samegame.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/demos/declarative/samegame/content/samegame.js b/demos/declarative/samegame/content/samegame.js index d890cd2..9914edb 100755 --- a/demos/declarative/samegame/content/samegame.js +++ b/demos/declarative/samegame/content/samegame.js @@ -222,23 +222,6 @@ function startCreatingBlock(xIdx,yIdx){ return; } -function tweetHighScore(twitterName, twitterPass) { - if(twitterName == '' || twitterPass == '') - return false;//Can't login like that - - var scoreStr = "I just played the QML SameGame, and got " + gameCanvas.score + " points on a " - + maxX + "x" + maxY + " grid. It took me " + timeStr(timer) + "."; - var postData = "status=" + scoreStr; - var postman = new XMLHttpRequest(); - postman.open("POST", "http://twitter.com/statuses/update.xml", true, twitterName, twitterPass); - postman.onreadystatechange = function() { - if (postman.readyState == postman.DONE) { - dialog.show("Your score has been tweeted for you."); - } - } - postman.send(postData); -} - function sendHighScore(name) { var postman = new XMLHttpRequest() var postData = "name="+name+"&score="+gameCanvas.score -- cgit v0.12 From 9e7bd55bde0d614719c67977507b270dc7326f05 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 2 Sep 2009 13:34:07 +1000 Subject: Save object creation line and column number This info is used by the debugger interface, and by the qmlInfo() stream. --- src/declarative/qml/qmldeclarativedata_p.h | 5 +++++ src/declarative/qml/qmlenginedebug.cpp | 11 +++++++++-- src/declarative/qml/qmlinfo.cpp | 16 +++++++++++++++- src/declarative/qml/qmlinstruction_p.h | 1 + src/declarative/qml/qmlvme.cpp | 5 +++++ 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h index 5a51eb7..a316c0c 100644 --- a/src/declarative/qml/qmldeclarativedata_p.h +++ b/src/declarative/qml/qmldeclarativedata_p.h @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE class QmlCompiledData; class QmlAbstractBinding; +class QmlContext; class QmlDeclarativeData : public QDeclarativeData { public: @@ -69,6 +70,10 @@ public: QmlContext *context; QmlAbstractBinding *bindings; + QmlContext *outerContext; // Can't this be found from context? + ushort lineNumber; + ushort columnNumber; + QmlCompiledData *deferredComponent; // Can't this be found from the context? unsigned int deferredIdx; diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp index 0e78cad..321fe74 100644 --- a/src/declarative/qml/qmlenginedebug.cpp +++ b/src/declarative/qml/qmlenginedebug.cpp @@ -181,9 +181,16 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message, QmlEngineDebugServer::QmlObjectData QmlEngineDebugServer::objectData(QObject *object) { + QmlDeclarativeData *ddata = QmlDeclarativeData::get(object); QmlObjectData rv; - rv.lineNumber = -1; - rv.columnNumber = -1; + if (ddata) { + rv.url = ddata->outerContext->baseUrl(); + rv.lineNumber = ddata->lineNumber; + rv.columnNumber = ddata->columnNumber; + } else { + rv.lineNumber = -1; + rv.columnNumber = -1; + } rv.objectName = object->objectName(); rv.objectType = object->metaObject()->className(); diff --git a/src/declarative/qml/qmlinfo.cpp b/src/declarative/qml/qmlinfo.cpp index 65a4298..e47b4ab 100644 --- a/src/declarative/qml/qmlinfo.cpp +++ b/src/declarative/qml/qmlinfo.cpp @@ -40,6 +40,8 @@ ****************************************************************************/ #include "qmlinfo.h" +#include +#include QT_BEGIN_NAMESPACE @@ -80,7 +82,19 @@ QmlInfo::QmlInfo(QObject *object) *this << "QML"; if (object) *this << object->metaObject()->className(); - *this << "(unknown location):"; + QmlDeclarativeData *ddata = QmlDeclarativeData::get(object); + if (ddata) { + QString location = QLatin1String("("); + location += ddata->outerContext->baseUrl().toString(); + location += QLatin1String(":"); + location += QString::number(ddata->lineNumber); + location += QLatin1String(":"); + location += QString::number(ddata->columnNumber); + location += QLatin1String(")"); + *this << location.toLatin1().constData(); + } else { + *this << "(unknown location):"; + } } /*! diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index 8861609a..ede06a2 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -170,6 +170,7 @@ public: struct { int type; int data; + ushort column; } create; struct { int data; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 930e6e4..7907195 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -174,6 +174,11 @@ QObject *QmlVME::run(QStack &stack, QmlContext *ctxt, QmlCompiledData VME_EXCEPTION("Unable to create object of type" << types.at(instr.create.type).className); } + QmlDeclarativeData *ddata = QmlDeclarativeData::get(o); + ddata->outerContext = ctxt; + ddata->lineNumber = instr.line; + ddata->columnNumber = instr.create.column; + if (instr.create.data != -1) { QmlCustomParser *customParser = types.at(instr.create.type).type->customParser(); -- cgit v0.12 From c3af2cb805d1ac5f7a5a944a23dc4c4238f8f530 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 2 Sep 2009 15:02:46 +1000 Subject: Provide some color manipulation functions. These may not be the final location for these, but it allows us to start testing. --- src/declarative/fx/qfxrect.cpp | 61 +-------------------- src/declarative/fx/qfxrect.h | 4 -- src/declarative/fx/qfxrect_p.h | 1 - src/declarative/qml/qmlengine.cpp | 112 ++++++++++++++++++++++++++++++++++++++ src/declarative/qml/qmlengine_p.h | 4 ++ 5 files changed, 118 insertions(+), 64 deletions(-) diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp index f8223f2..fbd7ee8 100644 --- a/src/declarative/fx/qfxrect.cpp +++ b/src/declarative/fx/qfxrect.cpp @@ -328,63 +328,6 @@ void QFxRect::setColor(const QColor &c) update(); } -/*! - \qmlproperty color Rectangle::tintColor - This property holds The color to tint the rectangle. - - This color will be drawn over the rectangle's color when the rectangle is painted. The tint color should usually be mostly transparent, or you will not be able to see the underlying color. The below example provides a slight red tint by having the tint color be pure red which is only 1/16th opaque. - - \qml - Rectangle { x: 0; width: 80; height: 80; color: "lightsteelblue" } - Rectangle { x: 100; width: 80; height: 80; color: "lightsteelblue"; tintColor: "#10FF0000" } - \endqml - \image declarative-rect_tint.png - - This attribute is not intended to be used with a single color over the lifetime of an user interface. It is most useful when a subtle change is intended to be conveyed due to some event; you can then use the tint color to more effectively tune the visible color. -*/ -QColor QFxRect::tintColor() const -{ - Q_D(const QFxRect); - return d->tintColor; -} - -void QFxRect::setTintColor(const QColor &c) -{ - Q_D(QFxRect); - if (d->tintColor == c) - return; - - d->tintColor = c; - update(); -} - -QColor QFxRectPrivate::getColor() -{ - if (tintColor.isValid()) { - int a = tintColor.alpha(); - if (a == 0xFF) - return tintColor; - else if (a == 0x00) - return color; - else { - uint src = tintColor.rgba(); - uint dest = color.rgba(); - - uint res = (((a * (src & 0xFF00FF)) + - ((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF; - res |= (((a * ((src >> 8) & 0xFF00FF)) + - ((0xFF - a) * ((dest >> 8) & 0xFF00FF)))) & 0xFF00FF00; - if ((src & 0xFF000000) == 0xFF000000) - res |= 0xFF000000; - - return QColor::fromRgba(res); - } - } else { - return color; - } -} - - void QFxRect::generateRoundedRect() { Q_D(QFxRect); @@ -443,7 +386,7 @@ void QFxRect::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) bool oldAA = p->testRenderHint(QPainter::Antialiasing); if (d->smooth) p->setRenderHints(QPainter::Antialiasing, true); - p->fillRect(QRectF(0, 0, width(), height()), d->getColor()); + p->fillRect(QRectF(0, 0, width(), height()), d->color); if (d->smooth) p->setRenderHint(QPainter::Antialiasing, oldAA); } @@ -527,7 +470,7 @@ void QFxRect::drawRect(QPainter &p) // Middle if (xMiddles && yMiddles) // XXX paint errors in animation example - //p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->getColor()); + //p.fillRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw, d->color); p.drawPixmap(QRect(xOffset-pw/2, yOffset-pw/2, width() - xSide + pw, height() - ySide + pw), d->rectImage, QRect(d->rectImage.width()/2, d->rectImage.height()/2, 1, 1)); // Middle right diff --git a/src/declarative/fx/qfxrect.h b/src/declarative/fx/qfxrect.h index 359e8fc..439cc65 100644 --- a/src/declarative/fx/qfxrect.h +++ b/src/declarative/fx/qfxrect.h @@ -136,7 +136,6 @@ class Q_DECLARATIVE_EXPORT QFxRect : public QFxItem Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(QColor tintColor READ tintColor WRITE setTintColor) Q_PROPERTY(QFxGradient *gradient READ gradient WRITE setGradient) Q_PROPERTY(QFxPen * border READ border) Q_PROPERTY(qreal radius READ radius WRITE setRadius) @@ -146,9 +145,6 @@ public: QColor color() const; void setColor(const QColor &); - QColor tintColor() const; - void setTintColor(const QColor &); - QFxPen *border(); QFxGradient *gradient() const; diff --git a/src/declarative/fx/qfxrect_p.h b/src/declarative/fx/qfxrect_p.h index 25fa38d..8eb074a 100644 --- a/src/declarative/fx/qfxrect_p.h +++ b/src/declarative/fx/qfxrect_p.h @@ -81,7 +81,6 @@ public: QColor getColor(); QColor color; QFxGradient *gradient; - QColor tintColor; QFxPen *getPen() { if (!pen) { Q_Q(QFxRect); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index d2d0590..0bd3931 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -80,6 +80,7 @@ #include #include #include +#include #include Q_DECLARE_METATYPE(QmlMetaProperty) @@ -121,12 +122,18 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) qt_add_qmlxmlhttprequest(&scriptEngine); + //types qtObject.setProperty(QLatin1String("rgba"), scriptEngine.newFunction(QmlEnginePrivate::rgba, 4)); qtObject.setProperty(QLatin1String("hsla"), scriptEngine.newFunction(QmlEnginePrivate::hsla, 4)); qtObject.setProperty(QLatin1String("rect"), scriptEngine.newFunction(QmlEnginePrivate::rect, 4)); qtObject.setProperty(QLatin1String("point"), scriptEngine.newFunction(QmlEnginePrivate::point, 2)); qtObject.setProperty(QLatin1String("size"), scriptEngine.newFunction(QmlEnginePrivate::size, 2)); qtObject.setProperty(QLatin1String("vector3d"), scriptEngine.newFunction(QmlEnginePrivate::vector, 3)); + + //color helpers + qtObject.setProperty(QLatin1String("lighter"), scriptEngine.newFunction(QmlEnginePrivate::lighter, 1)); + qtObject.setProperty(QLatin1String("darker"), scriptEngine.newFunction(QmlEnginePrivate::darker, 1)); + qtObject.setProperty(QLatin1String("tint"), scriptEngine.newFunction(QmlEnginePrivate::tint, 2)); } QmlEnginePrivate::~QmlEnginePrivate() @@ -809,6 +816,111 @@ QScriptValue QmlEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine) return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h))); } +QScriptValue QmlEnginePrivate::lighter(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 1) + return engine->nullValue(); + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + color = color.lighter(); + return qScriptValueFromValue(engine, qVariantFromValue(color)); +} + +QScriptValue QmlEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 1) + return engine->nullValue(); + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + color = color.darker(); + return qScriptValueFromValue(engine, qVariantFromValue(color)); +} + +/*! + This function allows tinting one color with another. + + The tint color should usually be mostly transparent, or you will not be able to see the underlying color. The below example provides a slight red tint by having the tint color be pure red which is only 1/16th opaque. + + \qml + Rectangle { x: 0; width: 80; height: 80; color: "lightsteelblue" } + Rectangle { x: 100; width: 80; height: 80; color: Qt.tint("lightsteelblue", "#10FF0000") } + \endqml + \image declarative-rect_tint.png + + Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color. +*/ +QScriptValue QmlEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine) +{ + if(ctxt->argumentCount() < 2) + return engine->nullValue(); + //get color + QVariant v = ctxt->argument(0).toVariant(); + QColor color; + if (v.type() == QVariant::Color) + color = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + color = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + + //get tint color + v = ctxt->argument(1).toVariant(); + QColor tintColor; + if (v.type() == QVariant::Color) + tintColor = v.value(); + else if (v.type() == QVariant::String) { + bool ok; + tintColor = QmlStringConverters::colorFromString(v.toString(), &ok); + if (!ok) + return engine->nullValue(); + } else + return engine->nullValue(); + + //tint + QColor finalColor; + int a = tintColor.alpha(); + if (a == 0xFF) + finalColor = tintColor; + else if (a == 0x00) + finalColor = color; + else { + uint src = tintColor.rgba(); + uint dest = color.rgba(); + + uint res = (((a * (src & 0xFF00FF)) + + ((0xFF - a) * (dest & 0xFF00FF))) >> 8) & 0xFF00FF; + res |= (((a * ((src >> 8) & 0xFF00FF)) + + ((0xFF - a) * ((dest >> 8) & 0xFF00FF)))) & 0xFF00FF00; + if ((src & 0xFF000000) == 0xFF000000) + res |= 0xFF000000; + + finalColor = QColor::fromRgba(res); + } + + return qScriptValueFromValue(engine, qVariantFromValue(finalColor)); +} + QmlScriptClass::QmlScriptClass(QmlEngine *bindengine) : QScriptClass(QmlEnginePrivate::getScriptEngine(bindengine)), engine(bindengine) diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index b3c6279..1e251cc 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -223,6 +223,10 @@ public: static QScriptValue size(QScriptContext*, QScriptEngine*); static QScriptValue rect(QScriptContext*, QScriptEngine*); + static QScriptValue lighter(QScriptContext*, QScriptEngine*); + static QScriptValue darker(QScriptContext*, QScriptEngine*); + static QScriptValue tint(QScriptContext*, QScriptEngine*); + static QScriptEngine *getScriptEngine(QmlEngine *e) { return &e->d_func()->scriptEngine; } static QmlEngine *getEngine(QScriptEngine *e) { return static_cast(e)->p->q_func(); } static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); } -- cgit v0.12 From 5994577c403d8622c535fa5d7fd3fd2d8b364043 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 16:15:35 +1000 Subject: SameGame score XSLT now sorts by score. --- demos/declarative/samegame/highscores/score_style.xsl | 1 + 1 file changed, 1 insertion(+) diff --git a/demos/declarative/samegame/highscores/score_style.xsl b/demos/declarative/samegame/highscores/score_style.xsl index 7dcf07e..670354c 100755 --- a/demos/declarative/samegame/highscores/score_style.xsl +++ b/demos/declarative/samegame/highscores/score_style.xsl @@ -13,6 +13,7 @@ Time, s + -- cgit v0.12 From 8ba41d00ff13c92e09d66321c5598a3855059060 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 16:41:51 +1000 Subject: Slightly better name dialog for SameGame --- demos/declarative/samegame/SameGame.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/demos/declarative/samegame/SameGame.qml b/demos/declarative/samegame/SameGame.qml index 877c1cc..ede4362 100644 --- a/demos/declarative/samegame/SameGame.qml +++ b/demos/declarative/samegame/SameGame.qml @@ -44,7 +44,8 @@ Rectangle { scoreName.forceClose(); } anchors.verticalCenter: parent.verticalCenter - x:160; width: 200; height:20; focus: true + width: 72; focus: true + anchors.right: scoreName.right } } -- cgit v0.12 From 5455a16f49e8d36e604705c14c842c8a4e1b4f1f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 2 Sep 2009 17:00:14 +1000 Subject: Disallow using typenames as ids This is now illegal: import Qt 4.6 Item { id: Item } as is import Qt 4.6 Item { id: Text } --- demos/declarative/flickr/common/ImageDetails.qml | 10 +++++----- demos/declarative/flickr/common/MediaButton.qml | 12 ++++++------ demos/declarative/flickr/common/MediaLineEdit.qml | 10 +++++----- demos/declarative/flickr/common/Star.qml | 4 ++-- demos/declarative/flickr/flickr-desktop.qml | 4 ++-- demos/declarative/flickr/mobile/Button.qml | 10 +++++----- demos/declarative/flickr/mobile/ImageDetails.qml | 4 ++-- examples/declarative/flowview/flowview.qml | 10 +++++----- src/declarative/qml/qmlcompiler.cpp | 7 +++++-- tests/auto/declarative/qmlparser/invalidID.6.errors.txt | 1 + tests/auto/declarative/qmlparser/invalidID.6.qml | 5 +++++ tests/auto/declarative/qmlparser/tst_qmlparser.cpp | 1 + 12 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 tests/auto/declarative/qmlparser/invalidID.6.errors.txt create mode 100644 tests/auto/declarative/qmlparser/invalidID.6.qml diff --git a/demos/declarative/flickr/common/ImageDetails.qml b/demos/declarative/flickr/common/ImageDetails.qml index dcd44eb..6b42910 100644 --- a/demos/declarative/flickr/common/ImageDetails.qml +++ b/demos/declarative/flickr/common/ImageDetails.qml @@ -19,7 +19,7 @@ Flipable { signal closed transform: Rotation { - id: Rotation + id: DetailsRotation origin.x: Container.width / 2; axis.y: 1; axis.z: 0 } @@ -48,7 +48,7 @@ Flipable { LikeOMeter { x: 40; y: 250; rating: Container.rating } - Flickable { id: Flickable; x: 220; width: 480; height: 210; y: 130; clip: true + Flickable { id: FlickSurface; x: 220; width: 480; height: 210; y: 130; clip: true viewportWidth: 480; viewportHeight: DescriptionText.height WebView { id: DescriptionText; width: parent.width @@ -70,8 +70,8 @@ Flipable { anchors.left: TagsLabel.right; anchors.top: Date.bottom; elide: "ElideRight"; text: Container.photoTags } - ScrollBar { id: ScrollBar; x: 720; y: Flickable.y; width: 7; height: Flickable.height; opacity: 0; - flickableArea: Flickable; clip: true } + ScrollBar { id: ScrollBar; x: 720; y: FlickSurface.y; width: 7; height: FlickSurface.height; opacity: 0; + flickableArea: FlickSurface; clip: true } } back: Item { @@ -136,7 +136,7 @@ Flipable { states: [ State { name: "Back" - PropertyChanges { target: Rotation; angle: 180 } + PropertyChanges { target: DetailsRotation; angle: 180 } } ] diff --git a/demos/declarative/flickr/common/MediaButton.qml b/demos/declarative/flickr/common/MediaButton.qml index 0ffd596..e1e09e8 100644 --- a/demos/declarative/flickr/common/MediaButton.qml +++ b/demos/declarative/flickr/common/MediaButton.qml @@ -8,7 +8,7 @@ Item { property string text Image { - id: Image + id: ButtonImage source: "pics/button.png" } Image { @@ -17,21 +17,21 @@ Item { opacity: 0 } MouseRegion { - id: MouseRegion - anchors.fill: Image + id: MyMouseRegion + anchors.fill: ButtonImage onClicked: { Container.clicked(); } } Text { font.bold: true color: "white" - anchors.centerIn: Image + anchors.centerIn: ButtonImage text: Container.text } - width: Image.width + width: ButtonImage.width states: [ State { name: "Pressed" - when: MouseRegion.pressed == true + when: MyMouseRegion.pressed == true PropertyChanges { target: Pressed opacity: 1 diff --git a/demos/declarative/flickr/common/MediaLineEdit.qml b/demos/declarative/flickr/common/MediaLineEdit.qml index 500a402..eab0b95 100644 --- a/demos/declarative/flickr/common/MediaLineEdit.qml +++ b/demos/declarative/flickr/common/MediaLineEdit.qml @@ -7,7 +7,7 @@ Item { property string text width: Math.max(94,Label.width + Editor.width + 20) - height: Image.height + height: ButtonImage.height states: [ State { @@ -48,7 +48,7 @@ Item { BorderImage { - id: Image + id: ButtonImage source: "pics/button.sci" anchors.left: Container.left anchors.right: Container.right @@ -63,12 +63,12 @@ Item { } MouseRegion { - id: MouseRegion - anchors.fill: Image + id: MyMouseRegion + anchors.fill: ButtonImage onClicked: { Container.state = Container.state=="Edit" ? "" : "Edit" } states: [ State { - when: MouseRegion.pressed == true + when: MyMouseRegion.pressed == true PropertyChanges { target: Pressed opacity: 1 diff --git a/demos/declarative/flickr/common/Star.qml b/demos/declarative/flickr/common/Star.qml index 006e86ad..c4d1bec 100644 --- a/demos/declarative/flickr/common/Star.qml +++ b/demos/declarative/flickr/common/Star.qml @@ -11,7 +11,7 @@ Item { signal clicked Image { - id: Image + id: StarImage source: "pics/ghns_star.png" x: 6 y: 7 @@ -27,7 +27,7 @@ Item { name: "on" when: Container.on == true PropertyChanges { - target: Image + target: StarImage opacity: 1 scale: 1 x: 1 diff --git a/demos/declarative/flickr/flickr-desktop.qml b/demos/declarative/flickr/flickr-desktop.qml index fca7e31..6a4efd9 100644 --- a/demos/declarative/flickr/flickr-desktop.qml +++ b/demos/declarative/flickr/flickr-desktop.qml @@ -15,7 +15,7 @@ Item { scale: Wrapper.PathView.scale; z: Wrapper.PathView.z transform: Rotation { - id: Rotation; origin.x: Wrapper.width/2; origin.y: Wrapper.height/2 + id: ItemRotation; origin.x: Wrapper.width/2; origin.y: Wrapper.height/2 axis.y: 1; axis.z: 0; angle: Wrapper.PathView.angle } @@ -67,7 +67,7 @@ Item { PropertyChanges { target: ImageDetails; z: 2 } ParentChange { target: Wrapper; parent: ImageDetails.frontContainer } PropertyChanges { target: Wrapper; x: 45; y: 35; scale: 1; z: 1000 } - PropertyChanges { target: Rotation; angle: 0 } + PropertyChanges { target: ItemRotation; angle: 0 } PropertyChanges { target: Shadows; opacity: 0 } PropertyChanges { target: ImageDetails; y: 20 } PropertyChanges { target: PhotoGridView; y: "-480" } diff --git a/demos/declarative/flickr/mobile/Button.qml b/demos/declarative/flickr/mobile/Button.qml index 3a0b42e..6887240 100644 --- a/demos/declarative/flickr/mobile/Button.qml +++ b/demos/declarative/flickr/mobile/Button.qml @@ -8,7 +8,7 @@ Item { property string text BorderImage { - id: Image + id: ButtonImage source: "images/toolbutton.sci" width: Container.width; height: Container.height } @@ -19,19 +19,19 @@ Item { width: Container.width; height: Container.height } MouseRegion { - id: MouseRegion - anchors.fill: Image + id: MyMouseRegion + anchors.fill: ButtonImage onClicked: { Container.clicked(); } } Text { color: "white" - anchors.centerIn: Image; font.bold: true + anchors.centerIn: ButtonImage; font.bold: true text: Container.text; style: "Raised"; styleColor: "black" } states: [ State { name: "Pressed" - when: MouseRegion.pressed == true + when: MyMouseRegion.pressed == true PropertyChanges { target: Pressed opacity: 1 diff --git a/demos/declarative/flickr/mobile/ImageDetails.qml b/demos/declarative/flickr/mobile/ImageDetails.qml index 5f16a24..617fe40 100644 --- a/demos/declarative/flickr/mobile/ImageDetails.qml +++ b/demos/declarative/flickr/mobile/ImageDetails.qml @@ -19,7 +19,7 @@ Flipable { signal closed transform: Rotation { - id: Rotation + id: ItemRotation origin.x: Container.width / 2; axis.y: 1; axis.z: 0 } @@ -116,7 +116,7 @@ Flipable { states: State { name: "Back" - PropertyChanges { target: Rotation; angle: 180 } + PropertyChanges { target: ItemRotation; angle: 180 } } transitions: Transition { diff --git a/examples/declarative/flowview/flowview.qml b/examples/declarative/flowview/flowview.qml index ca31bcc..1ab8e92 100644 --- a/examples/declarative/flowview/flowview.qml +++ b/examples/declarative/flowview/flowview.qml @@ -15,7 +15,7 @@ Rectangle { states: State { name: "rotated" - PropertyChanges { target: ListView; z: 2 } + PropertyChanges { target: MyListView; z: 2 } PropertyChanges { target: TopBar; y: -30 } PropertyChanges { target: BottomBar; y: 480 } PropertyChanges { target: LeftBar; x: 0 } @@ -44,7 +44,7 @@ Rectangle { } delegate: Package { Item { id: List; Package.name: "list"; width:120; height: 400; } - Item { id: Grid; Package.name: "grid"; width:400; height: 120; } + Item { id: GridItem; Package.name: "grid"; width:400; height: 120; } Loader { id: MyContent; width:400; height: 120; source: weblet } StateGroup { @@ -58,7 +58,7 @@ Rectangle { State { name: "InGrid" when: MyPhone.state != "rotated" - ParentChange { target: MyContent; parent: Grid } + ParentChange { target: MyContent; parent: GridItem } PropertyChanges { target: MyContent; x: 0; y: 0; } } ] @@ -75,7 +75,7 @@ Rectangle { from: "*"; to: "InList" SequentialAnimation { ParentAction{} - PauseAnimation { duration: 50 * (Grid.FlowView.row * 2 + Grid.FlowView.column) } + PauseAnimation { duration: 50 * (GridItem.FlowView.row * 2 + GridItem.FlowView.column) } NumberAnimation { properties: "x,y,rotation"; easing: "easeInOutQuad" } } } @@ -87,7 +87,7 @@ Rectangle { Item { FlowView { - id: ListView + id: MyListView vertical: true y: 40 x: 40 diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 070add7..c0f7bfd 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1452,10 +1452,13 @@ bool QmlCompiler::buildIdProperty(QmlParser::Property *prop, if (!isValidId(val)) COMPILE_EXCEPTION(prop, val << "is not a valid object id"); - // We disallow id's that conflict with import prefixes + // We disallow id's that conflict with import prefixes and types QmlEnginePrivate::ImportedNamespace *ns = 0; + QmlType *type = 0; QmlEnginePrivate::get(engine)->resolveType(unit->imports, val.toUtf8(), - 0, 0, 0, 0, &ns); + &type, 0, 0, 0, &ns); + if (type) + COMPILE_EXCEPTION(idValue, "id conflicts with type name"); if (ns) COMPILE_EXCEPTION(idValue, "id conflicts with namespace prefix"); diff --git a/tests/auto/declarative/qmlparser/invalidID.6.errors.txt b/tests/auto/declarative/qmlparser/invalidID.6.errors.txt new file mode 100644 index 0000000..861e3d7 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.6.errors.txt @@ -0,0 +1 @@ +3:9:id conflicts with type name diff --git a/tests/auto/declarative/qmlparser/invalidID.6.qml b/tests/auto/declarative/qmlparser/invalidID.6.qml new file mode 100644 index 0000000..ea34007 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.6.qml @@ -0,0 +1,5 @@ +import Test 1.0 +MyQmlObject { + id: MyQmlObject +} + diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp index e953717..4f2a1f5 100644 --- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -143,6 +143,7 @@ void tst_qmlparser::errors_data() QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false; QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false; QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false; + QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false; QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false; -- cgit v0.12 From 9260c597cc45e15943ad851f934ebb6e5ac1010a Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Wed, 2 Sep 2009 17:41:47 +1000 Subject: Add an assert before we dereference a null pointer Reviewed-by: Aaron Kennedy --- src/declarative/qml/qmlvme.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 7907195..a49cbd3 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -175,6 +175,7 @@ QObject *QmlVME::run(QStack &stack, QmlContext *ctxt, QmlCompiledData } QmlDeclarativeData *ddata = QmlDeclarativeData::get(o); + Q_ASSERT(ddata); ddata->outerContext = ctxt; ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; -- cgit v0.12 From ed417f18023f1bbd0636c9724b8f79e08c77d51a Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 3 Sep 2009 09:06:46 +1000 Subject: Add basic autotests for state handling. --- .../auto/declarative/states/data/basicBinding.qml | 12 + .../auto/declarative/states/data/basicBinding2.qml | 12 + .../auto/declarative/states/data/basicBinding3.qml | 13 + .../auto/declarative/states/data/basicBinding4.qml | 17 ++ .../auto/declarative/states/data/basicChanges.qml | 10 + .../auto/declarative/states/data/basicChanges2.qml | 15 ++ .../auto/declarative/states/data/basicChanges3.qml | 15 ++ .../declarative/states/data/basicExtension.qml | 16 ++ .../auto/declarative/states/data/fakeExtension.qml | 16 ++ tests/auto/declarative/states/states.pro | 6 + tests/auto/declarative/states/tst_states.cpp | 267 +++++++++++++++++++++ 11 files changed, 399 insertions(+) create mode 100644 tests/auto/declarative/states/data/basicBinding.qml create mode 100644 tests/auto/declarative/states/data/basicBinding2.qml create mode 100644 tests/auto/declarative/states/data/basicBinding3.qml create mode 100644 tests/auto/declarative/states/data/basicBinding4.qml create mode 100644 tests/auto/declarative/states/data/basicChanges.qml create mode 100644 tests/auto/declarative/states/data/basicChanges2.qml create mode 100644 tests/auto/declarative/states/data/basicChanges3.qml create mode 100644 tests/auto/declarative/states/data/basicExtension.qml create mode 100644 tests/auto/declarative/states/data/fakeExtension.qml create mode 100644 tests/auto/declarative/states/states.pro create mode 100644 tests/auto/declarative/states/tst_states.cpp diff --git a/tests/auto/declarative/states/data/basicBinding.qml b/tests/auto/declarative/states/data/basicBinding.qml new file mode 100644 index 0000000..930a6b2 --- /dev/null +++ b/tests/auto/declarative/states/data/basicBinding.qml @@ -0,0 +1,12 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + + property color sourceColor: "blue" + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: MyRectangle; color: sourceColor } + } +} diff --git a/tests/auto/declarative/states/data/basicBinding2.qml b/tests/auto/declarative/states/data/basicBinding2.qml new file mode 100644 index 0000000..6bfaf5a --- /dev/null +++ b/tests/auto/declarative/states/data/basicBinding2.qml @@ -0,0 +1,12 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + + property color sourceColor: "red" + width: 100; height: 100 + color: sourceColor + states: State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue" } + } +} \ No newline at end of file diff --git a/tests/auto/declarative/states/data/basicBinding3.qml b/tests/auto/declarative/states/data/basicBinding3.qml new file mode 100644 index 0000000..344bfae --- /dev/null +++ b/tests/auto/declarative/states/data/basicBinding3.qml @@ -0,0 +1,13 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + + property color sourceColor: "red" + property color sourceColor2: "blue" + width: 100; height: 100 + color: sourceColor + states: State { + name: "blue" + PropertyChanges { target: MyRectangle; color: sourceColor2 } + } +} \ No newline at end of file diff --git a/tests/auto/declarative/states/data/basicBinding4.qml b/tests/auto/declarative/states/data/basicBinding4.qml new file mode 100644 index 0000000..f0b72bd --- /dev/null +++ b/tests/auto/declarative/states/data/basicBinding4.qml @@ -0,0 +1,17 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + + property color sourceColor: "blue" + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: MyRectangle; color: sourceColor } + }, + State { + name: "green" + PropertyChanges { target: MyRectangle; color: "green" } + }] +} diff --git a/tests/auto/declarative/states/data/basicChanges.qml b/tests/auto/declarative/states/data/basicChanges.qml new file mode 100644 index 0000000..8d560c6 --- /dev/null +++ b/tests/auto/declarative/states/data/basicChanges.qml @@ -0,0 +1,10 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue" } + } +} \ No newline at end of file diff --git a/tests/auto/declarative/states/data/basicChanges2.qml b/tests/auto/declarative/states/data/basicChanges2.qml new file mode 100644 index 0000000..0f8783a --- /dev/null +++ b/tests/auto/declarative/states/data/basicChanges2.qml @@ -0,0 +1,15 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue" } + }, + State { + name: "green" + PropertyChanges { target: MyRectangle; color: "green" } + }] +} \ No newline at end of file diff --git a/tests/auto/declarative/states/data/basicChanges3.qml b/tests/auto/declarative/states/data/basicChanges3.qml new file mode 100644 index 0000000..2a5ca5d --- /dev/null +++ b/tests/auto/declarative/states/data/basicChanges3.qml @@ -0,0 +1,15 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue" } + }, + State { + name: "bordered" + PropertyChanges { target: MyRectangle; border.width: 2 } + }] +} diff --git a/tests/auto/declarative/states/data/basicExtension.qml b/tests/auto/declarative/states/data/basicExtension.qml new file mode 100644 index 0000000..230e00b --- /dev/null +++ b/tests/auto/declarative/states/data/basicExtension.qml @@ -0,0 +1,16 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue" } + }, + State { + name: "bordered" + extend: "blue" + PropertyChanges { target: MyRectangle; border.width: 2 } + }] +} \ No newline at end of file diff --git a/tests/auto/declarative/states/data/fakeExtension.qml b/tests/auto/declarative/states/data/fakeExtension.qml new file mode 100644 index 0000000..3d85c4f --- /dev/null +++ b/tests/auto/declarative/states/data/fakeExtension.qml @@ -0,0 +1,16 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: MyRectangle; color: "blue" } + }, + State { + name: "green" + extend: "blue" + PropertyChanges { target: MyRectangle; color: "green" } + }] +} \ No newline at end of file diff --git a/tests/auto/declarative/states/states.pro b/tests/auto/declarative/states/states.pro new file mode 100644 index 0000000..0474ea5 --- /dev/null +++ b/tests/auto/declarative/states/states.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_states.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/states/tst_states.cpp b/tests/auto/declarative/states/tst_states.cpp new file mode 100644 index 0000000..3a61bd6 --- /dev/null +++ b/tests/auto/declarative/states/tst_states.cpp @@ -0,0 +1,267 @@ +#include +#include +#include +#include + +class tst_states : public QObject +{ + Q_OBJECT +public: + tst_states() {} + +private slots: + void basicChanges(); + void basicExtension(); + void basicBinding(); +}; + +void tst_states::basicChanges() +{ + QmlEngine engine; + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + } + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicChanges2.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + } + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicChanges3.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1); + + rect->setState("bordered"); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),2); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1); + //### we should be checking that this is an implicit rather than explicit 1 (which currently fails) + + rect->setState("bordered"); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),2); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1); + + } +} + +void tst_states::basicExtension() +{ + QmlEngine engine; + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicExtension.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1); + + rect->setState("bordered"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),2); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1); + + rect->setState("bordered"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),2); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1); + } + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/fakeExtension.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + } +} + +void tst_states::basicBinding() +{ + QmlEngine engine; + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicBinding.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("green")); + QCOMPARE(rect->color(),QColor("green")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("yellow")); + } + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicBinding2.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("green")); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("green")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("yellow")); + } + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicBinding3.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor", QColor("green")); + QCOMPARE(rect->color(),QColor("green")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("red")); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor2", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor2", QColor("green")); + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + } + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/basicBinding4.qml"); + QFxRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + + rect->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + rect->setProperty("sourceColor", QColor("purple")); + QCOMPARE(rect->color(),QColor("green")); + + rect->setState("blue"); + QCOMPARE(rect->color(),QColor("purple")); + + rect->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rect->setState(""); + QCOMPARE(rect->color(),QColor("red")); + } +} + +QTEST_MAIN(tst_states) + +#include "tst_states.moc" -- cgit v0.12 From 48b47f9d242f76e944986df08a16c083bce47bef Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 3 Sep 2009 09:32:38 +1000 Subject: Make it easier to test examples with EGL. Currently -graphicssystem opengl is not very reliable with EGL, so we've added a -opengl option to qmlviewer which sets the viewport of the view to a QGLWidget and allows for GL testing. --- tools/qmlviewer/main.cpp | 5 +++++ tools/qmlviewer/qmlviewer.cpp | 18 ++++++++++++++++++ tools/qmlviewer/qmlviewer.h | 1 + tools/qmlviewer/qmlviewer.pro | 5 +++++ 4 files changed, 29 insertions(+) diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp index a4ed054..87d1232 100644 --- a/tools/qmlviewer/main.cpp +++ b/tools/qmlviewer/main.cpp @@ -41,6 +41,7 @@ void usage() qWarning(" -netcache ......................... set disk cache to size bytes"); qWarning(" -translation ........... set the language to run in"); qWarning(" -L ........................... prepend to the library search path"); + qWarning(" -opengl .................................. use a QGLWidget for the viewport"); qWarning(" "); qWarning(" Press F1 for interactive help"); exit(1); @@ -79,6 +80,7 @@ int main(int argc, char ** argv) bool devkeys = false; int cache = 0; QString translationFile; + bool useGL = false; for (int i = 1; i < argc; ++i) { QString arg = argv[i]; @@ -114,6 +116,8 @@ int main(int argc, char ** argv) usage(); translationFile = argv[i + 1]; ++i; + } else if (arg == "-opengl") { + useGL = true; } else if (arg == "-L") { libraries << QString(argv[++i]); } else if (arg[0] != '-') { @@ -130,6 +134,7 @@ int main(int argc, char ** argv) } QmlViewer viewer(0, frameless ? Qt::FramelessWindowHint : Qt::Widget); + viewer.setUseGL(useGL); foreach (QString lib, libraries) viewer.addLibraryPath(lib); viewer.setNetworkCacheSize(cache); diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index 272ebcb..3ae9a97 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -45,6 +45,10 @@ #include #include "proxysettings.h" +#ifdef GL_SUPPORTED +#include +#endif + QT_BEGIN_NAMESPACE class PreviewDeviceSkin : public DeviceSkin @@ -1003,6 +1007,20 @@ void QmlViewer::setNetworkCacheSize(int size) } } +void QmlViewer::setUseGL(bool useGL) +{ +#ifdef GL_SUPPORTED + if (useGL) { + QGLFormat format = QGLFormat::defaultFormat(); + format.setSampleBuffers(false); + + QGLWidget *glWidget = new QGLWidget(format); + glWidget->setAutoFillBackground(false); + canvas->setViewport(glWidget); + } +#endif +} + QT_END_NAMESPACE #include "qmlviewer.moc" diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h index c03c09f..e85acfa 100644 --- a/tools/qmlviewer/qmlviewer.h +++ b/tools/qmlviewer/qmlviewer.h @@ -43,6 +43,7 @@ public: void setDeviceKeys(bool); void setNetworkCacheSize(int size); void addLibraryPath(const QString& lib); + void setUseGL(bool use); QStringList builtinSkins() const; diff --git a/tools/qmlviewer/qmlviewer.pro b/tools/qmlviewer/qmlviewer.pro index bcf361e..77cae97 100644 --- a/tools/qmlviewer/qmlviewer.pro +++ b/tools/qmlviewer/qmlviewer.pro @@ -7,6 +7,11 @@ QT += declarative \ network \ sql +contains(QT_CONFIG, opengl) { + QT += opengl + DEFINES += GL_SUPPORTED +} + # Input HEADERS += qmlviewer.h \ proxysettings.h -- cgit v0.12 From b9c834048d6dc6e04567c1c73212ecb1b9c96664 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 3 Sep 2009 10:14:54 +1000 Subject: Add QML enum support Enums are accessed as . Currently this is highly unoptimal - enum assignments are not detected in the compiler, nor are they cached in the script engine. --- src/declarative/qml/qmlcompiler.cpp | 2 + src/declarative/qml/qmlcompiler_p.h | 1 + src/declarative/qml/qmlcomponent.cpp | 1 + src/declarative/qml/qmlcontext_p.h | 2 + src/declarative/qml/qmlengine.cpp | 135 ++++++++++++++++++--- src/declarative/qml/qmlengine_p.h | 33 ++++- tests/auto/declarative/qmlbindengine/enums.1.qml | 20 +++ tests/auto/declarative/qmlbindengine/testtypes.h | 19 +++ .../qmlbindengine/tst_qmlbindengine.cpp | 19 +++ 9 files changed, 213 insertions(+), 19 deletions(-) create mode 100644 tests/auto/declarative/qmlbindengine/enums.1.qml diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index c0f7bfd..6519dff 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -642,6 +642,8 @@ void QmlCompiler::compileTree(Object *tree) def.type = QmlInstruction::SetDefault; output->bytecode << def; + output->imports = unit->imports; + if (tree->metatype) static_cast(output->root) = *tree->metaObject(); else diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index c42c2d9..83c415c 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -76,6 +76,7 @@ public: QByteArray name; QUrl url; + QmlEnginePrivate::Imports imports; struct TypeReference { diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index c844a32..e897cce 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -488,6 +488,7 @@ QObject *QmlComponent::beginCreate(QmlContext *context) static_cast(QObjectPrivate::get(context)); QmlContext *ctxt = new QmlContext(context, 0, true); static_cast(ctxt->d_func())->url = d->cc->url; + static_cast(ctxt->d_func())->imports = d->cc->imports; QmlVME vme; QObject *rv = vme.run(ctxt, d->cc, d->start, d->count); diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index 84d990c..b305408 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -60,6 +60,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -91,6 +92,7 @@ public: QScriptValueList scopeChain; QUrl url; + QmlEnginePrivate::Imports imports; void init(); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 0d6e281..3d8b2c4 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -181,6 +181,7 @@ void QmlEnginePrivate::init() contextClass = new QmlContextScriptClass(q); objectClass = new QmlObjectScriptClass(q); valueTypeClass = new QmlValueTypeScriptClass(q); + typeNameClass = new QmlTypeNameScriptClass(q); rootContext = new QmlContext(q,true); #ifdef QT_SCRIPTTOOLS_LIB if (qmlDebugger()){ @@ -211,10 +212,22 @@ QmlEnginePrivate::CapturedProperty::CapturedProperty(const QmlMetaProperty &p) { } -//////////////////////////////////////////////////////////////////// -typedef QHash, bool> FunctionCache; -Q_GLOBAL_STATIC(FunctionCache, functionCache); +struct QmlTypeNameBridge +{ + QObject *object; + QmlType *type; + QmlEnginePrivate::ImportedNamespace *ns; +}; +Q_DECLARE_METATYPE(QmlTypeNameBridge); + +struct QmlValueTypeReference { + QmlValueType *type; + QGuard object; + int property; +}; +Q_DECLARE_METATYPE(QmlValueTypeReference); +//////////////////////////////////////////////////////////////////// QScriptClass::QueryFlags QmlEnginePrivate::queryContext(const QString &propName, uint *id, QmlContext *bindContext) @@ -223,19 +236,32 @@ QmlEnginePrivate::queryContext(const QString &propName, uint *id, *id = resolveData.safetyCheckId; resolveData.clear(); - QScriptClass::QueryFlags rv = 0; QHash::Iterator contextProperty = bindContext->d_func()->propertyNames.find(propName); if (contextProperty != bindContext->d_func()->propertyNames.end()) { - rv |= QScriptClass::HandlesReadAccess; resolveData.context = bindContext; resolveData.contextIndex = *contextProperty; - return rv; + return QScriptClass::HandlesReadAccess; } + QmlType *type = 0; ImportedNamespace *ns = 0; + if (currentExpression && bindContext == currentExpression->context() && + propName.at(0).isUpper() && resolveType(bindContext->d_func()->imports, propName.toUtf8(), &type, 0, 0, 0, &ns)) { + + if (type || ns) { + // Must be either an attached property, or an enum + resolveData.object = bindContext->d_func()->defaultObjects.first(); + resolveData.type = type; + resolveData.ns = ns; + return QScriptClass::HandlesReadAccess; + } + + } + + QScriptClass::QueryFlags rv = 0; for (int ii = 0; !rv && ii < bindContext->d_func()->defaultObjects.count(); ++ii) { rv = queryObject(propName, id, bindContext->d_func()->defaultObjects.at(ii)); @@ -252,7 +278,14 @@ QmlEnginePrivate::propertyContext(const QScriptString &name, Q_ASSERT(id == resolveData.safetyCheckId); - if (resolveData.context) { + if (resolveData.type || resolveData.ns) { + QmlTypeNameBridge tnb = { + resolveData.object, + resolveData.type, + resolveData.ns + }; + return scriptEngine.newObject(typeNameClass, scriptEngine.newVariant(qVariantFromValue(tnb))); + } else if (resolveData.context) { QmlContext *bindContext = resolveData.context; QmlContextPrivate *contextPrivate = bindContext->d_func(); int index = resolveData.contextIndex; @@ -314,13 +347,13 @@ QmlEnginePrivate::queryObject(const QString &propName, QPair key = qMakePair(obj->metaObject(), propName); bool isFunction = false; - if (functionCache()->contains(key)) { - isFunction = functionCache()->value(key); + if (functionCache.contains(key)) { + isFunction = functionCache.value(key); } else { QScriptValue sobj = scriptEngine.newQObject(obj); QScriptValue func = sobj.property(propName); isFunction = func.isFunction(); - functionCache()->insert(key, isFunction); + functionCache.insert(key, isFunction); } if (isFunction) { @@ -340,13 +373,6 @@ QmlEnginePrivate::queryObject(const QString &propName, return rv; } -struct QmlValueTypeReference { - QmlValueType *type; - QGuard object; - int property; -}; -Q_DECLARE_METATYPE(QmlValueTypeReference); - QScriptValue QmlEnginePrivate::propertyObject(const QScriptString &propName, QObject *obj, uint id) { @@ -1084,6 +1110,81 @@ void QmlContextScriptClass::setProperty(QScriptValue &object, } ///////////////////////////////////////////////////////////// +QmlTypeNameScriptClass::QmlTypeNameScriptClass(QmlEngine *engine) +: QmlScriptClass(engine), object(0), type(0) +{ +} + +QmlTypeNameScriptClass::~QmlTypeNameScriptClass() +{ +} + +QmlTypeNameScriptClass::QueryFlags +QmlTypeNameScriptClass::queryProperty(const QScriptValue &scriptObject, + const QScriptString &name, + QueryFlags flags, uint *id) +{ + QmlTypeNameBridge bridge = + qvariant_cast(scriptObject.data().toVariant()); + + object = 0; + type = 0; + QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); + + if (bridge.ns) { + QmlType *type = 0; + ep->resolveTypeInNamespace(bridge.ns, name.toString().toUtf8(), + &type, 0, 0, 0); + if (type) { + object = bridge.object; + this->type = type; + return HandlesReadAccess; + } else { + return 0; + } + + } else { + Q_ASSERT(bridge.type); + QString strName = name.toString(); + if (strName.at(0).isUpper()) { + // Must be an enum + // ### Optimize + const char *enumName = strName.toUtf8().constData(); + const QMetaObject *metaObject = bridge.type->baseMetaObject(); + for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { + QMetaEnum e = metaObject->enumerator(ii); + int value = e.keyToValue(enumName); + if (value != -1) { + enumValue = value; + return HandlesReadAccess; + } + } + return 0; + } else { + // Must be an attached property + this->object = qmlAttachedPropertiesObjectById(bridge.type->index(), bridge.object); + Q_ASSERT(this->object); + return ep->queryObject(strName, id, this->object); + } + } +} + +QScriptValue QmlTypeNameScriptClass::property(const QScriptValue &, + const QScriptString &propName, + uint id) +{ + QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); + if (type) { + QmlTypeNameBridge tnb = { object, type, 0 }; + return ep->scriptEngine.newObject(ep->typeNameClass, ep->scriptEngine.newVariant(qVariantFromValue(tnb))); + } else if (object) { + return ep->propertyObject(propName, object, id); + } else { + return QScriptValue(enumValue); + } +} + +///////////////////////////////////////////////////////////// QmlValueTypeScriptClass::QmlValueTypeScriptClass(QmlEngine *bindEngine) : QmlScriptClass(bindEngine) { diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 451276d..f492ccb 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -82,6 +82,7 @@ class QmlExpression; class QmlBasicScriptNodeCache; class QmlContextScriptClass; class QmlObjectScriptClass; +class QmlTypeNameScriptClass; class QmlValueTypeScriptClass; class QScriptEngineDebugger; class QNetworkReply; @@ -127,16 +128,22 @@ public: QScriptEngineDebugger *debugger; #endif + struct ImportedNamespace; struct ResolveData { ResolveData() : safetyCheckId(0) {} int safetyCheckId; void clear() { - object = 0; context = 0; contextIndex = -1; isFunction = false; + object = 0; context = 0; + type = 0; ns = 0; + contextIndex = -1; isFunction = false; } QObject *object; QmlContext *context; + QmlType *type; + QmlEnginePrivate::ImportedNamespace *ns; + int contextIndex; bool isFunction; QmlMetaProperty property; @@ -144,6 +151,7 @@ public: QmlContextScriptClass *contextClass; QmlObjectScriptClass *objectClass; QmlValueTypeScriptClass *valueTypeClass; + QmlTypeNameScriptClass *typeNameClass; // Used by DOM Core 3 API QScriptClass *nodeListClass; QScriptClass *namedNodeMapClass; @@ -199,6 +207,9 @@ public: } QmlValueTypeFactory valueTypes; + // ### Fixme + typedef QHash, bool> FunctionCache; + FunctionCache functionCache; QHash propertyCache; static QmlMetaObjectCache *cache(QmlEnginePrivate *priv, QObject *obj) { if (!priv || !obj || QObjectPrivate::get(obj)->metaObject) return 0; @@ -219,7 +230,6 @@ public: QmlImportsPrivate *d; }; - struct ImportedNamespace; bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const; bool resolveType(const Imports&, const QByteArray& type, QmlType** type_return, QUrl* url_return, @@ -313,6 +323,25 @@ public: const QScriptValue &value); }; +class QmlTypeNameScriptClass : public QmlScriptClass +{ +public: + QmlTypeNameScriptClass(QmlEngine *); + ~QmlTypeNameScriptClass(); + + virtual QueryFlags queryProperty(const QScriptValue &object, + const QScriptString &name, + QueryFlags flags, uint *id); + virtual QScriptValue property(const QScriptValue &object, + const QScriptString &name, + uint id); + +private: + QObject *object; + QmlType *type; + quint32 enumValue; +}; + class QmlValueTypeScriptClass : public QmlScriptClass { public: diff --git a/tests/auto/declarative/qmlbindengine/enums.1.qml b/tests/auto/declarative/qmlbindengine/enums.1.qml new file mode 100644 index 0000000..6351823 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/enums.1.qml @@ -0,0 +1,20 @@ +import Qt.test 1.0 +import Qt.test 1.0 as Namespace + +MyQmlObject { + // Enums from non-namespaced type + property int a: MyQmlObject.EnumValue1 + property int b: MyQmlObject.EnumValue2 + property int c: MyQmlObject.EnumValue3 + property int d: MyQmlObject.EnumValue4 + + // Enums from namespaced type + property int e: Namespace.MyQmlObject.EnumValue1 + property int f: Namespace.MyQmlObject.EnumValue2 + property int g: Namespace.MyQmlObject.EnumValue3 + property int h: Namespace.MyQmlObject.EnumValue4 + + // Test that enums don't mask attached properties + property int i: MyQmlObject.value + property int j: Namespace.MyQmlObject.value +} diff --git a/tests/auto/declarative/qmlbindengine/testtypes.h b/tests/auto/declarative/qmlbindengine/testtypes.h index f5b309e..f27c0b0 100644 --- a/tests/auto/declarative/qmlbindengine/testtypes.h +++ b/tests/auto/declarative/qmlbindengine/testtypes.h @@ -5,9 +5,21 @@ #include #include +class MyQmlAttachedObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value CONSTANT) +public: + MyQmlAttachedObject(QObject *parent) : QObject(parent) {} + + int value() const { return 19; } +}; + class MyQmlObject : public QObject { Q_OBJECT + Q_ENUMS(MyEnum) + Q_ENUMS(MyEnum2) Q_PROPERTY(bool trueProperty READ trueProperty CONSTANT) Q_PROPERTY(bool falseProperty READ falseProperty CONSTANT) Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringChanged) @@ -15,6 +27,9 @@ class MyQmlObject : public QObject public: MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0) {} + enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 }; + enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 }; + bool trueProperty() const { return true; } bool falseProperty() const { return false; } @@ -39,6 +54,10 @@ public: bool methodIntCalled() const { return m_methodIntCalled; } QString string() const { return m_string; } + + static MyQmlAttachedObject *qmlAttachedProperties(QObject *o) { + return new MyQmlAttachedObject(o); + } signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c); diff --git a/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp b/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp index 01cb54b..80373fe 100644 --- a/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp +++ b/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp @@ -38,6 +38,7 @@ private slots: void objectPropertiesTriggerReeval(); void deferredProperties(); void extensionObjects(); + void enums(); private: QmlEngine engine; @@ -366,6 +367,24 @@ void tst_qmlbindengine::extensionObjects() QCOMPARE(object->baseProperty(), 92); } +void tst_qmlbindengine::enums() +{ + QmlComponent component(&engine, TEST_FILE("enums.1.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("a").toInt(), 0); + QCOMPARE(object->property("b").toInt(), 1); + QCOMPARE(object->property("c").toInt(), 2); + QCOMPARE(object->property("d").toInt(), 3); + QCOMPARE(object->property("e").toInt(), 0); + QCOMPARE(object->property("f").toInt(), 1); + QCOMPARE(object->property("g").toInt(), 2); + QCOMPARE(object->property("h").toInt(), 3); + QCOMPARE(object->property("i").toInt(), 19); + QCOMPARE(object->property("j").toInt(), 19); +} + QTEST_MAIN(tst_qmlbindengine) #include "tst_qmlbindengine.moc" -- cgit v0.12 From 8ac9c707306f0eb8804310f47894d4723e190bce Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 3 Sep 2009 10:27:34 +1000 Subject: Remove dead test --- .../declarative/simplecanvasitem/data/test.qml | 60 ---------------- .../simplecanvasitem/simplecanvasitem.pro | 7 -- .../simplecanvasitem/tst_simplecanvasitem.cpp | 79 ---------------------- 3 files changed, 146 deletions(-) delete mode 100644 tests/auto/declarative/simplecanvasitem/data/test.qml delete mode 100644 tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro delete mode 100644 tests/auto/declarative/simplecanvasitem/tst_simplecanvasitem.cpp diff --git a/tests/auto/declarative/simplecanvasitem/data/test.qml b/tests/auto/declarative/simplecanvasitem/data/test.qml deleted file mode 100644 index 8fbbc2e..0000000 --- a/tests/auto/declarative/simplecanvasitem/data/test.qml +++ /dev/null @@ -1,60 +0,0 @@ -import Qt 4.6 - -Item { - width: 320 - height: 480 - Rect { - color: "blue" - x: 20 - y: 20 - width: 20 - height: 20 - Rect { - color: "black" - x: 20 - y: 20 - width: 10 - height: 10 - } - } - Rect { - color: "red" - x: 40 - y: 20 - width: 20 - height: 20 - } - Rect { - color: "green" - x: 60 - y: 20 - width: 20 - height: 20 - } - Rect { - color: "yellow" - x: 20 - y: 40 - width: 20 - height: 20 - } - Rect { - color: "purple" - x: 20 - y: 60 - width: 20 - height: 20 - } - Rect { - color: "white" - x: 40 - y: 40 - width: 20 - height: 20 - } - Rect { - anchors.fill: parent - color: "gray" - z: -1 - } -} diff --git a/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro b/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro deleted file mode 100644 index f4aea32..0000000 --- a/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative -contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, opengles1): QT += opengl -SOURCES += tst_simplecanvasitem.cpp - -# Define SRCDIR equal to test's source directory -DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/simplecanvasitem/tst_simplecanvasitem.cpp b/tests/auto/declarative/simplecanvasitem/tst_simplecanvasitem.cpp deleted file mode 100644 index cce4df1..0000000 --- a/tests/auto/declarative/simplecanvasitem/tst_simplecanvasitem.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include - -/* - Note: this autotest is specifically to test SimpleCanvasItem as a component of - Qt Declarative, and therefore will have all items created in XML. -*/ -class tst_SimpleCanvasItem : public QObject -{ - Q_OBJECT -public: - tst_SimpleCanvasItem(); - -private slots: - void test_pos(); - void test_scenePos(); -private: - QFxView *createView(const QString &filename); -}; - -tst_SimpleCanvasItem::tst_SimpleCanvasItem() -{ -} - -void tst_SimpleCanvasItem::test_pos() -{ - QFxView *canvas = createView(SRCDIR "/data/test.qml"); - canvas->execute(); - qApp->processEvents(); - QSimpleCanvasItem* root = qobject_cast(canvas->root()); - QVERIFY(root); - - QCOMPARE(root->pos(), QPointF(0,0)); - QCOMPARE(root->children().at(0)->pos(), QPointF(20,20)); - QCOMPARE(root->children().at(0)->children().at(0)->pos(), QPointF(20,20)); - QCOMPARE(root->children().at(2)->pos(), QPointF(60,20)); - QCOMPARE(root->children().at(3)->pos(), QPointF(20,40)); - QCOMPARE(root->children().at(5)->pos(), QPointF(40,40)); -} - -void tst_SimpleCanvasItem::test_scenePos() -{ - QFxView *canvas = createView(SRCDIR "/data/test.qml"); - canvas->execute(); - qApp->processEvents(); - QSimpleCanvasItem* root = qobject_cast(canvas->root()); - QVERIFY(root); - -#ifdef CANVAS_GL - QCOMPARE(root->transform(), QMatrix4x4()); -#else - QCOMPARE(root->transform(), QTransform()); -#endif - QCOMPARE(root->scenePos(), QPointF(0,0)); - QCOMPARE(root->children().at(0)->scenePos(), QPointF(20,20)); - QCOMPARE(root->children().at(0)->children().at(0)->scenePos(), QPointF(40,40)); - QCOMPARE(root->children().at(2)->scenePos(), QPointF(60,20)); - QCOMPARE(root->children().at(3)->scenePos(), QPointF(20,40)); - QCOMPARE(root->children().at(5)->scenePos(), QPointF(40,40)); -} - -QFxView *tst_SimpleCanvasItem::createView(const QString &filename) -{ - QFxView *canvas = new QFxView(0); - canvas->setFixedSize(240,320); - - QFile file(filename); - file.open(QFile::ReadOnly); - QString xml = file.readAll(); - canvas->setQml(xml, filename); - - return canvas; -} - -QTEST_MAIN(tst_SimpleCanvasItem) - -#include "tst_simplecanvasitem.moc" -- cgit v0.12 From c452c44d8cee138dcdd62f8c0f0db48b4ada5c40 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 3 Sep 2009 10:52:45 +1000 Subject: Fix a bug in the qmlvme, which lead to an assert on valid QML. As QmlComponents are created outside the CreateObject instruction, they could be created with an uninitalized declarative data member. Also this patch sets the column on CreateObject instructions too. Reviewed-by: Aaron Kennedy --- src/declarative/qml/qmlcompiler.cpp | 2 ++ src/declarative/qml/qmlinstruction_p.h | 1 + src/declarative/qml/qmlvme.cpp | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index c0f7bfd..c411b8d 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -781,6 +781,7 @@ void QmlCompiler::genObject(QmlParser::Object *obj) QmlInstruction create; create.type = QmlInstruction::CreateObject; create.line = obj->location.start.line; + create.create.column = obj->location.start.column; create.create.data = -1; if (!obj->custom.isEmpty()) create.create.data = output->indexForByteArray(obj->custom); @@ -937,6 +938,7 @@ void QmlCompiler::genComponent(QmlParser::Object *obj) QmlInstruction create; create.type = QmlInstruction::CreateComponent; create.line = root->location.start.line; + create.createComponent.column = root->location.start.column; create.createComponent.endLine = root->location.end.line; output->bytecode << create; int count = output->bytecode.count(); diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index ede06a2..3c6af1b 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -284,6 +284,7 @@ public: } assignSignalObject; struct { int count; + ushort column; int endLine; int metaObject; } createComponent; diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index a49cbd3..4d133e3 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -222,6 +222,14 @@ QObject *QmlVME::run(QStack &stack, QmlContext *ctxt, QmlCompiledData case QmlInstruction::CreateComponent: { QObject *qcomp = new QmlComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top()); + + QmlEngine::setContextForObject(qcomp, ctxt); + QmlDeclarativeData *ddata = QmlDeclarativeData::get(qcomp); + Q_ASSERT(ddata); + ddata->outerContext = ctxt; + ddata->lineNumber = instr.line; + ddata->columnNumber = instr.create.column; + stack.push(qcomp); ii += instr.createComponent.count; } -- cgit v0.12 From 369509bd4c1caeda50d3e6e15f98ffafb136a17e Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 3 Sep 2009 11:22:48 +1000 Subject: Get animation autotests working again, and add a few more. --- src/declarative/util/qmlanimation.h | 10 +- .../declarative/animations/data/badproperty1.qml | 6 +- .../auto/declarative/animations/data/badtype1.qml | 4 +- .../auto/declarative/animations/data/badtype2.qml | 4 +- .../auto/declarative/animations/data/badtype3.qml | 4 +- .../auto/declarative/animations/data/badtype4.qml | 9 +- tests/auto/declarative/animations/data/color.qml | 12 -- .../declarative/animations/data/dotproperty.qml | 6 +- .../declarative/animations/data/mixedtype1.qml | 8 +- .../declarative/animations/data/mixedtype2.qml | 6 +- tests/auto/declarative/animations/data/number.qml | 12 -- .../auto/declarative/animations/tst_animations.cpp | 136 +++++++++++++++++---- 12 files changed, 138 insertions(+), 79 deletions(-) delete mode 100644 tests/auto/declarative/animations/data/color.qml delete mode 100644 tests/auto/declarative/animations/data/number.qml diff --git a/src/declarative/util/qmlanimation.h b/src/declarative/util/qmlanimation.h index a898be8..7104f60 100644 --- a/src/declarative/util/qmlanimation.h +++ b/src/declarative/util/qmlanimation.h @@ -58,7 +58,7 @@ QT_MODULE(Declarative) class QmlAbstractAnimationPrivate; class QmlAnimationGroup; -class QmlAbstractAnimation : public QObject, public QmlPropertyValueSource, public QmlParserStatus +class Q_AUTOTEST_EXPORT QmlAbstractAnimation : public QObject, public QmlPropertyValueSource, public QmlParserStatus { Q_OBJECT Q_DECLARE_PRIVATE(QmlAbstractAnimation) @@ -68,8 +68,6 @@ class QmlAbstractAnimation : public QObject, public QmlPropertyValueSource, publ Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged()) Q_PROPERTY(bool repeat READ repeat WRITE setRepeat NOTIFY repeatChanged) - //Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) - //Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY targetChanged) Q_CLASSINFO("DefaultMethod", "start()") Q_INTERFACES(QmlParserStatus) @@ -252,7 +250,7 @@ protected: }; class QmlPropertyAnimationPrivate; -class QmlPropertyAnimation : public QmlAbstractAnimation +class Q_AUTOTEST_EXPORT QmlPropertyAnimation : public QmlAbstractAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QmlPropertyAnimation) @@ -304,7 +302,7 @@ Q_SIGNALS: void propertiesChanged(const QString &); }; -class QmlColorAnimation : public QmlPropertyAnimation +class Q_AUTOTEST_EXPORT QmlColorAnimation : public QmlPropertyAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QmlPropertyAnimation) @@ -322,7 +320,7 @@ public: void setTo(const QColor &); }; -class QmlNumberAnimation : public QmlPropertyAnimation +class Q_AUTOTEST_EXPORT QmlNumberAnimation : public QmlPropertyAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QmlPropertyAnimation) diff --git a/tests/auto/declarative/animations/data/badproperty1.qml b/tests/auto/declarative/animations/data/badproperty1.qml index b88cd6f..a01753e 100644 --- a/tests/auto/declarative/animations/data/badproperty1.qml +++ b/tests/auto/declarative/animations/data/badproperty1.qml @@ -1,10 +1,10 @@ import Qt 4.6 -Rect { +Rectangle { id: Wrapper width: 240 height: 320 - Rect { + Rectangle { id: MyRect color: "red" width: 50; height: 50 @@ -16,7 +16,7 @@ Rect { } states: State { name: "state1" - SetProperties { target: MyRect; pen.color: "blue" } + PropertyChanges { target: MyRect; pen.color: "blue" } } transitions: Transition { ColorAnimation { target: MyRect; to: "red"; properties: "pen.colr"; duration: 1000 } diff --git a/tests/auto/declarative/animations/data/badtype1.qml b/tests/auto/declarative/animations/data/badtype1.qml index 00db39e..1e689d5 100644 --- a/tests/auto/declarative/animations/data/badtype1.qml +++ b/tests/auto/declarative/animations/data/badtype1.qml @@ -1,9 +1,9 @@ import Qt 4.6 -Rect { +Rectangle { width: 240 height: 320 - Rect { + Rectangle { color: "red" width: 50; height: 50 x: 100; y: 100 diff --git a/tests/auto/declarative/animations/data/badtype2.qml b/tests/auto/declarative/animations/data/badtype2.qml index eeaaefc..e97194d 100644 --- a/tests/auto/declarative/animations/data/badtype2.qml +++ b/tests/auto/declarative/animations/data/badtype2.qml @@ -1,9 +1,9 @@ import Qt 4.6 -Rect { +Rectangle { width: 240 height: 320 - Rect { + Rectangle { color: "red" width: 50; height: 50 x: 100; y: 100 diff --git a/tests/auto/declarative/animations/data/badtype3.qml b/tests/auto/declarative/animations/data/badtype3.qml index cbb1a4d..b2d738f 100644 --- a/tests/auto/declarative/animations/data/badtype3.qml +++ b/tests/auto/declarative/animations/data/badtype3.qml @@ -1,9 +1,9 @@ import Qt 4.6 -Rect { +Rectangle { width: 240 height: 320 - Rect { + Rectangle { color: "red" color: ColorAnimation { from: 10; to: 15; running: true; } width: 50; height: 50 diff --git a/tests/auto/declarative/animations/data/badtype4.qml b/tests/auto/declarative/animations/data/badtype4.qml index 3e046fc..0c0a636 100644 --- a/tests/auto/declarative/animations/data/badtype4.qml +++ b/tests/auto/declarative/animations/data/badtype4.qml @@ -1,10 +1,10 @@ import Qt 4.6 -Rect { +Rectangle { id: Wrapper width: 240 height: 320 - Rect { + Rectangle { id: MyRect color: "red" width: 50; height: 50 @@ -16,10 +16,11 @@ Rect { } states: State { name: "state1" - SetProperties { target: MyRect; x: 200; color: "blue" } + PropertyChanges { target: MyRect; x: 200; color: "blue" } } transitions: Transition { + //comment out each in turn to make sure each only animates the relevant property ColorAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color - //NumberAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color + NumberAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color } } diff --git a/tests/auto/declarative/animations/data/color.qml b/tests/auto/declarative/animations/data/color.qml deleted file mode 100644 index 8a9ab8a..0000000 --- a/tests/auto/declarative/animations/data/color.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Qt 4.6 - -Rect { - width: 240 - height: 320 - Rect { - color: "red" - color: PropertyAnimation { to: "green"; running: true } - width: 50; height: 50 - x: 100; y: 100 - } -} diff --git a/tests/auto/declarative/animations/data/dotproperty.qml b/tests/auto/declarative/animations/data/dotproperty.qml index 25076b8..ee076c2 100644 --- a/tests/auto/declarative/animations/data/dotproperty.qml +++ b/tests/auto/declarative/animations/data/dotproperty.qml @@ -1,10 +1,10 @@ import Qt 4.6 -Rect { +Rectangle { id: Wrapper width: 240 height: 320 - Rect { + Rectangle { id: MyRect color: "red" width: 50; height: 50 @@ -16,7 +16,7 @@ Rect { } states: State { name: "state1" - SetProperties { target: MyRect; pen.color: "blue" } + PropertyChanges { target: MyRect; pen.color: "blue" } } transitions: Transition { ColorAnimation { properties: "pen.color"; duration: 1000 } diff --git a/tests/auto/declarative/animations/data/mixedtype1.qml b/tests/auto/declarative/animations/data/mixedtype1.qml index 8b8262b..ed50582 100644 --- a/tests/auto/declarative/animations/data/mixedtype1.qml +++ b/tests/auto/declarative/animations/data/mixedtype1.qml @@ -1,10 +1,10 @@ import Qt 4.6 -Rect { +Rectangle { id: Wrapper width: 240 height: 320 - Rect { + Rectangle { id: MyRect color: "red" width: 50; height: 50 @@ -16,9 +16,9 @@ Rect { } states: State { name: "state1" - SetProperties { target: MyRect; x: 200; width: 40 } + PropertyChanges { target: MyRect; x: 200; border.width: 10 } } transitions: Transition { - PropertyAnimation { properties: "x,width"; duration: 1000 } //x is real, width is int + PropertyAnimation { properties: "x,border.width"; duration: 1000 } //x is real, border.width is int } } diff --git a/tests/auto/declarative/animations/data/mixedtype2.qml b/tests/auto/declarative/animations/data/mixedtype2.qml index 95b8ed7..4854c2e 100644 --- a/tests/auto/declarative/animations/data/mixedtype2.qml +++ b/tests/auto/declarative/animations/data/mixedtype2.qml @@ -1,10 +1,10 @@ import Qt 4.6 -Rect { +Rectangle { id: Wrapper width: 240 height: 320 - Rect { + Rectangle { id: MyRect color: "red" width: 50; height: 50 @@ -16,7 +16,7 @@ Rect { } states: State { name: "state1" - SetProperties { target: MyRect; x: 200; color: "blue" } + PropertyChanges { target: MyRect; x: 200; color: "blue" } } transitions: Transition { PropertyAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color diff --git a/tests/auto/declarative/animations/data/number.qml b/tests/auto/declarative/animations/data/number.qml deleted file mode 100644 index bde1168..0000000 --- a/tests/auto/declarative/animations/data/number.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Qt 4.6 - -Rect { - width: 240 - height: 320 - Rect { - color: "red" - width: 50; height: 50 - x: 100; y: 100 - x: PropertyAnimation { from: 0; to: 200; duration: 1000; running: true } - } -} diff --git a/tests/auto/declarative/animations/tst_animations.cpp b/tests/auto/declarative/animations/tst_animations.cpp index 889d9b7..ff06a04 100644 --- a/tests/auto/declarative/animations/tst_animations.cpp +++ b/tests/auto/declarative/animations/tst_animations.cpp @@ -3,6 +3,7 @@ #include #include #include +#include class tst_animations : public QObject { @@ -11,11 +12,68 @@ public: tst_animations() {} private slots: + void simpleNumber(); + void simpleColor(); + void alwaysRunToEnd(); void badTypes(); void badProperties(); - //void mixedTypes(); + void mixedTypes(); }; +void tst_animations::simpleNumber() +{ + QFxRect rect; + QmlNumberAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.start(); + QTest::qWait(animation.duration() + 50); + QCOMPARE(rect.x(), qreal(200)); + + rect.setX(0); + animation.start(); + animation.pause(); + animation.setCurrentTime(125); + QCOMPARE(rect.x(), qreal(100)); +} + +void tst_animations::simpleColor() +{ + QFxRect rect; + QmlColorAnimation animation; + animation.setTarget(&rect); + animation.setProperty("color"); + animation.setTo(QColor("red")); + animation.start(); + QTest::qWait(animation.duration() + 50); + QCOMPARE(rect.color(), QColor("red")); + + rect.setColor(QColor("blue")); + animation.start(); + animation.pause(); + animation.setCurrentTime(125); + QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); +} + +void tst_animations::alwaysRunToEnd() +{ + QFxRect rect; + QmlPropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(1000); + animation.setRepeat(true); + animation.setAlwaysRunToEnd(true); + animation.start(); + QTest::qWait(1500); + animation.stop(); + QVERIFY(rect.x() != qreal(200)); + QTest::qWait(500 + 50); + QCOMPARE(rect.x(), qreal(200)); +} + void tst_animations::badTypes() { //don't crash @@ -50,47 +108,73 @@ void tst_animations::badTypes() QVERIFY(c.errors().count() == 1); QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected")); } + + //don't crash + { + QmlEngine engine; + QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/badtype4.qml")); + QFxRect *rect = qobject_cast(c.create()); + QVERIFY(rect); + + rect->setState("state1"); + QTest::qWait(1000 + 50); + QFxRect *myRect = qobject_cast(rect->QGraphicsObject::children().at(3)); //### not robust + QVERIFY(myRect); + QCOMPARE(myRect->x(),qreal(200)); + } } void tst_animations::badProperties() { - //don't crash (should be runtime error) + //make sure we get a runtime error { - QFxView *view = new QFxView; - view->setUrl(QUrl("file://" SRCDIR "/data/badproperty1.qml")); - - view->execute(); - qApp->processEvents(); + QmlEngine engine; + QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/badproperty1.qml")); + QFxRect *rect = qobject_cast(c.create()); + QVERIFY(rect); - delete view; + QTest::ignoreMessage(QtWarningMsg, "QML QmlColorAnimation (file://" SRCDIR "/data/badproperty1.qml:22:9) Cannot animate non-existant property \"pen.colr\" "); + rect->setState("state1"); } } -/*//test animating mixed types with property animation - //for example, int + real; color + real; etc +//test animating mixed types with property animation in a transition +//for example, int + real; color + real; etc void tst_animations::mixedTypes() { - //### this one isn't real robust because width will likely change to real as well + //assumes border.width stats a real -- not real robust { - QFxView *view = new QFxView; - view->setUrl(QUrl("file://" SRCDIR "/data/mixedtype1.qml")); - - view->execute(); - qApp->processEvents(); - - delete view; + QmlEngine engine; + QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/mixedtype1.qml")); + QFxRect *rect = qobject_cast(c.create()); + QVERIFY(rect); + + rect->setState("state1"); + QTest::qWait(500); + QFxRect *myRect = qobject_cast(rect->QGraphicsObject::children().at(3)); //### not robust + QVERIFY(myRect); + + //rather inexact -- is there a better way? + QVERIFY(myRect->x() > 100 && myRect->x() < 200); + QVERIFY(myRect->border()->width() > 1 && myRect->border()->width() < 10); } { - QFxView *view = new QFxView; - view->setUrl(QUrl("file://" SRCDIR "/data/mixedtype2.qml")); - - view->execute(); - qApp->processEvents(); - - delete view; + QmlEngine engine; + QmlComponent c(&engine, QUrl("file://" SRCDIR "/data/mixedtype2.qml")); + QFxRect *rect = qobject_cast(c.create()); + QVERIFY(rect); + + rect->setState("state1"); + QTest::qWait(500); + QFxRect *myRect = qobject_cast(rect->QGraphicsObject::children().at(3)); //### not robust + QVERIFY(myRect); + + //rather inexact -- is there a better way? + QVERIFY(myRect->x() > 100 && myRect->x() < 200); + QVERIFY(myRect->color() != QColor("red") && myRect->color() != QColor("blue")); } -}*/ +} QTEST_MAIN(tst_animations) -- cgit v0.12 From 0a73357d3851b4eb20483a05f434455f96ded10b Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 3 Sep 2009 11:27:32 +1000 Subject: Add one more animation test. --- tests/auto/declarative/animations/tst_animations.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/auto/declarative/animations/tst_animations.cpp b/tests/auto/declarative/animations/tst_animations.cpp index ff06a04..8e1abc6 100644 --- a/tests/auto/declarative/animations/tst_animations.cpp +++ b/tests/auto/declarative/animations/tst_animations.cpp @@ -15,6 +15,7 @@ private slots: void simpleNumber(); void simpleColor(); void alwaysRunToEnd(); + void dotProperty(); void badTypes(); void badProperties(); void mixedTypes(); @@ -74,6 +75,24 @@ void tst_animations::alwaysRunToEnd() QCOMPARE(rect.x(), qreal(200)); } +void tst_animations::dotProperty() +{ + QFxRect rect; + QmlNumberAnimation animation; + animation.setTarget(&rect); + animation.setProperty("border.width"); + animation.setTo(10); + animation.start(); + QTest::qWait(animation.duration() + 50); + QCOMPARE(rect.border()->width(), 10); + + rect.border()->setWidth(1); + animation.start(); + animation.pause(); + animation.setCurrentTime(125); + QCOMPARE(rect.border()->width(), 5); +} + void tst_animations::badTypes() { //don't crash -- cgit v0.12