diff options
author | Warwick Allison <warwick.allison@nokia.com> | 2009-10-27 06:30:08 (GMT) |
---|---|---|
committer | Warwick Allison <warwick.allison@nokia.com> | 2009-10-27 06:30:08 (GMT) |
commit | d72970e54390f00be28efaac148b55f027a1eb69 (patch) | |
tree | efeb095eebca0c2cf29391d08f3bc58d5baa1f68 | |
parent | fc4dd3eab91fc1959e216a754620a96cf05932d7 (diff) | |
parent | f2c0f63c2db21e3a0dd2fb78312084a835840be8 (diff) | |
download | Qt-d72970e54390f00be28efaac148b55f027a1eb69.zip Qt-d72970e54390f00be28efaac148b55f027a1eb69.tar.gz Qt-d72970e54390f00be28efaac148b55f027a1eb69.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
74 files changed, 2198 insertions, 266 deletions
diff --git a/examples/declarative/focusscope/test3.qml b/examples/declarative/focusscope/test3.qml index e5aa7b6..1b3181b 100644 --- a/examples/declarative/focusscope/test3.qml +++ b/examples/declarative/focusscope/test3.qml @@ -40,8 +40,8 @@ Rectangle { model: model delegate: verticalDelegate preferredHighlightBegin: 100 - preferredHighlightEnd: 101 - strictlyEnforceHighlightRange: true + preferredHighlightEnd: 100 + highlightRangeMode: "StrictlyEnforceRange" } diff --git a/examples/declarative/listview/content/ClickAutoRepeating.qml b/examples/declarative/listview/content/ClickAutoRepeating.qml index f0e7df1..796f9e3 100644 --- a/examples/declarative/listview/content/ClickAutoRepeating.qml +++ b/examples/declarative/listview/content/ClickAutoRepeating.qml @@ -4,25 +4,27 @@ Item { id: page property int repeatdelay: 300 property int repeatperiod: 75 - property bool pressed: false + property bool isPressed: false + signal pressed signal released signal clicked - pressed: SequentialAnimation { + + isPressed: SequentialAnimation { id: autoRepeat - PropertyAction { target: page; property: "pressed"; value: true } - ScriptAction { script: page.onPressed } - ScriptAction { script: page.onClicked } + PropertyAction { target: page; property: "isPressed"; value: true } + ScriptAction { script: page.pressed() } + ScriptAction { script: page.clicked() } PauseAnimation { duration: repeatdelay } SequentialAnimation { repeat: true - ScriptAction { script: page.onClicked } + ScriptAction { script: page.clicked() } PauseAnimation { duration: repeatperiod } } } MouseRegion { anchors.fill: parent onPressed: autoRepeat.start() - onReleased: { autoRepeat.stop(); parent.pressed = false; page.released } + onReleased: { autoRepeat.stop(); parent.isPressed = false; page.released() } } } diff --git a/examples/declarative/listview/content/pics/archive-insert.png b/examples/declarative/listview/content/pics/archive-insert.png Binary files differnew file mode 100644 index 0000000..b706248 --- /dev/null +++ b/examples/declarative/listview/content/pics/archive-insert.png diff --git a/examples/declarative/listview/content/pics/archive-remove.png b/examples/declarative/listview/content/pics/archive-remove.png Binary files differnew file mode 100644 index 0000000..9640f6b --- /dev/null +++ b/examples/declarative/listview/content/pics/archive-remove.png diff --git a/examples/declarative/listview/content/pics/go-down.png b/examples/declarative/listview/content/pics/go-down.png Binary files differnew file mode 100644 index 0000000..63331a5 --- /dev/null +++ b/examples/declarative/listview/content/pics/go-down.png diff --git a/examples/declarative/listview/content/pics/go-up.png b/examples/declarative/listview/content/pics/go-up.png Binary files differnew file mode 100644 index 0000000..4459024 --- /dev/null +++ b/examples/declarative/listview/content/pics/go-up.png diff --git a/examples/declarative/listview/content/pics/list-add.png b/examples/declarative/listview/content/pics/list-add.png Binary files differnew file mode 100644 index 0000000..e029787 --- /dev/null +++ b/examples/declarative/listview/content/pics/list-add.png diff --git a/examples/declarative/listview/content/pics/list-remove.png b/examples/declarative/listview/content/pics/list-remove.png Binary files differnew file mode 100644 index 0000000..2bb1a59 --- /dev/null +++ b/examples/declarative/listview/content/pics/list-remove.png diff --git a/examples/declarative/listview/dynamic.qml b/examples/declarative/listview/dynamic.qml index 4f8e483..78346f3 100644 --- a/examples/declarative/listview/dynamic.qml +++ b/examples/declarative/listview/dynamic.qml @@ -1,54 +1,48 @@ import Qt 4.6 import "content" -Item { - width: 320 - height: 500 +Rectangle { + width: 640; height: 480 + color: "#343434" ListModel { id: fruitModel ListElement { - name: "Apple" - cost: 2.45 + name: "Apple"; cost: 2.45 attributes: [ ListElement { description: "Core" }, ListElement { description: "Deciduous" } ] } ListElement { - name: "Banana" - cost: 1.95 + name: "Banana"; cost: 1.95 attributes: [ ListElement { description: "Tropical" }, ListElement { description: "Seedless" } ] } ListElement { - name: "Cumquat" - cost: 3.25 + name: "Cumquat"; cost: 3.25 types: [ "Small", "Smaller" ] attributes: [ ListElement { description: "Citrus" } ] } ListElement { - name: "Durian" - cost: 9.95 + name: "Durian"; cost: 9.95 attributes: [ ListElement { description: "Tropical" }, ListElement { description: "Smelly" } ] } ListElement { - name: "Elderberry" - cost: 0.05 + name: "Elderberry"; cost: 0.05 attributes: [ ListElement { description: "Berry" } ] } ListElement { - name: "Fig" - cost: 0.25 + name: "Fig"; cost: 0.25 attributes: [ ListElement { description: "Flower" } ] @@ -59,83 +53,85 @@ Item { id: fruitDelegate Item { width: parent.width; height: 55 - Text { id: label; font.pixelSize: 24; text: name; elide: "ElideRight"; anchors.right: cost.left; anchors.left:parent.left } - Text { id: cost; font.pixelSize: 24; text: '$'+Number(cost).toFixed(2); anchors.right: itemButtons.left } - Row { - anchors.top: label.bottom - spacing: 5 - Repeater { - model: attributes - Component { - Text { text: description } - } + + Column { + id: moveButtons; x: 5; width: childrenRect.width; anchors.verticalCenter: parent.verticalCenter + Image { source: "content/pics/go-up.png" + MouseRegion { anchors.fill: parent; onClicked: fruitModel.move(index,index-1,1) } + } + Image { source: "content/pics/go-down.png" + MouseRegion { anchors.fill: parent; onClicked: fruitModel.move(index,index+1,1) } + } + } + + Column { + anchors { right: itemButtons.left; verticalCenter: parent.verticalCenter; left: moveButtons.right; leftMargin: 10 } + Text { + id: label; font.bold: true; text: name; elide: Text.ElideRight; font.pixelSize: 15 + width: parent.width; color: "White" + } + Row { + spacing: 5 + Repeater { model: attributes; Component { Text { text: description; color: "White" } } } } } + Row { id: itemButtons - anchors.right: parent.right - width: childrenRect.width - Image { source: "content/pics/add.png" + anchors.right: removeButton.left; anchors.rightMargin: 35; spacing: 10 + width: childrenRect.width; anchors.verticalCenter: parent.verticalCenter + Image { source: "content/pics/list-add.png" ClickAutoRepeating { id: clickUp; anchors.fill: parent; onClicked: fruitModel.set(index,"cost",Number(cost)+0.25) } - scale: clickUp.pressed ? 0.9 : 1 + scale: clickUp.isPressed ? 0.9 : 1; transformOrigin: Item.Center } - Image { source: "content/pics/del.png" + Text { id: costText; text: '$'+Number(cost).toFixed(2); font.pixelSize: 15; color: "White"; font.bold: true; } + Image { source: "content/pics/list-remove.png" ClickAutoRepeating { id: clickDown; anchors.fill: parent; onClicked: fruitModel.set(index,"cost",Math.max(0,Number(cost)-0.25)) } - scale: clickDown.pressed ? 0.9 : 1 - } - Image { source: "content/pics/trash.png" - MouseRegion { anchors.fill: parent; onClicked: fruitModel.remove(index) } - } - Column { - width: childrenRect.width - Image { source: "content/pics/moreUp.png" - MouseRegion { anchors.fill: parent; onClicked: fruitModel.move(index,index-1,1) } - } - Image { source: "content/pics/moreDown.png" - MouseRegion { anchors.fill: parent; onClicked: fruitModel.move(index,index+1,1) } - } + scale: clickDown.isPressed ? 0.9 : 1; transformOrigin: Item.Center } } + Image { + id: removeButton; source: "content/pics/archive-remove.png" + anchors { verticalCenter: parent.verticalCenter; right: parent.right; rightMargin: 10 } + MouseRegion { anchors.fill:parent; onClicked: fruitModel.remove(index) } + } } } ListView { - model: fruitModel - delegate: fruitDelegate - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: buttons.top + model: fruitModel; delegate: fruitDelegate + anchors { top: parent.top; left: parent.left; right: parent.right; bottom: buttons.top } } Row { - width: childrenRect.width + x: 8; width: childrenRect.width height: childrenRect.height - anchors.bottom: parent.bottom + anchors { bottom: parent.bottom; bottomMargin: 8 } + spacing: 8 id: buttons - Image { source: "content/pics/add.png" + Image { source: "content/pics/archive-insert.png" MouseRegion { anchors.fill: parent; onClicked: { fruitModel.append({ "name":"Pizza Margarita", "cost":5.95, "attributes":[{"description": "Cheese"},{"description": "Tomato"}] - }) + }) } } } - Image { source: "content/pics/add.png" + Image { source: "content/pics/archive-insert.png" MouseRegion { anchors.fill: parent; onClicked: { fruitModel.insert(0,{ "name":"Pizza Supreme", "cost":9.95, "attributes":[{"description": "Cheese"},{"description": "Tomato"},{"description": "The Works"}] - }) + }) } } } - Image { source: "content/pics/trash.png" + Image { source: "content/pics/archive-remove.png" MouseRegion { anchors.fill: parent; onClicked: fruitModel.clear() } } } diff --git a/examples/declarative/listview/itemlist.qml b/examples/declarative/listview/itemlist.qml index 6dfc90b..77f5c2d 100644 --- a/examples/declarative/listview/itemlist.qml +++ b/examples/declarative/listview/itemlist.qml @@ -30,8 +30,8 @@ Rectangle { anchors.bottomMargin: 30 model: itemModel preferredHighlightBegin: 0 - preferredHighlightEnd: 1 - strictlyEnforceHighlightRange: true + preferredHighlightEnd: 0 + highlightRangeMode: "StrictlyEnforceRange" orientation: "Horizontal" } diff --git a/examples/declarative/listview/listview.qml b/examples/declarative/listview/listview.qml index 98974fd..b614904 100644 --- a/examples/declarative/listview/listview.qml +++ b/examples/declarative/listview/listview.qml @@ -41,7 +41,7 @@ Rectangle { // current item within the the bounds of the range, however // items will not scroll beyond the beginning or end of the view, // forcing the highlight to move outside the range at the ends. - // The third list sets strictlyEnforceHighlightRange to true + // The third list sets the highlightRangeMode to StrictlyEnforceRange // and sets a range smaller than the height of an item. This // forces the current item to change when the view is flicked, // since the highlight is unable to move. @@ -61,6 +61,7 @@ Rectangle { model: MyPetsModel; delegate: petDelegate; highlight: petHighlight preferredHighlightBegin: 80 preferredHighlightEnd: 220 + highlightRangeMode: "ApplyRange" currentIndex: list1.currentIndex } ListView { @@ -69,7 +70,7 @@ Rectangle { model: MyPetsModel; delegate: petDelegate; highlight: petHighlight currentIndex: list1.currentIndex preferredHighlightBegin: 125 - preferredHighlightEnd: 126 - strictlyEnforceHighlightRange: true + preferredHighlightEnd: 125 + highlightRangeMode: "StrictlyEnforceRange" } } diff --git a/examples/declarative/parallax/ParallaxView.qml b/examples/declarative/parallax/ParallaxView.qml index 4ddab00..1708ad1 100644 --- a/examples/declarative/parallax/ParallaxView.qml +++ b/examples/declarative/parallax/ParallaxView.qml @@ -1,7 +1,11 @@ import Qt 4.6 Item { + id: root + property alias background: background.source + default property alias content: visualModel.children + property int currentIndex: 0 Image { id: background @@ -10,10 +14,12 @@ Item { width: Math.max(list.viewportWidth, parent.width) } - /* - default property alias content: visualModel.children ListView { id: list + + currentIndex: root.currentIndex + onCurrentIndexChanged: root.currentIndex = currentIndex + orientation: "Horizontal" overShoot: false anchors.fill: parent @@ -21,21 +27,62 @@ Item { highlight: Item { height: 1; width: 1} preferredHighlightBegin: 0 - preferredHighlightEnd: 1 - strictlyEnforceHighlightRange: true + preferredHighlightEnd: 0 + highlightRangeMode: "StrictlyEnforceRange" } - */ - default property alias content: flickArea.data - Flickable { - id: list - anchors.fill: parent - overShoot: false - viewportWidth: flickArea.width + ListView { + id: selector + + currentIndex: root.currentIndex + onCurrentIndexChanged: root.currentIndex = currentIndex + + height: 50 + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + width: Math.min(count * 50, parent.width - 20) + interactive: width == parent.width - 20 + orientation: "Horizontal" + + delegate: Item { + width: 50; height: 50 + id: delegateRoot + + Image { + id: image + source: modelData.icon + smooth: true + scale: 0.8 + transformOrigin: "Center" + } + + MouseRegion { + anchors.fill: parent + onClicked: { root.currentIndex = index } + } + + states: State { + name: "Selected" + when: delegateRoot.ListView.isCurrentItem == true + PropertyChanges { + target: image + scale: 1 + y: -5 + } + } + transitions: Transition { + NumberAnimation { + properties: "scale,y" + } + } + } + model: visualModel.children - Item { - id: flickArea - width: childrenRect.width + Rectangle { + color: "#40FFFFFF" + x: -10; + y: -10; + width: parent.width + 20; height: parent.height + 10 } } } diff --git a/examples/declarative/parallax/parallax.qml b/examples/declarative/parallax/parallax.qml index 9adcfd7..52bd210 100644 --- a/examples/declarative/parallax/parallax.qml +++ b/examples/declarative/parallax/parallax.qml @@ -2,45 +2,54 @@ import Qt 4.6 import "../clock" Rectangle { + id: root + width: 320 height: 480 ParallaxView { + id: parallax anchors.fill: parent background: "pics/background.jpg" - Row { - Item { - width: 320 - height: 480 + Item { + property url icon: "pics/yast-wol.png" + width: 320 + height: 480 - Clock { - anchors.centerIn: parent - } + Clock { + anchors.centerIn: parent } + } - Item { - width: 320 - height: 480 + Item { + property url icon: "pics/home-page.svg" - Smiley {} - } + width: 320 + height: 480 - Item { - width: 320 - height: 480 - - Loader { - anchors.centerIn: parent - width: 300; height: 460 - clip: true - resizeMode: Loader.SizeItemToLoader - - source: "../../../demos/declarative/samegame/samegame.qml" - } - } + Smiley {} + } + + Item { + property url icon: "pics/yast-joystick.png" + width: 320 + height: 480 + + Loader { + anchors.top: parent.top + anchors.topMargin: 10 + anchors.horizontalCenter: parent.horizontalCenter + + width: 300; height: 400 + clip: true + resizeMode: Loader.SizeItemToLoader + + source: "../../../demos/declarative/samegame/samegame.qml" + } } - } + currentIndex: root.currentIndex + } } diff --git a/examples/declarative/parallax/pics/home-page.svg b/examples/declarative/parallax/pics/home-page.svg new file mode 100644 index 0000000..4f16958 --- /dev/null +++ b/examples/declarative/parallax/pics/home-page.svg @@ -0,0 +1,445 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="48" + height="48" + overflow="visible" + enable-background="new 0 0 128 129.396" + xml:space="preserve" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.46" + sodipodi:docname="go-home.svg" + sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions" + version="1.0" + inkscape:export-filename="/home/tigert/My Downloads/go-home.png" + inkscape:export-xdpi="90.000000" + inkscape:export-ydpi="90.000000" + inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata + id="metadata367"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><cc:license + rdf:resource="http://creativecommons.org/licenses/publicdomain/" /><dc:title>Go Home</dc:title><dc:creator><cc:Agent><dc:title>Jakub Steiner</dc:title></cc:Agent></dc:creator><dc:source>http://jimmac.musichall.cz</dc:source><dc:subject><rdf:Bag><rdf:li>home</rdf:li><rdf:li>return</rdf:li><rdf:li>go</rdf:li><rdf:li>default</rdf:li><rdf:li>user</rdf:li><rdf:li>directory</rdf:li></rdf:Bag></dc:subject><dc:contributor><cc:Agent><dc:title>Tuomas Kuosmanen</dc:title></cc:Agent></dc:contributor></cc:Work><cc:License + rdf:about="http://creativecommons.org/licenses/publicdomain/"><cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /></cc:License></rdf:RDF></metadata><defs + id="defs365"><inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 24 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="48 : 24 : 1" + inkscape:persp3d-origin="24 : 16 : 1" + id="perspective92" /><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient5031" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)" + cx="605.71429" + cy="486.64789" + fx="605.71429" + fy="486.64789" + r="117.14286" /><linearGradient + inkscape:collect="always" + id="linearGradient5060"><stop + style="stop-color:black;stop-opacity:1;" + offset="0" + id="stop5062" /><stop + style="stop-color:black;stop-opacity:0;" + offset="1" + id="stop5064" /></linearGradient><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5060" + id="radialGradient5029" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)" + cx="605.71429" + cy="486.64789" + fx="605.71429" + fy="486.64789" + r="117.14286" /><linearGradient + id="linearGradient5048"><stop + style="stop-color:black;stop-opacity:0;" + offset="0" + id="stop5050" /><stop + id="stop5056" + offset="0.5" + style="stop-color:black;stop-opacity:1;" /><stop + style="stop-color:black;stop-opacity:0;" + offset="1" + id="stop5052" /></linearGradient><linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5048" + id="linearGradient5027" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)" + x1="302.85715" + y1="366.64789" + x2="302.85715" + y2="609.50507" /><linearGradient + id="linearGradient2406"><stop + style="stop-color:#7c7e79;stop-opacity:1;" + offset="0" + id="stop2408" /><stop + id="stop2414" + offset="0.1724138" + style="stop-color:#848681;stop-opacity:1;" /><stop + style="stop-color:#898c86;stop-opacity:1;" + offset="1" + id="stop2410" /></linearGradient><linearGradient + inkscape:collect="always" + id="linearGradient2390"><stop + style="stop-color:#919191;stop-opacity:1;" + offset="0" + id="stop2392" /><stop + style="stop-color:#919191;stop-opacity:0;" + offset="1" + id="stop2394" /></linearGradient><linearGradient + inkscape:collect="always" + id="linearGradient2378"><stop + style="stop-color:#575757;stop-opacity:1;" + offset="0" + id="stop2380" /><stop + style="stop-color:#575757;stop-opacity:0;" + offset="1" + id="stop2382" /></linearGradient><linearGradient + inkscape:collect="always" + id="linearGradient2368"><stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop2370" /><stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop2372" /></linearGradient><linearGradient + inkscape:collect="always" + id="linearGradient2349"><stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop2351" /><stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop2353" /></linearGradient><linearGradient + id="linearGradient2341"><stop + id="stop2343" + offset="0" + style="stop-color:#000000;stop-opacity:1;" /><stop + id="stop2345" + offset="1" + style="stop-color:#000000;stop-opacity:0;" /></linearGradient><linearGradient + id="linearGradient2329"><stop + style="stop-color:#000000;stop-opacity:0.18556701;" + offset="0" + id="stop2331" /><stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop2333" /></linearGradient><linearGradient + inkscape:collect="always" + id="linearGradient2319"><stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop2321" /><stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop2323" /></linearGradient><linearGradient + id="linearGradient2307"><stop + style="stop-color:#edd400;stop-opacity:1;" + offset="0" + id="stop2309" /><stop + style="stop-color:#998800;stop-opacity:1;" + offset="1" + id="stop2311" /></linearGradient><linearGradient + inkscape:collect="always" + id="linearGradient2299"><stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop2301" /><stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop2303" /></linearGradient><linearGradient + id="XMLID_2_" + gradientUnits="userSpaceOnUse" + x1="80.223602" + y1="117.5205" + x2="48.046001" + y2="59.7995" + gradientTransform="matrix(0.314683,0.000000,0.000000,0.314683,4.128264,3.742874)"> + <stop + offset="0" + style="stop-color:#CCCCCC" + id="stop17" /> + <stop + offset="0.9831" + style="stop-color:#FFFFFF" + id="stop19" /> + <midPointStop + offset="0" + style="stop-color:#CCCCCC" + id="midPointStop48" /> + <midPointStop + offset="0.5" + style="stop-color:#CCCCCC" + id="midPointStop50" /> + <midPointStop + offset="0.9831" + style="stop-color:#FFFFFF" + id="midPointStop52" /> + </linearGradient><linearGradient + inkscape:collect="always" + xlink:href="#XMLID_2_" + id="linearGradient1514" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.336922,0.000000,0.000000,0.166888,17.98288,15.46151)" + x1="52.006104" + y1="166.1331" + x2="14.049017" + y2="-42.218513" /><linearGradient + id="XMLID_39_" + gradientUnits="userSpaceOnUse" + x1="64.387703" + y1="65.124001" + x2="64.387703" + y2="35.569" + gradientTransform="matrix(0.354101,0.000000,0.000000,0.354101,1.638679,-8.364921e-2)"> + <stop + offset="0" + style="stop-color:#FFFFFF" + id="stop336" /> + <stop + offset="0.8539" + style="stop-color:#FF6200" + id="stop338" /> + <stop + offset="1" + style="stop-color:#F25D00" + id="stop340" /> + <midPointStop + offset="0" + style="stop-color:#FFFFFF" + id="midPointStop335" /> + <midPointStop + offset="0.5" + style="stop-color:#FFFFFF" + id="midPointStop337" /> + <midPointStop + offset="0.8539" + style="stop-color:#FF6200" + id="midPointStop339" /> + <midPointStop + offset="0.5" + style="stop-color:#FF6200" + id="midPointStop341" /> + <midPointStop + offset="1" + style="stop-color:#F25D00" + id="midPointStop343" /> + </linearGradient><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2299" + id="radialGradient2305" + cx="7.5326638" + cy="24.202574" + fx="7.5326638" + fy="24.202574" + r="8.2452128" + gradientTransform="matrix(4.100086,-1.627292e-17,2.125447e-14,4.201322,-25.41506,-78.53967)" + gradientUnits="userSpaceOnUse" /><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2307" + id="radialGradient2313" + cx="19.985598" + cy="36.77816" + fx="19.985598" + fy="36.77816" + r="1.0821035" + gradientTransform="matrix(1.125263,0.000000,0.000000,0.982744,-3.428678,0.565787)" + gradientUnits="userSpaceOnUse" /><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2319" + id="radialGradient2325" + cx="20.443665" + cy="37.425829" + fx="20.443665" + fy="37.425829" + r="1.0821035" + gradientTransform="matrix(1.125263,0.000000,0.000000,0.982744,-3.428678,0.731106)" + gradientUnits="userSpaceOnUse" /><linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2329" + id="linearGradient2335" + x1="17.602522" + y1="26.057423" + x2="17.682528" + y2="32.654099" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.898789,0,0,1.071914,0.478025,-2.080838)" /><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2341" + id="radialGradient2339" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.100086,1.627292e-17,2.125447e-14,-4.201322,-5.198109,105.3535)" + cx="11.68129" + cy="19.554111" + fx="11.68129" + fy="19.554111" + r="8.2452126" /><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2349" + id="radialGradient2355" + cx="24.023088" + cy="40.56913" + fx="24.023088" + fy="40.56913" + r="16.28684" + gradientTransform="matrix(1.000000,0.000000,0.000000,0.431250,1.157278e-15,23.07369)" + gradientUnits="userSpaceOnUse" /><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2368" + id="radialGradient2374" + cx="29.913452" + cy="30.442923" + fx="29.913452" + fy="30.442923" + r="4.0018832" + gradientTransform="matrix(3.751495,-2.191984e-22,1.723265e-22,3.147818,-82.00907,-65.70704)" + gradientUnits="userSpaceOnUse" /><radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2378" + id="radialGradient2384" + cx="24.195112" + cy="10.577631" + fx="24.195112" + fy="10.577631" + r="15.242914" + gradientTransform="matrix(1.125263,-3.585417e-8,4.269819e-8,1.340059,-3.006704,1.355395)" + gradientUnits="userSpaceOnUse" /><linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2390" + id="linearGradient2396" + x1="30.603519" + y1="37.337803" + x2="30.603519" + y2="36.112415" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.263867,0,0,0.859794,-6.499556,8.390924)" /><linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2406" + id="linearGradient2412" + x1="17.850183" + y1="28.939463" + x2="19.040216" + y2="41.03223" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.888785,0,0,1.08932,2.41099,-1.524336)" /></defs><sodipodi:namedview + inkscape:cy="-2.3755359" + inkscape:cx="25.234802" + inkscape:zoom="1" + inkscape:window-height="691" + inkscape:window-width="872" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + borderopacity="0.21568627" + bordercolor="#666666" + pagecolor="#ffffff" + id="base" + inkscape:showpageshadow="false" + inkscape:window-x="466" + inkscape:window-y="157" + inkscape:current-layer="svg2" + fill="#555753" + showgrid="false" + stroke="#a40000" + showguides="true" + inkscape:guide-bbox="true" /> + <g + style="display:inline" + id="g5022" + transform="matrix(2.158196e-2,0,0,1.859457e-2,43.12251,41.63767)"><rect + y="-150.69685" + x="-1559.2523" + height="478.35718" + width="1339.6335" + id="rect4173" + style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /><path + sodipodi:nodetypes="cccc" + id="path5058" + d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z " + style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /><path + style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z " + id="path5018" + sodipodi:nodetypes="cccc" /></g><path + style="color:#000000;fill:url(#linearGradient1514);fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.0000006;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + d="M 21.619576,8.1833733 L 27.577035,8.1833733 C 28.416767,8.1833733 41.46351,23.618701 41.46351,24.524032 L 41.019989,43.020777 C 41.019989,43.92611 40.343959,44.654954 39.504227,44.654954 L 8.0469496,44.654954 C 7.2072167,44.654954 6.5311871,43.92611 6.5311871,43.020777 L 6.5876651,24.524032 C 6.5876651,23.618701 20.779844,8.1833733 21.619576,8.1833733 z " + id="rect1512" + sodipodi:nodetypes="ccccccccc" /><path + style="fill:none" + id="path5" + d="M 46.963575,45.735573 L 1.6386762,45.735573 L 1.6386762,0.41067554 L 46.963575,0.41067554 L 46.963575,45.735573 z " /><path + style="fill:url(#linearGradient2335);fill-opacity:1;fill-rule:evenodd" + id="path2327" + d="M 23,29 L 22.954256,44.090942 L 11.111465,44.090942 L 11,29 L 23,29 z " + clip-rule="evenodd" + sodipodi:nodetypes="ccccc" /><path + sodipodi:nodetypes="ccccccccc" + id="path2357" + d="M 21.780459,9.405584 L 27.339556,9.405584 C 28.123138,9.405584 40.340425,23.805172 40.340425,24.649756 L 39.993267,42.862067 C 39.993267,43.321326 39.84953,43.515532 39.480892,43.515532 L 8.0936894,43.529812 C 7.7250517,43.529812 7.5097258,43.449894 7.5097258,43.076262 L 7.7250676,24.649756 C 7.7250676,23.805172 20.99688,9.405584 21.780459,9.405584 z " + style="opacity:0.3125;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /><path + clip-rule="evenodd" + d="M 7.2075295,27.943053 L 7.1532728,30.538247 L 25.521437,17.358993 L 40.807832,28.513421 L 40.879142,28.201707 L 24.508686,12.297576 L 7.2075295,27.943053 z " + id="path23" + style="opacity:0.2;fill:url(#radialGradient2384);fill-opacity:1;fill-rule:evenodd" + sodipodi:nodetypes="ccccccc" /><path + clip-rule="evenodd" + d="M 22,30 L 22,44.090942 L 12.188971,44.090942 L 12,30 L 22,30 z " + id="path188" + style="fill:url(#linearGradient2412);fill-opacity:1;fill-rule:evenodd" + sodipodi:nodetypes="ccccc" /><path + style="opacity:0.40909089;fill:url(#radialGradient2325);fill-opacity:1;fill-rule:evenodd" + id="path2315" + d="M 19.576856,36.44767 C 20.249646,36.44767 20.793472,36.922275 20.793472,37.506177 C 20.793472,38.095988 20.249646,38.574532 19.576856,38.574532 C 18.904584,38.574532 18.35817,38.095988 18.35817,37.506177 C 18.358685,36.922275 18.904584,36.44767 19.576856,36.44767 z " + clip-rule="evenodd" /><path + clip-rule="evenodd" + d="M 19.462314,35.932229 C 20.135103,35.932229 20.678929,36.406834 20.678929,36.990736 C 20.678929,37.580545 20.135103,38.059089 19.462314,38.059089 C 18.790041,38.059089 18.243627,37.580545 18.243627,36.990736 C 18.244142,36.406834 18.790041,35.932229 19.462314,35.932229 z " + id="path217" + style="fill:url(#radialGradient2313);fill-opacity:1;fill-rule:evenodd" /><path + d="M 24.447748,11.559337 L 43.374808,28.729205 L 43.869487,29.121196 L 44.273163,28.949811 L 43.900293,28.188138 L 43.622679,27.964702 L 24.447748,12.392396 L 5.0582327,28.135731 L 4.8206309,28.279851 L 4.603921,28.986637 L 5.0373408,29.115885 L 5.4218948,28.807462 L 24.447748,11.559337 z " + id="path342" + style="fill:url(#XMLID_39_)" + sodipodi:nodetypes="ccccccccccccc" /><path + style="fill:#ef2929;stroke:#a40000" + id="path362" + d="M 24.330168,2.2713382 L 2.4484294,20.372675 L 1.8237005,27.538603 L 3.8236367,29.602926 C 3.8236367,29.602926 24.231018,12.445641 24.44773,12.274963 L 44.08027,29.818223 L 45.978694,27.494226 L 44.362903,20.382852 L 24.44773,2.1668788 L 24.330168,2.2713382 z " + sodipodi:nodetypes="cccccccccc" /> +<path + style="opacity:0.40909089;color:#000000;fill:url(#radialGradient2305);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + d="M 2.8413446,20.613129 L 2.5497894,27.236494 L 24.369219,8.980075 L 24.298891,3.0867443 L 2.8413446,20.613129 z " + id="path1536" + sodipodi:nodetypes="ccccc" /><path + sodipodi:nodetypes="ccccc" + id="path2337" + d="M 24.483763,8.7509884 L 24.583223,2.9098867 L 43.912186,20.56184 L 45.403998,27.062652 L 24.483763,8.7509884 z " + style="opacity:0.13636367;color:#000000;fill:url(#radialGradient2339);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /><path + style="opacity:0.31818183;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999934;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + d="M 27.102228,27.719824 L 36.142223,27.719824 C 36.912818,27.719824 37.53319,28.340194 37.53319,29.110791 L 37.525229,38.190012 C 37.525229,38.960608 36.928907,39.455981 36.158311,39.455981 L 27.102228,39.455981 C 26.331631,39.455981 25.711261,38.835608 25.711261,38.065012 L 25.711261,29.110791 C 25.711261,28.340194 26.331631,27.719824 27.102228,27.719824 z " + id="rect2361" + sodipodi:nodetypes="ccccccccc" /><rect + style="opacity:1;color:#000000;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + id="rect3263" + width="10.001333" + height="9.9624557" + x="26.507767" + y="28.514256" + rx="0.38128215" + ry="0.38128215" /><path + style="opacity:0.39772728;color:#000000;fill:url(#radialGradient2374);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999958;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + d="M 27.107118,34.408261 C 30.725101,34.739438 32.634842,32.962557 35.97527,32.855521 L 36,29.00603 L 27.088388,29 L 27.107118,34.408261 z " + id="rect2363" + sodipodi:nodetypes="ccccc" /></svg>
\ No newline at end of file diff --git a/examples/declarative/parallax/pics/yast-joystick.png b/examples/declarative/parallax/pics/yast-joystick.png Binary files differnew file mode 100644 index 0000000..858cea0 --- /dev/null +++ b/examples/declarative/parallax/pics/yast-joystick.png diff --git a/examples/declarative/parallax/pics/yast-wol.png b/examples/declarative/parallax/pics/yast-wol.png Binary files differnew file mode 100644 index 0000000..7712180 --- /dev/null +++ b/examples/declarative/parallax/pics/yast-wol.png diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index a83ee66..cbfe9f6 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -618,11 +618,18 @@ void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) newY = minY + (newY - minY) / 2; if (newY < maxY && maxY - minY < 0) newY = maxY + (newY - maxY) / 2; - if (q->overShoot() || (newY <= minY && newY >= maxY)) { + if (!q->overShoot() && (newY > minY || newY < maxY)) { + if (newY > minY) + newY = minY; + else if (newY < maxY) + newY = maxY; + else + rejectY = true; + } + if (!rejectY) { _moveY.setValue(newY); moved = true; - } else if (!q->overShoot()) - rejectY = true; + } if (qAbs(dy) > DragThreshold) stealMouse = true; } @@ -638,11 +645,19 @@ void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) newX = minX + (newX - minX) / 2; if (newX < maxX && maxX - minX < 0) newX = maxX + (newX - maxX) / 2; - if (q->overShoot() || (newX <= minX && newX >= maxX)) { + if (!q->overShoot() && (newX > minX || newX < maxX)) { + if (newX > minX) + newX = minX; + else if (newX < maxX) + newX = maxX; + else + rejectX = true; + } + if (!rejectX) { _moveX.setValue(newX); moved = true; - } else if (!q->overShoot()) - rejectX = true; + } + if (qAbs(dx) > DragThreshold) stealMouse = true; } diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 1a4a60c..28d2bb2 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -176,9 +176,9 @@ public: , highlightRangeStart(0), highlightRangeEnd(0) , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightPosAnimator(0), highlightSizeAnimator(0), spacing(0.0) - , highlightMoveSpeed(400), highlightResizeSpeed(400) + , highlightMoveSpeed(400), highlightResizeSpeed(400), highlightRange(QFxListView::NoHighlightRange) , ownModel(false), wrap(false), autoHighlight(true) - , haveHighlightRange(false), strictHighlightRange(false) + , haveHighlightRange(false) {} void init(); @@ -392,12 +392,12 @@ public: qreal spacing; qreal highlightMoveSpeed; qreal highlightResizeSpeed; + QFxListView::HighlightRangeMode highlightRange; bool ownModel : 1; bool wrap : 1; bool autoHighlight : 1; bool haveHighlightRange : 1; - bool strictHighlightRange : 1; }; void QFxListViewPrivate::init() @@ -798,7 +798,7 @@ void QFxListViewPrivate::fixupY() if (orient == Qt::Horizontal) return; - if (haveHighlightRange && strictHighlightRange) { + if (haveHighlightRange && highlightRange == QFxListView::StrictlyEnforceRange) { if (currentItem && highlight && currentItem->position() != highlight->position()) { moveReason = Mouse; timeline.clear(); @@ -813,7 +813,7 @@ void QFxListViewPrivate::fixupX() if (orient == Qt::Vertical) return; - if (haveHighlightRange && strictHighlightRange) { + if (haveHighlightRange && highlightRange == QFxListView::StrictlyEnforceRange) { if (currentItem && highlight && currentItem->position() != highlight->position()) { moveReason = Mouse; timeline.clear(); @@ -1141,19 +1141,25 @@ void QFxListView::setHighlightFollowsCurrentItem(bool autoHighlight) /*! \qmlproperty real ListView::preferredHighlightBegin \qmlproperty real ListView::preferredHighlightEnd - \qmlproperty bool ListView::strictlyEnforceHighlightRange + \qmlproperty bool ListView::highlightRangeMode These properties set the preferred range of the highlight (current item) within the view. - If the strictlyEnforceHighlightRange property is false (default) + If highlightRangeMode is set to \e ApplyRange the view will + attempt to maintain the highlight within the range, however the highlight can move outside of the range at the ends of the list or due to a mouse interaction. - If strictlyEnforceHighlightRange is true then the highlight will never - move outside the range. This means that the current item will change + If highlightRangeMode is set to \e StrictlyEnforceRange the highlight will never + move outside of the range. This means that the current item will change if a keyboard or mouse action would cause the highlight to move outside of the range. + + The default value is \e NoHighlightRange. + + Note that a valid range requires preferredHighlightEnd to be greater + than or equal to preferredHighlightBegin. */ qreal QFxListView::preferredHighlightBegin() const { @@ -1165,7 +1171,7 @@ void QFxListView::setPreferredHighlightBegin(qreal start) { Q_D(QFxListView); d->highlightRangeStart = start; - d->haveHighlightRange = d->highlightRangeStart < d->highlightRangeEnd; + d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; } qreal QFxListView::preferredHighlightEnd() const @@ -1178,19 +1184,20 @@ void QFxListView::setPreferredHighlightEnd(qreal end) { Q_D(QFxListView); d->highlightRangeEnd = end; - d->haveHighlightRange = d->highlightRangeStart < d->highlightRangeEnd; + d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; } -bool QFxListView::strictlyEnforceHighlightRange() const +QFxListView::HighlightRangeMode QFxListView::highlightRangeMode() const { Q_D(const QFxListView); - return d->strictHighlightRange; + return d->highlightRange; } -void QFxListView::setStrictlyEnforceHighlightRange(bool strict) +void QFxListView::setHighlightRangeMode(HighlightRangeMode mode) { Q_D(QFxListView); - d->strictHighlightRange = strict; + d->highlightRange = mode; + d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; } /*! @@ -1375,14 +1382,14 @@ void QFxListView::viewportMoved() if (isFlicking() || d->pressed) d->moveReason = QFxListViewPrivate::Mouse; if (d->moveReason == QFxListViewPrivate::Mouse) { - if (d->haveHighlightRange && d->strictHighlightRange && d->highlight) { + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { int idx = d->snapIndex(); if (idx >= 0 && idx != d->currentIndex) d->updateCurrent(idx); qreal pos = d->currentItem->position(); - if (pos > d->position() + d->highlightRangeEnd - d->highlight->size()) - pos = d->position() + d->highlightRangeEnd - d->highlight->size(); + if (pos > d->position() + d->highlightRangeEnd - 1 - d->highlight->size()) + pos = d->position() + d->highlightRangeEnd - 1 - d->highlight->size(); if (pos < d->position() + d->highlightRangeStart) pos = d->position() + d->highlightRangeStart; d->highlight->setPosition(pos); @@ -1396,7 +1403,7 @@ qreal QFxListView::minYExtent() const if (d->orient == Qt::Horizontal) return QFxFlickable::minYExtent(); qreal extent = -d->startPosition(); - if (d->haveHighlightRange && d->strictHighlightRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) extent += d->highlightRangeStart; return extent; @@ -1408,8 +1415,8 @@ qreal QFxListView::maxYExtent() const if (d->orient == Qt::Horizontal) return QFxFlickable::maxYExtent(); qreal extent; - if (d->haveHighlightRange && d->strictHighlightRange) - extent = -(d->endPosition() - d->highlightRangeEnd); + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + extent = -(d->positionAt(count()-1) - d->highlightRangeEnd); else extent = -(d->endPosition() - height()); qreal minY = minYExtent(); @@ -1424,7 +1431,7 @@ qreal QFxListView::minXExtent() const if (d->orient == Qt::Vertical) return QFxFlickable::minXExtent(); qreal extent = -d->startPosition(); - if (d->haveHighlightRange && d->strictHighlightRange) + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) extent += d->highlightRangeStart; return extent; @@ -1436,8 +1443,8 @@ qreal QFxListView::maxXExtent() const if (d->orient == Qt::Vertical) return QFxFlickable::maxXExtent(); qreal extent; - if (d->haveHighlightRange && d->strictHighlightRange) - extent = -(d->endPosition() - d->highlightRangeEnd); + if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) + extent = -(d->positionAt(count()-1) - d->highlightRangeEnd); else extent = -(d->endPosition() - width()); qreal minX = minXExtent(); @@ -1536,7 +1543,7 @@ void QFxListView::trackedPositionChanged() if (!isFlicking() && !d->pressed && d->moveReason != QFxListViewPrivate::Mouse) { const qreal trackedPos = d->trackedItem->position(); if (d->haveHighlightRange) { - if (d->strictHighlightRange) { + if (d->highlightRange == StrictlyEnforceRange) { qreal pos = d->position(); if (trackedPos > pos + d->highlightRangeEnd - d->trackedItem->size()) pos = trackedPos - d->highlightRangeEnd + d->trackedItem->size(); diff --git a/src/declarative/fx/qfxlistview.h b/src/declarative/fx/qfxlistview.h index 1ff0e27..0fa0fa0 100644 --- a/src/declarative/fx/qfxlistview.h +++ b/src/declarative/fx/qfxlistview.h @@ -69,7 +69,7 @@ class Q_DECLARATIVE_EXPORT QFxListView : public QFxFlickable Q_PROPERTY(qreal preferredHighlightBegin READ preferredHighlightBegin WRITE setPreferredHighlightBegin) Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd) - Q_PROPERTY(bool strictlyEnforceHighlightRange READ strictlyEnforceHighlightRange WRITE setStrictlyEnforceHighlightRange) + Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode) Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged) @@ -80,6 +80,7 @@ class Q_DECLARATIVE_EXPORT QFxListView : public QFxFlickable Q_PROPERTY(qreal highlightMoveSpeed READ highlightMoveSpeed WRITE setHighlightMoveSpeed NOTIFY highlightMoveSpeedChanged) Q_PROPERTY(qreal highlightResizeSpeed READ highlightResizeSpeed WRITE setHighlightResizeSpeed NOTIFY highlightResizeSpeedChanged) + Q_ENUMS(HighlightRangeMode) Q_CLASSINFO("DefaultProperty", "data") public: @@ -104,8 +105,9 @@ public: bool highlightFollowsCurrentItem() const; void setHighlightFollowsCurrentItem(bool); - bool strictlyEnforceHighlightRange() const; - void setStrictlyEnforceHighlightRange(bool strict); + enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange }; + HighlightRangeMode highlightRangeMode() const; + void setHighlightRangeMode(HighlightRangeMode mode); qreal preferredHighlightBegin() const; void setPreferredHighlightBegin(qreal); diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp index e1ac246..7ee6eea 100644 --- a/src/declarative/fx/qfxvisualitemmodel.cpp +++ b/src/declarative/fx/qfxvisualitemmodel.cpp @@ -123,6 +123,10 @@ public: emit q->countChanged(); } + void emitChildrenChanged() { + Q_Q(QFxVisualItemModel); + emit q->childrenChanged(); + } ItemList children; }; @@ -224,6 +228,8 @@ void QFxVisualItemModelPrivate::ItemList::append(QFxItem *item) QmlConcreteList<QFxItem*>::append(item); item->QObject::setParent(model->q_ptr); model->itemAppended(); + + model->emitChildrenChanged(); } QFxVisualItemModelAttached *QFxVisualItemModel::qmlAttachedProperties(QObject *obj) diff --git a/src/declarative/fx/qfxvisualitemmodel.h b/src/declarative/fx/qfxvisualitemmodel.h index 5b613d8..8e33279 100644 --- a/src/declarative/fx/qfxvisualitemmodel.h +++ b/src/declarative/fx/qfxvisualitemmodel.h @@ -108,7 +108,7 @@ class Q_DECLARATIVE_EXPORT QFxVisualItemModel : public QFxVisualModel Q_OBJECT Q_DECLARE_PRIVATE(QFxVisualItemModel) - Q_PROPERTY(QmlList<QFxItem *>* children READ children DESIGNABLE false) + Q_PROPERTY(QmlList<QFxItem *>* children READ children NOTIFY childrenChanged DESIGNABLE false) Q_CLASSINFO("DefaultProperty", "children") public: @@ -128,6 +128,9 @@ public: static QFxVisualItemModelAttached *qmlAttachedProperties(QObject *obj); +signals: + void childrenChanged(); + private: Q_DISABLE_COPY(QFxVisualItemModel) }; diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp index b7aac54..eba4307 100644 --- a/src/declarative/qml/qmlbasicscript.cpp +++ b/src/declarative/qml/qmlbasicscript.cpp @@ -658,7 +658,7 @@ QVariant QmlBasicScript::run(QmlContext *context, QObject *me) case ScriptInstruction::FetchRootConstant: { - QObject *obj = contextPrivate->defaultObjects.last(); + QObject *obj = contextPrivate->defaultObjects.at(0); stack.push(fetch_value(obj, instr.constant.idx, instr.constant.type)); if (obj && instr.constant.notify != 0) diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 69ebf9c..60282dc 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1687,7 +1687,7 @@ bool QmlCompiler::buildGroupedProperty(QmlParser::Property *prop, if (prop->type < (int)QVariant::UserType) { QmlEnginePrivate *ep = static_cast<QmlEnginePrivate *>(QObjectPrivate::get(engine)); - if (ep->valueTypes[prop->type]) { + if (prop->type >= 0 /* QVariant == -1 */ && ep->valueTypes[prop->type]) { COMPILE_CHECK(buildValueTypeProperty(ep->valueTypes[prop->type], prop->value, obj, ctxt.incr())); obj->addValueTypeProperty(prop); diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 7ba3544..2ebdf10 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -50,9 +50,6 @@ #include <private/qmlbindingoptimizations_p.h> #include <QtDeclarative/qmlinfo.h> -// 6-bits -#define MAXIMUM_DEFAULT_OBJECTS 63 - QT_BEGIN_NAMESPACE QmlContextPrivate::QmlContextPrivate() @@ -130,22 +127,6 @@ void QmlContextPrivate::init() parent->d_func()->childContexts.insert(q); } -void QmlContextPrivate::addDefaultObject(QObject *object, Priority priority) -{ - if (defaultObjects.count() >= (MAXIMUM_DEFAULT_OBJECTS - 1)) { - qWarning("QmlContext: Cannot have more than %d default objects on " - "one bind context.", MAXIMUM_DEFAULT_OBJECTS - 1); - return; - } - - if (priority == HighPriority) { - defaultObjects.insert(highPriorityCount++, object); - } else { - defaultObjects.append(object); - } -} - - /*! \class QmlContext \brief The QmlContext class defines a context within a QML engine. @@ -366,7 +347,7 @@ QmlContext *QmlContext::parentContext() const void QmlContext::addDefaultObject(QObject *defaultObject) { Q_D(QmlContext); - d->addDefaultObject(defaultObject, QmlContextPrivate::NormalPriority); + d->defaultObjects.prepend(defaultObject); } /*! diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index be7bf1d..6af5f64 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -104,12 +104,6 @@ public: void dump(); void dump(int depth); - enum Priority { - HighPriority, - NormalPriority - }; - void addDefaultObject(QObject *, Priority); - void invalidateEngines(); QSet<QmlContext *> childContexts; diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp index 4df23f0..a978df2 100644 --- a/src/declarative/qml/qmlcontextscriptclass.cpp +++ b/src/declarative/qml/qmlcontextscriptclass.cpp @@ -155,7 +155,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje } } - for (int ii = 0; ii < cp->defaultObjects.count(); ++ii) { + for (int ii = cp->defaultObjects.count() - 1; ii >= 0; --ii) { QScriptClass::QueryFlags rv = ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index ab3c23a..0e239ce 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -476,6 +476,8 @@ QmlEngine *qmlEngine(const QObject *obj) QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create) { QmlDeclarativeData *data = QmlDeclarativeData::get(object); + if (!data) + return 0; // Attached properties are only on objects created by QML QObject *rv = data->attachedProperties?data->attachedProperties->value(id):0; if (rv || !create) diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 3b89a23..c62756b 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -293,8 +293,7 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd QmlEnginePrivate *ep = QmlEnginePrivate::get(engine); if (secondaryScope) - ctxtPriv->defaultObjects.insert(ctxtPriv->highPriorityCount, - secondaryScope); + ctxtPriv->defaultObjects.append(secondaryScope); QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); @@ -328,8 +327,11 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUnd return QVariant(); } - if (secondaryScope) - ctxtPriv->defaultObjects.removeAt(ctxtPriv->highPriorityCount); + if (secondaryScope) { + QObject *last = ctxtPriv->defaultObjects.takeLast(); + Q_ASSERT(last == secondaryScope); + Q_UNUSED(last); + } QVariant rv; diff --git a/tests/auto/declarative/qmllanguage/data/alias.7.qml b/tests/auto/declarative/qmllanguage/data/alias.7.qml new file mode 100644 index 0000000..d3cf5fe --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/alias.7.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +Object { + property Object object + property alias aliasedObject: target.object + + object: Object { + id: target + + property Object object + object: Object {} + } +} + diff --git a/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.1.errors.txt b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.1.errors.txt new file mode 100644 index 0000000..7c00ce4 --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.1.errors.txt @@ -0,0 +1 @@ +5:5:Invalid property access diff --git a/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.1.qml b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.1.qml new file mode 100644 index 0000000..5e95c48 --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.1.qml @@ -0,0 +1,6 @@ +import Qt 4.6 + +Object { + property var o; + o.blah: 10 +} diff --git a/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.2.errors.txt b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.2.errors.txt new file mode 100644 index 0000000..7c00ce4 --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.2.errors.txt @@ -0,0 +1 @@ +5:5:Invalid property access diff --git a/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.2.qml b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.2.qml new file mode 100644 index 0000000..b11d34c --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/invalidGroupedProperty.2.qml @@ -0,0 +1,7 @@ +import Qt 4.6 + +Object { + property int o; + o.blah: 10 +} + diff --git a/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml new file mode 100644 index 0000000..99a9746 --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.1.qml @@ -0,0 +1,5 @@ +import Test 1.0 +import Qt 4.6 +Object { +} + diff --git a/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml new file mode 100644 index 0000000..8179dbd --- /dev/null +++ b/tests/auto/declarative/qmllanguage/data/qmlAttachedPropertiesObjectMethod.2.qml @@ -0,0 +1,6 @@ +import Test 1.0 +import Qt 4.6 +Object { + MyQmlObject.value: 10 +} + diff --git a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp index 1544312..78c66ad 100644 --- a/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp +++ b/tests/auto/declarative/qmllanguage/tst_qmllanguage.cpp @@ -79,6 +79,8 @@ private slots: void importsOrder_data(); void importsOrder(); + void qmlAttachedPropertiesObjectMethod(); + // regression tests for crashes void crash1(); @@ -185,7 +187,6 @@ void tst_qmllanguage::errors_data() QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false; QTest::newRow("invalidID.6") << "invalidID.6.qml" << "invalidID.6.errors.txt" << false; - QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false; QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true; QTest::newRow("fakeDotProperty") << "fakeDotProperty.qml" << "fakeDotProperty.errors.txt" << false; @@ -196,12 +197,16 @@ void tst_qmllanguage::errors_data() QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false; QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false; QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false; + QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false; + QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false; + QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false; QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false; QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false; QTest::newRow("importVersionMissing (installed)") << "importVersionMissingInstalled.qml" << "importVersionMissingInstalled.errors.txt" << false; - QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false; + + } void tst_qmllanguage::errors() @@ -695,6 +700,33 @@ void tst_qmllanguage::aliasProperties() QCOMPARE(object->property("a").toInt(), 1923); } + + // Ptr Alias Cleanup - check that aliases to ptr types return 0 + // if the object aliased to is removed + { + QmlComponent component(&engine, TEST_FILE("alias.7.qml")); + VERIFY_ERRORS(0); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QObject *object1 = qvariant_cast<QObject *>(object->property("object")); + QVERIFY(object1 != 0); + QObject *object2 = qvariant_cast<QObject *>(object1->property("object")); + QVERIFY(object2 != 0); + + QObject *alias = qvariant_cast<QObject *>(object->property("aliasedObject")); + QVERIFY(alias == object2); + + delete object1; + + QObject *alias2 = object; // "Random" start value + int status = -1; + void *a[] = { &alias2, 0, &status }; + QMetaObject::metacall(object, QMetaObject::ReadProperty, + object->metaObject()->indexOfProperty("aliasedObject"), a); + QVERIFY(alias2 == 0); + } } // Test that the root element in a composite type can be a Component @@ -1037,6 +1069,34 @@ void tst_qmllanguage::importsOrder() testType(qml,type); } +void tst_qmllanguage::qmlAttachedPropertiesObjectMethod() +{ + QObject object; + + QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0); + QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0); + + { + QmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.1.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(object, false), (QObject *)0); + QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0); + } + + { + QmlComponent component(&engine, TEST_FILE("qmlAttachedPropertiesObjectMethod.2.qml")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, false) != 0); + QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(object, true) != 0); + } +} + void tst_qmllanguage::crash1() { QmlComponent component(&engine, "Component {}"); diff --git a/tools/qmldebugger/canvasframerate.h b/tools/qmldebugger/canvasframerate.h deleted file mode 100644 index aa275aa..0000000 --- a/tools/qmldebugger/canvasframerate.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CANVASFRAMERATE_H -#define CANVASFRAMERATE_H - -#include <QWidget> - -QT_BEGIN_NAMESPACE - -class QmlDebugConnection; -class QTabWidget; -class QSpinBox; -class CanvasFrameRate : public QWidget -{ - Q_OBJECT -public: - CanvasFrameRate(QmlDebugConnection *, QWidget *parent = 0); - - void setSizeHint(const QSize &); - virtual QSize sizeHint() const; - -private slots: - void newTab(); - void stateChanged(int); - -private: - QTabWidget *m_tabs; - QSpinBox *m_spin; - QObject *m_plugin; - QSize m_sizeHint; -}; - -QT_END_NAMESPACE - -#endif // CANVASFRAMERATE_H - diff --git a/tools/qmldebugger/creatorplugin/QmlInspector.pluginspec b/tools/qmldebugger/creatorplugin/QmlInspector.pluginspec new file mode 100644 index 0000000..cdba135 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/QmlInspector.pluginspec @@ -0,0 +1,28 @@ +<plugin name="QmlInspector" version="1.3.80" compatVersion="1.3.80"> + <vendor>Nokia Corporation</vendor> + <copyright>(C) 2008-2009 Nokia Corporation</copyright> + <license> +Commercial Usage + +Licensees holding valid Qt Commercial licenses may use this plugin in +accordance with the Qt Commercial License Agreement provided with the +Software or, alternatively, in accordance with the terms contained in +a written agreement between you and Nokia. + +GNU Lesser General Public License Usage + +Alternatively, this plugin may be used under the terms of the GNU Lesser +General Public License version 2.1 as published by the Free Software +Foundation. 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.</license> + <description>Qml support</description> + <url>http://qt.nokia.com</url> + <dependencyList> + <dependency name="QmlProjectManager" version="1.3.80"/> + <dependency name="ProjectExplorer" version="1.3.80"/> + <dependency name="CppTools" version="1.3.80"/> + <dependency name="CppEditor" version="1.3.80"/> + <dependency name="Help" version="1.3.80"/> + </dependencyList> +</plugin>
\ No newline at end of file diff --git a/tools/qmldebugger/creatorplugin/README b/tools/qmldebugger/creatorplugin/README new file mode 100644 index 0000000..e7e205e --- /dev/null +++ b/tools/qmldebugger/creatorplugin/README @@ -0,0 +1,5 @@ +To enable this project, qmldebugger.pro requires that these two environment +variables be defined: + +CREATOR_SRC_DIR -> source directory for Qt Creator +CREATOR_BUILD_DIR -> build directory for Qt Creator diff --git a/tools/qmldebugger/creatorplugin/creatorplugin.pro b/tools/qmldebugger/creatorplugin/creatorplugin.pro new file mode 100644 index 0000000..d191a37 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/creatorplugin.pro @@ -0,0 +1,29 @@ +TEMPLATE = lib +TARGET = QmlInspector + +INCLUDEPATH += . +DEPENDPATH += . + +include(../standalone/qmldebugger.pri) + +HEADERS += qmlinspectorplugin.h \ + qmlinspector.h \ + qmlinspectormode.h \ + inspectoroutputpane.h \ + runcontrol.h + +SOURCES += qmlinspectorplugin.cpp \ + qmlinspectormode.cpp \ + inspectoroutputpane.cpp \ + runcontrol.cpp + +OTHER_FILES += QmlInspector.pluginspec +RESOURCES += qmlinspector.qrc + +IDE_BUILD_TREE=$$(CREATOR_BUILD_DIR) + +include($$(CREATOR_SRC_DIR)/src/qtcreatorplugin.pri) +include($$(CREATOR_SRC_DIR)/src/plugins/projectexplorer/projectexplorer.pri) +include($$(CREATOR_SRC_DIR)/src/plugins/coreplugin/coreplugin.pri) +LIBS += -L$$(CREATOR_BUILD_DIR)/lib/qtcreator + diff --git a/tools/qmldebugger/creatorplugin/images/logo.png b/tools/qmldebugger/creatorplugin/images/logo.png Binary files differnew file mode 100644 index 0000000..5ac14a5 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/images/logo.png diff --git a/tools/qmldebugger/creatorplugin/inspectoroutputpane.cpp b/tools/qmldebugger/creatorplugin/inspectoroutputpane.cpp new file mode 100644 index 0000000..d3f9913 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/inspectoroutputpane.cpp @@ -0,0 +1,108 @@ +#include <QtGui/qtextedit.h> + +#include "inspectoroutputpane.h" + +InspectorOutputPane::InspectorOutputPane(QObject *parent) + : Core::IOutputPane(parent), + m_textEdit(new QTextEdit) +{ +} + +InspectorOutputPane::~InspectorOutputPane() +{ + delete m_textEdit; +} + +QWidget *InspectorOutputPane::outputWidget(QWidget *parent) +{ + Q_UNUSED(parent); + return m_textEdit; +} + +QList<QWidget*> InspectorOutputPane::toolBarWidgets() const +{ + return QList<QWidget *>(); +} + +QString InspectorOutputPane::name() const +{ + return tr("Inspector Output"); +} + +int InspectorOutputPane::priorityInStatusBar() const +{ + return 1; +} + +void InspectorOutputPane::clearContents() +{ + m_textEdit->clear(); +} + +void InspectorOutputPane::visibilityChanged(bool visible) +{ + Q_UNUSED(visible); +} + +void InspectorOutputPane::setFocus() +{ + m_textEdit->setFocus(); +} + +bool InspectorOutputPane::hasFocus() +{ + return m_textEdit->hasFocus(); +} + +bool InspectorOutputPane::canFocus() +{ + return true; +} + +bool InspectorOutputPane::canNavigate() +{ + return false; +} + +bool InspectorOutputPane::canNext() +{ + return false; +} + +bool InspectorOutputPane::canPrevious() +{ + return false; +} + +void InspectorOutputPane::goToNext() +{ +} + +void InspectorOutputPane::goToPrev() +{ +} + +void InspectorOutputPane::addOutput(RunControl *, const QString &text) +{ + m_textEdit->insertPlainText(text); + m_textEdit->moveCursor(QTextCursor::End); +} + +void InspectorOutputPane::addOutputInline(RunControl *, const QString &text) +{ + m_textEdit->insertPlainText(text); + m_textEdit->moveCursor(QTextCursor::End); +} + +void InspectorOutputPane::addErrorOutput(RunControl *, const QString &text) +{ + m_textEdit->append(text); + m_textEdit->moveCursor(QTextCursor::End); +} + +void InspectorOutputPane::addInspectorStatus(const QString &text) +{ + m_textEdit->append(text); + m_textEdit->moveCursor(QTextCursor::End); +} + diff --git a/tools/qmldebugger/creatorplugin/inspectoroutputpane.h b/tools/qmldebugger/creatorplugin/inspectoroutputpane.h new file mode 100644 index 0000000..60c648a --- /dev/null +++ b/tools/qmldebugger/creatorplugin/inspectoroutputpane.h @@ -0,0 +1,55 @@ +#ifndef INSPECTOROUTPUTPANE_H +#define INSPECTOROUTPUTPANE_H + +#include <QtCore/QObject> + +#include <coreplugin/ioutputpane.h> + + +QT_BEGIN_NAMESPACE + +class QTextEdit; + +class RunControl; + +class InspectorOutputPane : public Core::IOutputPane +{ + Q_OBJECT +public: + InspectorOutputPane(QObject *parent = 0); + virtual ~InspectorOutputPane(); + + virtual QWidget *outputWidget(QWidget *parent); + virtual QList<QWidget*> toolBarWidgets() const; + virtual QString name() const; + + virtual int priorityInStatusBar() const; + + virtual void clearContents(); + virtual void visibilityChanged(bool visible); + + virtual void setFocus(); + virtual bool hasFocus(); + virtual bool canFocus(); + + virtual bool canNavigate(); + virtual bool canNext(); + virtual bool canPrevious(); + virtual void goToNext(); + virtual void goToPrev(); + +public slots: + void addOutput(RunControl *, const QString &text); + void addOutputInline(RunControl *, const QString &text); + + void addErrorOutput(RunControl *, const QString &text); + void addInspectorStatus(const QString &text); + +private: + QTextEdit *m_textEdit; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/tools/qmldebugger/creatorplugin/qmlinspector.h b/tools/qmldebugger/creatorplugin/qmlinspector.h new file mode 100644 index 0000000..98b9cbe --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspector.h @@ -0,0 +1,25 @@ +#ifndef QMLINSPECTOR_H +#define QMLINSPECTOR_H + +#include <QString> + +namespace QmlInspector { + namespace Constants { + const char * const RUN = "QmlInspector.Run"; + const char * const STOP = "QmlInspector.Stop"; + + const char * const C_INSPECTOR = "QmlInspector"; + }; + + class StartParameters + { + public: + StartParameters() : port(0) {} + ~StartParameters() {} + + QString address; + quint16 port; + }; +}; + +#endif diff --git a/tools/qmldebugger/creatorplugin/qmlinspector.qrc b/tools/qmldebugger/creatorplugin/qmlinspector.qrc new file mode 100644 index 0000000..45e8dda --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspector.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/qmlinspector" > + <file>images/logo.png</file> + </qresource> +</RCC> + diff --git a/tools/qmldebugger/creatorplugin/qmlinspectormode.cpp b/tools/qmldebugger/creatorplugin/qmlinspectormode.cpp new file mode 100644 index 0000000..9367b19 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectormode.cpp @@ -0,0 +1,495 @@ +#include <QtCore/QStringList> +#include <QtCore/QtPlugin> +#include <QtCore/QDebug> + +#include <QtGui/qtoolbutton.h> +#include <QtGui/qtoolbar.h> +#include <QtGui/qboxlayout.h> +#include <QtGui/qlabel.h> +#include <QtGui/qdockwidget.h> +#include <QtGui/qaction.h> +#include <QtGui/qlineedit.h> +#include <QtGui/qlabel.h> +#include <QtGui/qspinbox.h> + +#include <coreplugin/basemode.h> +#include <coreplugin/findplaceholder.h> +#include <coreplugin/minisplitter.h> +#include <coreplugin/outputpane.h> +#include <coreplugin/rightpane.h> +#include <coreplugin/navigationwidget.h> +#include <coreplugin/icore.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/uniqueidmanager.h> + +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/actionmanager/actionmanager.h> + +#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/project.h> + +#include <utils/styledbar.h> +#include <utils/fancymainwindow.h> + +#include <QtDeclarative/qmldebug.h> +#include <QtDeclarative/qmldebugclient.h> + +#include "../standalone/objectpropertiesview.h" +#include "../standalone/objecttree.h" +#include "../standalone/watchtable.h" +#include "../standalone/canvasframerate.h" +#include "../standalone/expressionquerywidget.h" + +#include "qmlinspector.h" +#include "qmlinspectormode.h" + +QT_BEGIN_NAMESPACE + + +class EngineSpinBox : public QSpinBox +{ + Q_OBJECT +public: + struct EngineInfo + { + QString name; + int id; + }; + + EngineSpinBox(QWidget *parent = 0); + + void addEngine(int engine, const QString &name); + void clearEngines(); + +protected: + virtual QString textFromValue(int value) const; + virtual int valueFromText(const QString &text) const; + +private: + QList<EngineInfo> m_engines; +}; + +EngineSpinBox::EngineSpinBox(QWidget *parent) + : QSpinBox(parent) +{ + setEnabled(false); + setReadOnly(true); + setRange(0, 0); +} + +void EngineSpinBox::addEngine(int engine, const QString &name) +{ + EngineInfo info; + info.id = engine; + if (name.isEmpty()) + info.name = tr("Engine %1", "engine number").arg(engine); + else + info.name = name; + m_engines << info; + + setRange(0, m_engines.count()-1); +} + +void EngineSpinBox::clearEngines() +{ + m_engines.clear(); +} + +QString EngineSpinBox::textFromValue(int value) const +{ + for (int i=0; i<m_engines.count(); i++) { + if (m_engines[i].id == value) + return m_engines[i].name; + } + return QLatin1String("<None>"); +} + +int EngineSpinBox::valueFromText(const QString &text) const +{ + for (int i=0; i<m_engines.count(); i++) { + if (m_engines[i].name == text) + return m_engines[i].id; + } + return -1; +} + + +QmlInspectorMode::QmlInspectorMode(QObject *parent) + : Core::BaseMode(parent), + m_conn(0), + m_client(0), + m_engineQuery(0), + m_contextQuery(0) +{ + m_watchTableModel = new WatchTableModel(0, this); + + initActions(); + setWidget(createModeWindow()); + + setName(tr("QML Inspect")); + setIcon(QIcon(":/qmlinspector/images/logo.png")); + setUniqueModeName("QML_INSPECT_MODE"); +} + +quint16 QmlInspectorMode::viewerPort() const +{ + return m_portSpinBox->value(); +} + +void QmlInspectorMode::connectToViewer() +{ + if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState) + return; + + delete m_client; m_client = 0; + + if (m_conn) { + m_conn->disconnectFromHost(); + delete m_conn; + } + + m_conn = new QmlDebugConnection(this); + connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + SLOT(connectionStateChanged())); + connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)), + SLOT(connectionError())); + m_conn->connectToHost(m_addressEdit->text(), m_portSpinBox->value()); +} + +void QmlInspectorMode::disconnectFromViewer() +{ + m_conn->disconnectFromHost(); +} + +void QmlInspectorMode::connectionStateChanged() +{ + switch (m_conn->state()) { + default: + case QAbstractSocket::UnconnectedState: + emit statusMessage(tr("[Inspector] disconnected\n\n")); + m_addressEdit->setEnabled(true); + m_portSpinBox->setEnabled(true); + break; + case QAbstractSocket::HostLookupState: + emit statusMessage(tr("[Inspector] resolving host...")); + break; + case QAbstractSocket::ConnectingState: + emit statusMessage(tr("[Inspector] connecting to debug server...")); + break; + case QAbstractSocket::ConnectedState: + { + emit statusMessage(tr("[Inspector] connected\n")); + m_addressEdit->setEnabled(false); + m_portSpinBox->setEnabled(false); + + if (!m_client) { + m_client = new QmlEngineDebug(m_conn, this); + m_objectTreeWidget->setEngineDebug(m_client); + m_propertiesWidget->setEngineDebug(m_client); + m_watchTableModel->setEngineDebug(m_client); + m_expressionWidget->setEngineDebug(m_client); + } + + m_objectTreeWidget->clear(); + m_propertiesWidget->clear(); + m_expressionWidget->clear(); + m_watchTableModel->removeAllWatches(); + m_frameRateWidget->reset(m_conn); + + reloadEngines(); + break; + } + case QAbstractSocket::ClosingState: + emit statusMessage(tr("[Inspector] closing...")); + break; + } +} + +void QmlInspectorMode::connectionError() +{ + emit statusMessage(tr("[Inspector] error: (%1) %2", "%1=error code, %2=error message") + .arg(m_conn->error()).arg(m_conn->errorString())); +} + +void QmlInspectorMode::initActions() +{ + m_actions.startAction = new QAction(tr("Start Inspector"), this); + m_actions.startAction->setIcon(QIcon(ProjectExplorer::Constants::ICON_RUN)); + + m_actions.stopAction = new QAction(tr("Stop Inspector"), this); + m_actions.stopAction->setIcon(QIcon(ProjectExplorer::Constants::ICON_STOP)); + + Core::ICore *core = Core::ICore::instance(); + Core::ActionManager *am = core->actionManager(); + Core::UniqueIDManager *uidm = core->uniqueIDManager(); + + QList<int> context; + context << uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR); + + am->registerAction(m_actions.startAction, QmlInspector::Constants::RUN, context); + connect(m_actions.startAction, SIGNAL(triggered()), SIGNAL(startViewer())); + + am->registerAction(m_actions.stopAction, QmlInspector::Constants::STOP, context); + connect(m_actions.stopAction, SIGNAL(triggered()), SIGNAL(stopViewer())); +} + + +QToolButton *QmlInspectorMode::createToolButton(QAction *action) +{ + QToolButton *button = new QToolButton; + button->setDefaultAction(action); + return button; +} + +QWidget *QmlInspectorMode::createMainView() +{ + initWidgets(); + + Utils::FancyMainWindow *mainWindow = new Utils::FancyMainWindow; + mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + mainWindow->setDocumentMode(true); + + QBoxLayout *editorHolderLayout = new QVBoxLayout; + editorHolderLayout->setMargin(0); + editorHolderLayout->setSpacing(0); + + QWidget *editorAndFindWidget = new QWidget; + editorAndFindWidget->setLayout(editorHolderLayout); + editorHolderLayout->addWidget(new Core::EditorManagerPlaceHolder(this)); + editorHolderLayout->addWidget(new Core::FindToolBarPlaceHolder(editorAndFindWidget)); + + Utils::StyledBar *treeOptionBar = new Utils::StyledBar; + QHBoxLayout *treeOptionBarLayout = new QHBoxLayout(treeOptionBar); + treeOptionBarLayout->setContentsMargins(5, 0, 5, 0); + treeOptionBarLayout->setSpacing(5); + treeOptionBarLayout->addWidget(new QLabel(tr("QML engine:"))); + treeOptionBarLayout->addWidget(m_engineSpinBox); + + QWidget *treeWindow = new QWidget; + QVBoxLayout *treeWindowLayout = new QVBoxLayout(treeWindow); + treeWindowLayout->setMargin(0); + treeWindowLayout->setSpacing(0); + treeWindowLayout->addWidget(treeOptionBar); + treeWindowLayout->addWidget(m_objectTreeWidget); + + Core::MiniSplitter *documentAndTree = new Core::MiniSplitter; + documentAndTree->addWidget(editorAndFindWidget); + documentAndTree->addWidget(new Core::RightPanePlaceHolder(this)); + documentAndTree->addWidget(treeWindow); + documentAndTree->setStretchFactor(0, 2); + documentAndTree->setStretchFactor(1, 0); + documentAndTree->setStretchFactor(2, 0); + + Utils::StyledBar *configBar = new Utils::StyledBar; + configBar->setProperty("topBorder", true); + + QHBoxLayout *configBarLayout = new QHBoxLayout(configBar); + configBarLayout->setMargin(0); + configBarLayout->setSpacing(5); + + Core::ICore *core = Core::ICore::instance(); + Core::ActionManager *am = core->actionManager(); + configBarLayout->addWidget(createToolButton(am->command(QmlInspector::Constants::RUN)->action())); + configBarLayout->addWidget(createToolButton(am->command(QmlInspector::Constants::STOP)->action())); + configBarLayout->addWidget(m_addressEdit); + configBarLayout->addWidget(m_portSpinBox); + configBarLayout->addStretch(); + + QWidget *widgetAboveTabs = new QWidget; + QVBoxLayout *widgetAboveTabsLayout = new QVBoxLayout(widgetAboveTabs); + widgetAboveTabsLayout->setMargin(0); + widgetAboveTabsLayout->setSpacing(0); + widgetAboveTabsLayout->addWidget(documentAndTree); + widgetAboveTabsLayout->addWidget(configBar); + + Core::MiniSplitter *mainSplitter = new Core::MiniSplitter(Qt::Vertical); + mainSplitter->addWidget(widgetAboveTabs); + mainSplitter->addWidget(createBottomWindow()); + mainSplitter->setStretchFactor(0, 3); + mainSplitter->setStretchFactor(1, 1); + + QWidget *centralWidget = new QWidget; + QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget); + centralLayout->setMargin(0); + centralLayout->setSpacing(0); + centralLayout->addWidget(mainSplitter); + + mainWindow->setCentralWidget(centralWidget); + + return mainWindow; +} + +QWidget *QmlInspectorMode::createBottomWindow() +{ + Utils::FancyMainWindow *win = new Utils::FancyMainWindow; + win->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + win->setDocumentMode(true); + win->setTrackingEnabled(true); + + Core::MiniSplitter *leftSplitter = new Core::MiniSplitter(Qt::Vertical); + leftSplitter->addWidget(m_propertiesWidget); + leftSplitter->addWidget(m_expressionWidget); + leftSplitter->setStretchFactor(0, 2); + leftSplitter->setStretchFactor(1, 1); + + Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal); + propSplitter->addWidget(leftSplitter); + propSplitter->addWidget(m_watchTableView); + propSplitter->setStretchFactor(0, 2); + propSplitter->setStretchFactor(1, 1); + propSplitter->setWindowTitle(tr("Properties and Watchers")); + + QDockWidget *propertiesDock = win->addDockForWidget(propSplitter); + win->addDockWidget(Qt::TopDockWidgetArea, propertiesDock); + + QDockWidget *frameRateDock = win->addDockForWidget(m_frameRateWidget); + win->addDockWidget(Qt::TopDockWidgetArea, frameRateDock); + + // stack the dock widgets as tabs + win->tabifyDockWidget(frameRateDock, propertiesDock); + + return win; +} + +QWidget *QmlInspectorMode::createModeWindow() +{ + // right-side window with editor, output etc. + Core::MiniSplitter *mainWindowSplitter = new Core::MiniSplitter; + mainWindowSplitter->addWidget(createMainView()); + mainWindowSplitter->addWidget(new Core::OutputPanePlaceHolder(this)); + mainWindowSplitter->setStretchFactor(0, 10); + mainWindowSplitter->setStretchFactor(1, 0); + mainWindowSplitter->setOrientation(Qt::Vertical); + + // navigation + right-side window + Core::MiniSplitter *splitter = new Core::MiniSplitter; + splitter->addWidget(new Core::NavigationWidgetPlaceHolder(this)); + splitter->addWidget(mainWindowSplitter); + splitter->setStretchFactor(0, 0); + splitter->setStretchFactor(1, 1); + return splitter; +} + +void QmlInspectorMode::initWidgets() +{ + m_objectTreeWidget = new ObjectTree; + m_propertiesWidget = new ObjectPropertiesView; + m_watchTableView = new WatchTableView(m_watchTableModel); + m_frameRateWidget = new CanvasFrameRate; + m_expressionWidget = new ExpressionQueryWidget; + + // FancyMainWindow uses widgets' window titles for tab labels + m_objectTreeWidget->setWindowTitle(tr("Object Tree")); + m_frameRateWidget->setWindowTitle(tr("Frame rate")); + + m_watchTableView->setModel(m_watchTableModel); + WatchTableHeaderView *header = new WatchTableHeaderView(m_watchTableModel); + m_watchTableView->setHorizontalHeader(header); + + connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QmlDebugObjectReference)), + m_propertiesWidget, SLOT(reload(QmlDebugObjectReference))); + connect(m_objectTreeWidget, SIGNAL(expressionWatchRequested(QmlDebugObjectReference,QString)), + m_watchTableModel, SLOT(expressionWatchRequested(QmlDebugObjectReference,QString))); + + connect(m_propertiesWidget, SIGNAL(activated(QmlDebugObjectReference,QmlDebugPropertyReference)), + m_watchTableModel, SLOT(togglePropertyWatch(QmlDebugObjectReference,QmlDebugPropertyReference))); + + connect(m_watchTableModel, SIGNAL(watchCreated(QmlDebugWatch*)), + m_propertiesWidget, SLOT(watchCreated(QmlDebugWatch*))); + + connect(m_watchTableModel, SIGNAL(rowsInserted(QModelIndex,int,int)), + m_watchTableView, SLOT(scrollToBottom())); + + connect(m_watchTableView, SIGNAL(objectActivated(int)), + m_objectTreeWidget, SLOT(setCurrentObject(int))); + + connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QmlDebugObjectReference)), + m_expressionWidget, SLOT(setCurrentObject(QmlDebugObjectReference))); + + m_addressEdit = new QLineEdit; + m_addressEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + m_addressEdit->setText("127.0.0.1"); + + m_portSpinBox = new QSpinBox; + m_portSpinBox->setMinimum(1024); + m_portSpinBox->setMaximum(20000); + m_portSpinBox->setValue(3768); + + m_engineSpinBox = new EngineSpinBox; + m_engineSpinBox->setEnabled(false); + connect(m_engineSpinBox, SIGNAL(valueChanged(int)), + SLOT(queryEngineContext(int))); +} + +void QmlInspectorMode::reloadEngines() +{ + if (m_engineQuery) { + emit statusMessage("[Inspector] Waiting for response to previous engine query"); + return; + } + + m_engineSpinBox->setEnabled(false); + + m_engineQuery = m_client->queryAvailableEngines(this); + if (!m_engineQuery->isWaiting()) + enginesChanged(); + else + QObject::connect(m_engineQuery, SIGNAL(stateChanged(State)), + this, SLOT(enginesChanged())); +} + +void QmlInspectorMode::enginesChanged() +{ + m_engineSpinBox->clearEngines(); + + QList<QmlDebugEngineReference> engines = m_engineQuery->engines(); + delete m_engineQuery; m_engineQuery = 0; + + if (engines.isEmpty()) + qWarning("qmldebugger: no engines found!"); + + m_engineSpinBox->setEnabled(true); + + for (int i=0; i<engines.count(); i++) + m_engineSpinBox->addEngine(engines.at(i).debugId(), engines.at(i).name()); + + if (engines.count() > 0) { + m_engineSpinBox->setValue(engines.at(0).debugId()); + queryEngineContext(engines.at(0).debugId()); + } +} + +void QmlInspectorMode::queryEngineContext(int id) +{ + if (id < 0) + return; + + if (m_contextQuery) { + delete m_contextQuery; + m_contextQuery = 0; + } + + m_contextQuery = m_client->queryRootContexts(QmlDebugEngineReference(id), this); + if (!m_contextQuery->isWaiting()) + contextChanged(); + else + QObject::connect(m_contextQuery, SIGNAL(stateChanged(State)), + this, SLOT(contextChanged())); +} + +void QmlInspectorMode::contextChanged() +{ + //dump(m_contextQuery->rootContext(), 0); + + foreach (const QmlDebugObjectReference &object, m_contextQuery->rootContext().objects()) + m_objectTreeWidget->reload(object.debugId()); + + delete m_contextQuery; m_contextQuery = 0; +} + +QT_END_NAMESPACE + +#include "qmlinspectormode.moc" + diff --git a/tools/qmldebugger/creatorplugin/qmlinspectormode.h b/tools/qmldebugger/creatorplugin/qmlinspectormode.h new file mode 100644 index 0000000..c70d630 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectormode.h @@ -0,0 +1,91 @@ +#ifndef QMLINSPECTORMODE_H +#define QMLINSPECTORMODE_H + +#include <QAction> + +#include <coreplugin/basemode.h> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +class QToolButton; +class QLineEdit; +class QSpinBox; +class QLabel; + +class QmlEngineDebug; +class QmlDebugConnection; +class QmlDebugEnginesQuery; +class QmlDebugRootContextQuery; +class ObjectTree; +class WatchTableModel; +class WatchTableView; +class ObjectPropertiesView; +class CanvasFrameRate; +class ExpressionQueryWidget; +class EngineSpinBox; + + +class QmlInspectorMode : public Core::BaseMode +{ + Q_OBJECT + +public: + QmlInspectorMode(QObject *parent = 0); + + + quint16 viewerPort() const; + +signals: + void startViewer(); + void stopViewer(); + void statusMessage(const QString &text); + +public slots: + void connectToViewer(); // using host, port from widgets + void disconnectFromViewer(); + +private slots: + void connectionStateChanged(); + void connectionError(); + void reloadEngines(); + void enginesChanged(); + void queryEngineContext(int); + void contextChanged(); + +private: + struct Actions { + QAction *startAction; + QAction *stopAction; + }; + + void initActions(); + QWidget *createModeWindow(); + QWidget *createMainView(); + void initWidgets(); + QWidget *createBottomWindow(); + QToolButton *createToolButton(QAction *action); + + Actions m_actions; + + QmlDebugConnection *m_conn; + QmlEngineDebug *m_client; + + QmlDebugEnginesQuery *m_engineQuery; + QmlDebugRootContextQuery *m_contextQuery; + + ObjectTree *m_objectTreeWidget; + ObjectPropertiesView *m_propertiesWidget; + WatchTableModel *m_watchTableModel; + WatchTableView *m_watchTableView; + CanvasFrameRate *m_frameRateWidget; + ExpressionQueryWidget *m_expressionWidget; + + QLineEdit *m_addressEdit; + QSpinBox *m_portSpinBox; + EngineSpinBox *m_engineSpinBox; +}; + +QT_END_NAMESPACE + +#endif diff --git a/tools/qmldebugger/creatorplugin/qmlinspectorplugin.cpp b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.cpp new file mode 100644 index 0000000..c743974 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.cpp @@ -0,0 +1,138 @@ +#include <QtCore/QStringList> +#include <QtCore/QtPlugin> +#include <QtCore/QDebug> + +#include <coreplugin/icore.h> + +#include <projectexplorer/runconfiguration.h> +#include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/project.h> + +#include <coreplugin/coreconstants.h> +#include <coreplugin/uniqueidmanager.h> + +#include <extensionsystem/pluginmanager.h> + +#include <QtDeclarative/qmldebug.h> +#include <QtDeclarative/qmldebugclient.h> + +#include "runcontrol.h" +#include "qmlinspector.h" +#include "qmlinspectormode.h" +#include "inspectoroutputpane.h" +#include "qmlinspectorplugin.h" + +QT_BEGIN_NAMESPACE + + +QmlInspectorPlugin::QmlInspectorPlugin() + : m_inspectMode(0), + m_runControl(0) +{ +} + +QmlInspectorPlugin::~QmlInspectorPlugin() +{ +} + +void QmlInspectorPlugin::shutdown() +{ + removeObject(m_inspectMode); + delete m_inspectMode; + m_inspectMode = 0; + + removeObject(m_outputPane); + delete m_outputPane; + m_outputPane = 0; +} + +bool QmlInspectorPlugin::initialize(const QStringList &arguments, QString *errorString) +{ + Q_UNUSED(arguments); + Q_UNUSED(errorString); + + Core::ICore *core = Core::ICore::instance(); + Core::UniqueIDManager *uidm = core->uniqueIDManager(); + + QList<int> modeContext; + modeContext.append(uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR)); + + QList<int> inspectorContext; + inspectorContext.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER)); + inspectorContext.append(uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR)); + inspectorContext.append(uidm->uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE)); + + m_inspectMode = new QmlInspectorMode(this); + connect(m_inspectMode, SIGNAL(startViewer()), SLOT(startViewer())); + connect(m_inspectMode, SIGNAL(stopViewer()), SLOT(stopViewer())); + m_inspectMode->setContext(modeContext); + addObject(m_inspectMode); + + m_outputPane = new InspectorOutputPane; + addObject(m_outputPane); + + connect(m_inspectMode, SIGNAL(statusMessage(QString)), + m_outputPane, SLOT(addInspectorStatus(QString))); + + m_runControlFactory = new QmlInspectorRunControlFactory(this); + addAutoReleasedObject(m_runControlFactory); + + return true; +} + +void QmlInspectorPlugin::extensionsInitialized() +{ +} + +void QmlInspectorPlugin::startViewer() +{ + stopViewer(); + + ProjectExplorer::Project *project = 0; + ProjectExplorer::ProjectExplorerPlugin *plugin = ProjectExplorer::ProjectExplorerPlugin::instance(); + if (plugin) + project = plugin->currentProject(); + if (!project) { + qDebug() << "No project loaded"; // TODO should this just run the debugger without a viewer? + return; + } + + QSharedPointer<ProjectExplorer::RunConfiguration> rc = project->activeRunConfiguration(); + + QmlInspector::StartParameters sp; + sp.port = m_inspectMode->viewerPort(); + + m_runControl = m_runControlFactory->create(rc, ProjectExplorer::Constants::RUNMODE, sp); + + if (m_runControl) { + connect(m_runControl, SIGNAL(started()), m_inspectMode, SLOT(connectToViewer())); + connect(m_runControl, SIGNAL(finished()), m_inspectMode, SLOT(disconnectFromViewer())); + + connect(m_runControl, SIGNAL(addToOutputWindow(RunControl*,QString)), + m_outputPane, SLOT(addOutput(RunControl*,QString))); + connect(m_runControl, SIGNAL(addToOutputWindowInline(RunControl*,QString)), + m_outputPane, SLOT(addOutputInline(RunControl*,QString))); + connect(m_runControl, SIGNAL(error(RunControl*,QString)), + m_outputPane, SLOT(addErrorOutput(RunControl*,QString))); + + m_runControl->start(); + m_outputPane->popup(false); + } + +} + +void QmlInspectorPlugin::stopViewer() +{ + if (m_runControl) { + m_runControl->stop(); + m_runControl->deleteLater(); + m_runControl = 0; + } +} + + +Q_EXPORT_PLUGIN(QmlInspectorPlugin) + +QT_END_NAMESPACE + diff --git a/tools/qmldebugger/creatorplugin/qmlinspectorplugin.h b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.h new file mode 100644 index 0000000..b0237e2 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/qmlinspectorplugin.h @@ -0,0 +1,50 @@ +#ifndef QMLINSPECTORPLUGIN_H +#define QMLINSPECTORPLUGIN_H + +#include <extensionsystem/iplugin.h> + +#include <QtCore/QObject> +#include <QtCore/QPointer> + +QT_BEGIN_NAMESPACE + +class QStringList; + + +class QmlInspectorRunControlFactory; +class QmlInspectorMode; +class InspectorOutputPane; + +namespace ProjectExplorer +{ + class RunControl; +} + +class QmlInspectorPlugin : public ExtensionSystem::IPlugin +{ + Q_OBJECT + +public: + QmlInspectorPlugin(); + ~QmlInspectorPlugin(); + + virtual bool initialize(const QStringList &arguments, QString *errorString); + virtual void extensionsInitialized(); + virtual void shutdown(); + +private slots: + void startViewer(); + void stopViewer(); + +private: + QmlInspectorMode *m_inspectMode; + InspectorOutputPane *m_outputPane; + + QmlInspectorRunControlFactory *m_runControlFactory; + QPointer<ProjectExplorer::RunControl> m_runControl; +}; + + +QT_END_NAMESPACE + +#endif // QMLINSPECTORPLUGIN_H diff --git a/tools/qmldebugger/creatorplugin/runcontrol.cpp b/tools/qmldebugger/creatorplugin/runcontrol.cpp new file mode 100644 index 0000000..11c7165 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/runcontrol.cpp @@ -0,0 +1,135 @@ +#include <QtCore/qdebug.h> +#include <QtCore/qtimer.h> + +#include <projectexplorer/applicationlauncher.h> +#include <projectexplorer/applicationrunconfiguration.h> +#include <projectexplorer/projectexplorerconstants.h> + +#include "runcontrol.h" + +using namespace ProjectExplorer; + + +QmlInspectorRunControlFactory::QmlInspectorRunControlFactory(QObject *parent) + : ProjectExplorer::IRunControlFactory(parent) +{ +} + +bool QmlInspectorRunControlFactory::canRun(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode) const +{ + Q_UNUSED(runConfiguration); + if (mode != ProjectExplorer::Constants::RUNMODE) + return false; + return true; +} + +ProjectExplorer::RunControl *QmlInspectorRunControlFactory::create(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode) +{ + Q_UNUSED(mode); + return new QmlInspectorRunControl(runConfiguration); +} + +ProjectExplorer::RunControl *QmlInspectorRunControlFactory::create(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, +const QString &mode, const QmlInspector::StartParameters &sp) +{ + Q_UNUSED(mode); + return new QmlInspectorRunControl(runConfiguration, sp); +} + +QString QmlInspectorRunControlFactory::displayName() const +{ + return tr("Qml Inspector"); +} + +QWidget *QmlInspectorRunControlFactory::configurationWidget(const QSharedPointer<RunConfiguration> &runConfiguration) +{ + Q_UNUSED(runConfiguration); + return 0; +} + + + +QmlInspectorRunControl::QmlInspectorRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, +const QmlInspector::StartParameters &sp) + : ProjectExplorer::RunControl(runConfiguration), + m_running(false), + m_viewerLauncher(0), + m_startParams(sp) +{ +} + +QmlInspectorRunControl::~QmlInspectorRunControl() +{ +} + +void QmlInspectorRunControl::start() +{ + if (m_running || m_viewerLauncher) + return; + + m_viewerLauncher = new ProjectExplorer::ApplicationLauncher(this); + connect(m_viewerLauncher, SIGNAL(applicationError(QString)), SLOT(applicationError(QString))); + connect(m_viewerLauncher, SIGNAL(processExited(int)), SLOT(viewerExited())); + connect(m_viewerLauncher, SIGNAL(appendOutput(QString)), SLOT(appendOutput(QString))); + connect(m_viewerLauncher, SIGNAL(bringToForegroundRequested(qint64)), + this, SLOT(appStarted())); + + QSharedPointer<LocalApplicationRunConfiguration> rc = + runConfiguration().objectCast<LocalApplicationRunConfiguration>(); + if (rc.isNull()) { // TODO + return; + } + + ProjectExplorer::Environment env = rc->environment(); + env.set("QML_DEBUG_SERVER_PORT", QString::number(m_startParams.port)); + + QStringList arguments = rc->commandLineArguments(); + arguments << QLatin1String("-stayontop"); + + m_viewerLauncher->setEnvironment(env.toStringList()); + m_viewerLauncher->setWorkingDirectory(rc->workingDirectory()); + + m_running = true; + + m_viewerLauncher->start(static_cast<ApplicationLauncher::Mode>(rc->runMode()), + rc->executable(), arguments); +} + +void QmlInspectorRunControl::stop() +{ + if (m_viewerLauncher->isRunning()) + m_viewerLauncher->stop(); +} + +bool QmlInspectorRunControl::isRunning() const +{ + return m_running; +} + +void QmlInspectorRunControl::appStarted() +{ + QTimer::singleShot(500, this, SLOT(delayedStart())); +} + +void QmlInspectorRunControl::appendOutput(const QString &s) +{ + emit addToOutputWindow(this, s); +} + +void QmlInspectorRunControl::delayedStart() +{ + emit started(); +} + +void QmlInspectorRunControl::viewerExited() +{ + m_running = false; + emit finished(); + + deleteLater(); +} + +void QmlInspectorRunControl::applicationError(const QString &s) +{ + emit error(this, s); +} diff --git a/tools/qmldebugger/creatorplugin/runcontrol.h b/tools/qmldebugger/creatorplugin/runcontrol.h new file mode 100644 index 0000000..b2976f6 --- /dev/null +++ b/tools/qmldebugger/creatorplugin/runcontrol.h @@ -0,0 +1,65 @@ +#ifndef QMLINSPECTORRUNCONTROL_H +#define QMLINSPECTORRUNCONTROL_H + +#include <QtCore/qobject.h> + +#include <projectexplorer/runconfiguration.h> + +#include "qmlinspector.h" + +namespace ProjectExplorer { + class ApplicationLauncher; +} + +class QmlInspectorRunControlFactory : public ProjectExplorer::IRunControlFactory +{ + Q_OBJECT + +public: + explicit QmlInspectorRunControlFactory(QObject *parent); + + virtual bool canRun( + const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QString &mode) const; + + virtual ProjectExplorer::RunControl *create( + const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QString &mode); + + ProjectExplorer::RunControl *create( + const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QString &mode, + const QmlInspector::StartParameters &sp); + + virtual QString displayName() const; + + virtual QWidget *configurationWidget(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration); +}; + +class QmlInspectorRunControl : public ProjectExplorer::RunControl +{ + Q_OBJECT + +public: + explicit QmlInspectorRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, + const QmlInspector::StartParameters &sp = QmlInspector::StartParameters()); + ~QmlInspectorRunControl(); + + virtual void start(); + virtual void stop(); + virtual bool isRunning() const; + +private slots: + void appendOutput(const QString &s); + void appStarted(); + void delayedStart(); + void viewerExited(); + void applicationError(const QString &error); + +private: + bool m_running; + ProjectExplorer::ApplicationLauncher *m_viewerLauncher; + QmlInspector::StartParameters m_startParams; +}; + +#endif diff --git a/tools/qmldebugger/qmldebugger.pro b/tools/qmldebugger/qmldebugger.pro index 4cdfd18..2dd353a 100644 --- a/tools/qmldebugger/qmldebugger.pro +++ b/tools/qmldebugger/qmldebugger.pro @@ -1,8 +1,10 @@ -DESTDIR = ../../bin +TEMPLATE = subdirs +CONFIG += ordered -include(qmldebugger.pri) +SUBDIRS = standalone -target.path=$$[QT_INSTALL_BINS] -INSTALLS += target - -CONFIG += console +CREATOR_SRC = $$(CREATOR_SRC_DIR) +CREATOR_BUILD = $$(CREATOR_BUILD_DIR) +!isEmpty(CREATOR_SRC):!isEmpty(CREATOR_BUILD) { + SUBDIRS += creatorplugin +} diff --git a/tools/qmldebugger/canvasframerate.cpp b/tools/qmldebugger/standalone/canvasframerate.cpp index 7c5d089..10c3dbf 100644 --- a/tools/qmldebugger/canvasframerate.cpp +++ b/tools/qmldebugger/standalone/canvasframerate.cpp @@ -56,7 +56,7 @@ private: QLineGraph::QLineGraph(QWidget *parent) : QWidget(parent), sb(Qt::Horizontal, this), position(-1), samplesPerWidth(99), resolutionForHeight(50), ignoreScroll(false) { - setMinimumHeight(180); + setMinimumHeight(200); sb.setMaximum(0); sb.setMinimum(0); @@ -178,7 +178,6 @@ void QLineGraph::paintEvent(QPaintEvent *) QPainter p(this); p.setRenderHint(QPainter::Antialiasing); - QRect r(50, 10, width() - 60, height() - 60); p.setBrush(QColor("lightsteelblue")); drawSample(&p, 0, r); @@ -247,11 +246,10 @@ void CanvasFrameRatePlugin::messageReceived(const QByteArray &data) ld = d; } -CanvasFrameRate::CanvasFrameRate(QmlDebugConnection *client, QWidget *parent) -: QWidget(parent) +CanvasFrameRate::CanvasFrameRate(QWidget *parent) +: QWidget(parent), + m_plugin(0) { - m_plugin = new CanvasFrameRatePlugin(client); - QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0,0,0,0); layout->setSpacing(0); @@ -261,7 +259,8 @@ CanvasFrameRate::CanvasFrameRate(QmlDebugConnection *client, QWidget *parent) layout->addWidget(m_tabs); QHBoxLayout *bottom = new QHBoxLayout; - bottom->setSpacing(5); + bottom->setContentsMargins(5, 0, 5, 0); + bottom->setSpacing(10); layout->addLayout(bottom); QLabel *label = new QLabel("Resolution", this); @@ -275,15 +274,51 @@ CanvasFrameRate::CanvasFrameRate(QmlDebugConnection *client, QWidget *parent) bottom->addStretch(2); - QCheckBox *check = new QCheckBox("Enable", this); - bottom->addWidget(check); - QObject::connect(check, SIGNAL(stateChanged(int)), - this, SLOT(stateChanged(int))); + m_enabledCheckBox = new QCheckBox("Enable", this); + bottom->addWidget(m_enabledCheckBox); + QObject::connect(m_enabledCheckBox, SIGNAL(stateChanged(int)), + this, SLOT(enabledStateChanged(int))); QPushButton *pb = new QPushButton(tr("New Tab"), this); QObject::connect(pb, SIGNAL(clicked()), this, SLOT(newTab())); bottom->addWidget(pb); +} + +void CanvasFrameRate::reset(QmlDebugConnection *conn) +{ + delete m_plugin; + m_plugin = 0; + + QWidget *w; + for (int i=0; i<m_tabs->count(); i++) { + w = m_tabs->widget(i); + m_tabs->removeTab(i); + delete w; + } + if (conn) { + connect(conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + SLOT(connectionStateChanged(QAbstractSocket::SocketState))); + if (conn->state() == QAbstractSocket::ConnectedState) + handleConnected(conn); + } +} + +void CanvasFrameRate::connectionStateChanged(QAbstractSocket::SocketState state) +{ + if (state == QAbstractSocket::UnconnectedState) { + delete m_plugin; + m_plugin = 0; + } else if (state == QAbstractSocket::ConnectedState) { + handleConnected(qobject_cast<QmlDebugConnection*>(sender())); + } +} + +void CanvasFrameRate::handleConnected(QmlDebugConnection *conn) +{ + delete m_plugin; + m_plugin = new CanvasFrameRatePlugin(conn); + enabledStateChanged(m_enabledCheckBox->checkState()); newTab(); } @@ -299,6 +334,9 @@ QSize CanvasFrameRate::sizeHint() const void CanvasFrameRate::newTab() { + if (!m_plugin) + return; + if (m_tabs->count()) { QWidget *w = m_tabs->widget(m_tabs->count() - 1); QObject::disconnect(m_plugin, SIGNAL(sample(int,int,int,bool)), @@ -317,11 +355,12 @@ void CanvasFrameRate::newTab() m_tabs->setCurrentIndex(id); } -void CanvasFrameRate::stateChanged(int s) +void CanvasFrameRate::enabledStateChanged(int s) { bool checked = s != 0; - static_cast<QmlDebugClient *>(m_plugin)->setEnabled(checked); + if (m_plugin) + static_cast<QmlDebugClient *>(m_plugin)->setEnabled(checked); } QT_END_NAMESPACE diff --git a/tools/qmldebugger/standalone/canvasframerate.h b/tools/qmldebugger/standalone/canvasframerate.h new file mode 100644 index 0000000..6c1ff9f --- /dev/null +++ b/tools/qmldebugger/standalone/canvasframerate.h @@ -0,0 +1,46 @@ +#ifndef CANVASFRAMERATE_H +#define CANVASFRAMERATE_H + +#include <QtCore/qpointer.h> +#include <QtGui/qwidget.h> + +#include <QtDeclarative/qmldebugclient.h> + +QT_BEGIN_NAMESPACE + +class QTabWidget; +class QSpinBox; +class QCheckBox; + +class CanvasFrameRatePlugin; + +class CanvasFrameRate : public QWidget +{ + Q_OBJECT +public: + CanvasFrameRate(QWidget *parent = 0); + + void reset(QmlDebugConnection *conn); + + void setSizeHint(const QSize &); + virtual QSize sizeHint() const; + +private slots: + void newTab(); + void enabledStateChanged(int); + void connectionStateChanged(QAbstractSocket::SocketState state); + +private: + void handleConnected(QmlDebugConnection *conn); + + QTabWidget *m_tabs; + QSpinBox *m_spin; + CanvasFrameRatePlugin *m_plugin; + QSize m_sizeHint; + QCheckBox *m_enabledCheckBox; +}; + +QT_END_NAMESPACE + +#endif // CANVASFRAMERATE_H + diff --git a/tools/qmldebugger/engine.cpp b/tools/qmldebugger/standalone/engine.cpp index a1fd009..a1fd009 100644 --- a/tools/qmldebugger/engine.cpp +++ b/tools/qmldebugger/standalone/engine.cpp diff --git a/tools/qmldebugger/engine.h b/tools/qmldebugger/standalone/engine.h index a3ebe46..a3ebe46 100644 --- a/tools/qmldebugger/engine.h +++ b/tools/qmldebugger/standalone/engine.h diff --git a/tools/qmldebugger/engine.png b/tools/qmldebugger/standalone/engine.png Binary files differindex a0a8a04..a0a8a04 100644 --- a/tools/qmldebugger/engine.png +++ b/tools/qmldebugger/standalone/engine.png diff --git a/tools/qmldebugger/engines.qml b/tools/qmldebugger/standalone/engines.qml index 1e9335b..1e9335b 100644 --- a/tools/qmldebugger/engines.qml +++ b/tools/qmldebugger/standalone/engines.qml diff --git a/tools/qmldebugger/expressionquerywidget.cpp b/tools/qmldebugger/standalone/expressionquerywidget.cpp index 53ede3a..f8f5aef 100644 --- a/tools/qmldebugger/expressionquerywidget.cpp +++ b/tools/qmldebugger/standalone/expressionquerywidget.cpp @@ -17,28 +17,25 @@ ExpressionQueryWidget::ExpressionQueryWidget(QmlEngineDebug *client, QWidget *pa m_client(client), m_query(0), m_textEdit(new QTextEdit), - m_lineEdit(0), - m_button(0) + m_lineEdit(0) { m_prompt = QLatin1String(">> "); QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); + layout->setSpacing(0); layout->addWidget(m_textEdit); updateTitle(); if (m_style == Compact) { - QHBoxLayout *hbox = new QHBoxLayout; - m_button = new QPushButton(tr("Query")); - m_button->setEnabled(false); - connect(m_button, SIGNAL(clicked()), SLOT(executeExpression())); m_lineEdit = new QLineEdit; connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(executeExpression())); - connect(m_lineEdit, SIGNAL(textChanged(QString)), SLOT(lineEditTextChanged(QString))); + QHBoxLayout *hbox = new QHBoxLayout; + hbox->setMargin(5); + hbox->setSpacing(5); hbox->addWidget(new QLabel(tr("Expression:"))); hbox->addWidget(m_lineEdit); - hbox->addWidget(m_button); layout->addLayout(hbox); m_textEdit->setReadOnly(true); @@ -53,6 +50,12 @@ void ExpressionQueryWidget::setEngineDebug(QmlEngineDebug *client) m_client = client; } +void ExpressionQueryWidget::clear() +{ + m_textEdit->clear(); + m_lineEdit->clear(); +} + void ExpressionQueryWidget::updateTitle() { if (m_currObject.debugId() < 0) { @@ -153,12 +156,6 @@ void ExpressionQueryWidget::showResult() } } -void ExpressionQueryWidget::lineEditTextChanged(const QString &s) -{ - if (m_button) - m_button->setEnabled(!s.isEmpty()); -} - bool ExpressionQueryWidget::eventFilter(QObject *obj, QEvent *event) { if (obj == m_textEdit) { diff --git a/tools/qmldebugger/expressionquerywidget.h b/tools/qmldebugger/standalone/expressionquerywidget.h index 3d9b580..6fab059 100644 --- a/tools/qmldebugger/expressionquerywidget.h +++ b/tools/qmldebugger/standalone/expressionquerywidget.h @@ -24,6 +24,7 @@ public: ExpressionQueryWidget(QmlEngineDebug *client = 0, QWidget *parent = 0); void setEngineDebug(QmlEngineDebug *client); + void clear(); protected: bool eventFilter(QObject *obj, QEvent *event); @@ -34,7 +35,6 @@ public slots: private slots: void executeExpression(); void showResult(); - void lineEditTextChanged(const QString &s); private: void appendPrompt(); diff --git a/tools/qmldebugger/main.cpp b/tools/qmldebugger/standalone/main.cpp index c9983cd..c9983cd 100644 --- a/tools/qmldebugger/main.cpp +++ b/tools/qmldebugger/standalone/main.cpp diff --git a/tools/qmldebugger/objectpropertiesview.cpp b/tools/qmldebugger/standalone/objectpropertiesview.cpp index 274552a..ae9e8be 100644 --- a/tools/qmldebugger/objectpropertiesview.cpp +++ b/tools/qmldebugger/standalone/objectpropertiesview.cpp @@ -43,6 +43,7 @@ ObjectPropertiesView::ObjectPropertiesView(QmlEngineDebug *client, QWidget *pare setLayout(layout); m_tree = new QTreeWidget(this); + m_tree->setAlternatingRowColors(true); m_tree->setExpandsOnDoubleClick(false); m_tree->setHeaderLabels(QStringList() << tr("Property") << tr("Value")); QObject::connect(m_tree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), @@ -58,6 +59,11 @@ void ObjectPropertiesView::setEngineDebug(QmlEngineDebug *client) m_client = client; } +void ObjectPropertiesView::clear() +{ + setObject(QmlDebugObjectReference()); +} + void ObjectPropertiesView::reload(const QmlDebugObjectReference &obj) { if (!m_client) @@ -105,7 +111,6 @@ void ObjectPropertiesView::setObject(const QmlDebugObjectReference &object) m_object = object; m_tree->clear(); - QList<QmlDebugPropertyReference> properties = object.properties(); for (int i=0; i<properties.count(); i++) { const QmlDebugPropertyReference &p = properties[i]; diff --git a/tools/qmldebugger/objectpropertiesview.h b/tools/qmldebugger/standalone/objectpropertiesview.h index d555940..6a1fc03 100644 --- a/tools/qmldebugger/objectpropertiesview.h +++ b/tools/qmldebugger/standalone/objectpropertiesview.h @@ -18,6 +18,7 @@ public: ObjectPropertiesView(QmlEngineDebug *client = 0, QWidget *parent = 0); void setEngineDebug(QmlEngineDebug *client); + void clear(); signals: void activated(const QmlDebugObjectReference &, const QmlDebugPropertyReference &); diff --git a/tools/qmldebugger/objecttree.cpp b/tools/qmldebugger/standalone/objecttree.cpp index 981a80b..4059e77 100644 --- a/tools/qmldebugger/objecttree.cpp +++ b/tools/qmldebugger/standalone/objecttree.cpp @@ -68,6 +68,9 @@ void ObjectTree::objectFetched() void ObjectTree::currentItemChanged(QTreeWidgetItem *item) { + if (!item) + return; + QmlDebugObjectReference obj = item->data(0, Qt::UserRole).value<QmlDebugObjectReference>(); if (obj.debugId() < 0) { qWarning("QML Object Tree: bad object id"); diff --git a/tools/qmldebugger/objecttree.h b/tools/qmldebugger/standalone/objecttree.h index 95820f3..95820f3 100644 --- a/tools/qmldebugger/objecttree.h +++ b/tools/qmldebugger/standalone/objecttree.h diff --git a/tools/qmldebugger/qmldebugger.cpp b/tools/qmldebugger/standalone/qmldebugger.cpp index 2828026..5455878 100644 --- a/tools/qmldebugger/qmldebugger.cpp +++ b/tools/qmldebugger/standalone/qmldebugger.cpp @@ -45,7 +45,8 @@ QmlDebugger::QmlDebugger(QWidget *parent) m_tabs = new QTabWidget(this); layout->addWidget(m_tabs); - CanvasFrameRate *cfr = new CanvasFrameRate(&client, this); + CanvasFrameRate *cfr = new CanvasFrameRate(this); + cfr->reset(&client); cfr->setSizeHint(QSize(800, 600)); m_tabs->addTab(cfr, tr("Frame Rate")); diff --git a/tools/qmldebugger/qmldebugger.h b/tools/qmldebugger/standalone/qmldebugger.h index 9203e33..9203e33 100644 --- a/tools/qmldebugger/qmldebugger.h +++ b/tools/qmldebugger/standalone/qmldebugger.h diff --git a/tools/qmldebugger/qmldebugger.pri b/tools/qmldebugger/standalone/qmldebugger.pri index c49d334..aad5eb1 100644 --- a/tools/qmldebugger/qmldebugger.pri +++ b/tools/qmldebugger/standalone/qmldebugger.pri @@ -2,23 +2,15 @@ QT += network declarative contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, opengles1): QT += opengl # Input -HEADERS += $$PWD/qmldebugger.h \ - $$PWD/canvasframerate.h \ +HEADERS += $$PWD/canvasframerate.h \ $$PWD/watchtable.h \ - $$PWD/engine.h \ $$PWD/objecttree.h \ $$PWD/objectpropertiesview.h \ $$PWD/expressionquerywidget.h -SOURCES += $$PWD/qmldebugger.cpp \ - $$PWD/main.cpp \ - $$PWD/canvasframerate.cpp \ +SOURCES += $$PWD/canvasframerate.cpp \ $$PWD/watchtable.cpp \ - $$PWD/engine.cpp \ $$PWD/objecttree.cpp \ $$PWD/objectpropertiesview.cpp \ $$PWD/expressionquerywidget.cpp -RESOURCES += $$PWD/qmldebugger.qrc - -OTHER_FILES += $$PWD/engines.qml diff --git a/tools/qmldebugger/qmldebugger.qrc b/tools/qmldebugger/standalone/qmldebugger.qrc index cb53ad5..cb53ad5 100644 --- a/tools/qmldebugger/qmldebugger.qrc +++ b/tools/qmldebugger/standalone/qmldebugger.qrc diff --git a/tools/qmldebugger/refresh.png b/tools/qmldebugger/standalone/refresh.png Binary files differindex 8befc80..8befc80 100644 --- a/tools/qmldebugger/refresh.png +++ b/tools/qmldebugger/standalone/refresh.png diff --git a/tools/qmldebugger/standalone/standalone.pro b/tools/qmldebugger/standalone/standalone.pro new file mode 100644 index 0000000..72e3ef5 --- /dev/null +++ b/tools/qmldebugger/standalone/standalone.pro @@ -0,0 +1,18 @@ +DESTDIR = ../../bin + +include(qmldebugger.pri) + +HEADERS += $$PWD/qmldebugger.h \ + $$PWD/engine.h + +SOURCES += $$PWD/qmldebugger.cpp \ + $$PWD/engine.cpp \ + $$PWD/main.cpp + +RESOURCES += $$PWD/qmldebugger.qrc +OTHER_FILES += $$PWD/engines.qml + +target.path=$$[QT_INSTALL_BINS] +INSTALLS += target + +CONFIG += console diff --git a/tools/qmldebugger/watchtable.cpp b/tools/qmldebugger/standalone/watchtable.cpp index 774727b..ee74cfb 100644 --- a/tools/qmldebugger/watchtable.cpp +++ b/tools/qmldebugger/standalone/watchtable.cpp @@ -18,7 +18,7 @@ WatchTableModel::WatchTableModel(QmlEngineDebug *client, QObject *parent) } WatchTableModel::~WatchTableModel() -{ +{ for (int i=0; i<m_columns.count(); i++) delete m_columns[i].watch; } @@ -247,7 +247,7 @@ void WatchTableModel::expressionWatchRequested(const QmlDebugObjectReference &ob } } -void WatchTableModel::stopWatching(int column) +void WatchTableModel::removeWatchAt(int column) { if (!m_client) return; @@ -260,6 +260,17 @@ void WatchTableModel::stopWatching(int column) } } +void WatchTableModel::removeAllWatches() +{ + for (int i=0; i<m_columns.count(); i++) { + if (m_client) + m_client->removeWatch(m_columns[i].watch); + delete m_columns[i].watch; + } + m_columns.clear(); + m_values.clear(); + reset(); +} //---------------------------------------------- @@ -281,7 +292,7 @@ void WatchTableHeaderView::mousePressEvent(QMouseEvent *me) QList<QAction *> actions; actions << &action; if (QMenu::exec(actions, me->globalPos())) - m_model->stopWatching(col); + m_model->removeWatchAt(col); } } } @@ -293,6 +304,7 @@ WatchTableView::WatchTableView(WatchTableModel *model, QWidget *parent) : QTableView(parent), m_model(model) { + setAlternatingRowColors(true); connect(model, SIGNAL(watchCreated(QmlDebugWatch*)), SLOT(watchCreated(QmlDebugWatch*))); connect(this, SIGNAL(activated(QModelIndex)), SLOT(indexActivated(QModelIndex))); } diff --git a/tools/qmldebugger/watchtable.h b/tools/qmldebugger/standalone/watchtable.h index 772142c..67c2565 100644 --- a/tools/qmldebugger/watchtable.h +++ b/tools/qmldebugger/standalone/watchtable.h @@ -29,7 +29,8 @@ public: QmlDebugWatch *findWatch(int column) const; int columnForWatch(QmlDebugWatch *watch) const; - void stopWatching(int column); + void removeWatchAt(int column); + void removeAllWatches(); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp index f82867f..3f531e4 100644 --- a/tools/qmlviewer/main.cpp +++ b/tools/qmlviewer/main.cpp @@ -28,6 +28,7 @@ void usage() qWarning(" -frameless ............................... run with no window frame"); qWarning(" -maximized................................ run maximized"); qWarning(" -fullscreen............................... run fullscreen"); + qWarning(" -stayontop................................ keep viewer window on top"); qWarning(" -skin <qvfbskindir> ...................... run with a skin window frame"); qWarning(" \"list\" for a list of built-ins"); qWarning(" -resizeview .............................. resize the view, not the skin"); @@ -105,6 +106,7 @@ int main(int argc, char ** argv) QString translationFile; bool useGL = false; bool fullScreen = false; + bool stayOnTop = false; bool maximized = false; for (int i = 1; i < argc; ++i) { @@ -116,6 +118,8 @@ int main(int argc, char ** argv) maximized = true; } else if (arg == "-fullscreen") { fullScreen = true; + } else if (arg == "-stayontop") { + stayOnTop = true; } else if (arg == "-skin") { if (lastArg) usage(); skin = QString(argv[++i]); @@ -183,9 +187,12 @@ int main(int argc, char ** argv) app.installTranslator(&qmlTranslator); } - QmlViewer viewer(0, frameless ? Qt::FramelessWindowHint : Qt::Widget); + Qt::WFlags wflags = (frameless ? Qt::FramelessWindowHint : Qt::Widget); + if (stayOnTop) + wflags |= Qt::WindowStaysOnTopHint; + + QmlViewer viewer(0, wflags); if (!scriptopts.isEmpty()) { - QStringList options = scriptopts.split(QLatin1Char(','), QString::SkipEmptyParts); |