diff options
98 files changed, 887 insertions, 1031 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..4de2202 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 diff --git a/demos/declarative/flickr/mobile/GridDelegate.qml b/demos/declarative/flickr/mobile/GridDelegate.qml index 291d874..767315c 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 { 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/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml index 89fe3e8..ab36122 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,9 +29,9 @@ 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 width: w * s; height: h * s; visible: originalImage.status != Image.Ready @@ -42,7 +43,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/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..5e4be4c 100644 --- a/demos/declarative/photoviewer/photoviewer.qml +++ b/demos/declarative/photoviewer/photoviewer.qml @@ -10,8 +10,6 @@ Rectangle { width: 800; height: 480; color: "#d5d6d8" - Script { source: "PhotoViewerCore/script/script.js" } - ListModel { id: photosModel ListElement { tag: "Flowers" } 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/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/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/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/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/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index 1ebbaee..8b46039 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; }; /*! @@ -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/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/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 6dbcd16..745734e 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -66,7 +66,7 @@ void QDeclarativeLoaderPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem void QDeclarativeLoaderPrivate::clear() { if (ownComponent) { - delete component; + component->deleteLater(); component = 0; ownComponent = false; } @@ -285,7 +285,16 @@ 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); 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/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/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..28c2210 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); } } 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..c883805 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; } } @@ -539,7 +571,7 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData } 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)) { QDeclarativeError error; error.setUrl(unit->imports.baseUrl()); @@ -558,14 +590,18 @@ 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, diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 782c0d7..85896c4 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) { diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index d74aa33..ecf3ec8 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -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 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..0bedbeb 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; } } @@ -1434,22 +1432,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 +1463,7 @@ public: } } } - return qmldircontent; + return qmldirParser.components(); } QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine) @@ -1512,9 +1510,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 qmldircontent = qmldircontentnetwork; + QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork; QString uri = uri_arg; QDeclarativeEnginePrivate::ImportedNamespace *s; if (prefix.isEmpty()) { @@ -1566,19 +1564,19 @@ public: url = QUrl::fromLocalFile(fi.absolutePath()).toString(); uri = resolvedUri(dir, engine); - qmldircontent = importExtension(absoluteFilePath, uri, engine); + qmldircomponents = importExtension(absoluteFilePath, uri, engine); break; } } } 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()) { uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine); - qmldircontent = importExtension(localFileOrQrc, + qmldircomponents = importExtension(localFileOrQrc, uri, engine); @@ -1597,7 +1595,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 +1615,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 +1625,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 +1695,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 +1714,6 @@ QDeclarativeTypeNameCache *QDeclarativeEnginePrivate::Imports::cache(QDeclarativ } cacheForNamespace(engine, set, cache); - - return cache; } /* @@ -1970,12 +1955,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) 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); return ok; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index f1b7b0e..6532d30 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,9 @@ 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) const; bool resolveType(const Imports&, const QByteArray& type, QDeclarativeType** type_return, QUrl* url_return, int *version_major, int *version_minor, @@ -302,6 +305,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/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/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/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index eb339f6..925eb36 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()") 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/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/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 6f5bb66..96c75a9 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -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; @@ -944,7 +943,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/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp index 4d4678a..cb35734 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() { diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 59a062a..c2dbf92 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> @@ -251,13 +248,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); @@ -455,8 +445,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/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 ddf00ea..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 \ @@ -62,8 +58,7 @@ HEADERS += \ $$PWD/qdeclarativebehavior_p.h \ $$PWD/qdeclarativefontloader_p.h \ $$PWD/qdeclarativestyledtext_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p_p.h + $$PWD/qdeclarativelistmodelworkeragent_p.h contains(QT_CONFIG, xmlpatterns) { QT+=xmlpatterns 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/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..04c6710 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> @@ -57,6 +58,7 @@ private slots: void create(); void checkFrontAndBack(); void setFrontAndBack(); + void crash(); private: QDeclarativeEngine engine; @@ -108,6 +110,14 @@ void tst_qdeclarativeflipable::setFrontAndBack() delete obj; } +void tst_qdeclarativeflipable::crash() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl(SRCDIR "/data/crash.qml")); + canvas->show(); + delete canvas; +} + QTEST_MAIN(tst_qdeclarativeflipable) #include "tst_qdeclarativeflipable.moc" 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/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..9188d72 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -1242,6 +1242,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/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/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/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index 61b2800..2c20836 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -88,6 +88,8 @@ private slots: void failNetworkRequest(); // void networkComponent(); + void deleteComponentCrash(); + private: QDeclarativeEngine engine; }; @@ -459,6 +461,28 @@ 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); + QEXPECT_FAIL("", "QTBUG-9245", Continue); + QVERIFY(loader->source() == QUrl::fromLocalFile(SRCDIR "/data/BlueRect.qml")); + + delete item; +} + QTEST_MAIN(tst_QDeclarativeLoader) #include "tst_qdeclarativeloader.moc" 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..9e1d727 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() @@ -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/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/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/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) { |